Skip to content

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

@graingert

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

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