importlib_metadata handles PathLike objects on sys.path when importlib.PathFinder does not
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