Skip to content

importlib_metadata handles PathLike objects on sys.path when importlib.PathFinder does not #372

Description

@graingert

demo script:

import contextlib
import os
import pathlib
import sys
import tempfile

import importlib_metadata


@contextlib.contextmanager
def _tmp_path(*args, **kwargs):
    with tempfile.TemporaryDirectory(*args, **kwargs) as tmp_dir:
        yield pathlib.Path(tmp_dir)


def main():
    with _tmp_path() as tmp_path:
        (tmp_path / "module.py").write_bytes(b"def function():\n    return 1\n")
        dist_info = tmp_path / "demo_package-0.0.0.dist-info"
        dist_info.mkdir()
        (dist_info / "entry_points.txt").write_bytes(
            b"[group]\nname = module:function\n"
        )
        sys.path.append(tmp_path)
        ep = next(
            iter(importlib_metadata.entry_points(name="name", group="group")), None
        )
        print(ep)
        print(ep.load())


if __name__ == "__main__":
    sys.exit(main())

results in:

EntryPoint(name='name', value='module:function', group='group')
Traceback (most recent call last):
  File "/home/graingert/projects/demo_importlib.py", line 33, in <module>
    sys.exit(main())
             ^^^^^^
  File "/usr/lib/python3.11/contextlib.py", line 155, in __exit__
    self.gen.throw(typ, value, traceback)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/graingert/projects/demo_importlib.py", line 13, in _tmp_path
    yield pathlib.Path(tmp_dir)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/graingert/projects/demo_importlib.py", line 29, in main
    print(ep.load())
          ^^^^^^^^^
  File "/home/graingert/.virtualenvs/testing311/lib/python3.11/site-packages/importlib_metadata/__init__.py", line 203, in load
    module = import_module(match.group('module'))
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1206, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1178, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1142, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'module'

however if I os.fsdecode the tmp_path - before appending it to the sys.path I get:

EntryPoint(name='name', value='module:function', group='group')
<function function at 0x7f2b12192700>

see also https://github.com/python/cpython/blob/23dcea5de736b367c0244042aaca10971538b2b4/Lib/importlib/_bootstrap_external.py#L1460-L1461
and https://bugs.python.org/issue32642

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions