Search code examples
pythonpkg-resources

Replacing pkg_resources `Distribution.run_script()`


As pkg_resources is deprecated but the official migration guides don't offer migration paths for all of its API I'm seeking a replacement for Distribution.run_script().

As far as I can see its only purpose is to take a script shipped in scripts and either read it from the disk or get it with Distribution.get_metadata() and then execute it in the provided namespace. So my questions are:

  1. Is there a ready to use replacement for this (I suppose no)?
  2. What is the get_metadata() code path for, is it there for zipped eggs or for some other reason? Is there a ready to use replacement for this code path, as the other codepath is much easier to replace? Or is it never relevant anyway?

Solution

  • Here is a replacement I went with, it may be incomplete but it works with zipped eggs. Unfortunately it uses a private attribute but I don't see a public API exposing _path.

    def _run_script(dist, script_name, namespace):
        # an importlib-based replacement for pkg_resources.NullProvider.run_script()
        script = 'scripts/' + script_name
        source = dist.read_text(script)
        if not source:
            raise ValueError(
                f"Script {script!r} not found in metadata at {dist._path!r}"
            )
        script_filename = dist._path.joinpath(script)
        code = compile(source, str(script_filename), 'exec')
        exec(code, namespace, namespace)