-
-
Notifications
You must be signed in to change notification settings - Fork 87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
importlib_metadata handles PathLike objects on sys.path when importlib.PathFinder does not #372
Comments
I've uploaded the repro as a gist so I can replicate the error with this one-liner:
|
I can confirm the same issue exists in the stdlib version:
I'm not sure there's much for importlib metadata to do here. Sure, it could exclude path entries that aren't strings. I do see where importlib_metadata resolves a pathlib.Path to str. It looks like that cast was added to introduce compatibility on Python 2 (see #121 (comment)). Now that Python 2 support is dropped, that cast can be dropped too. I wonder what that does to the repro. |
afaik sys.path can have bytes in, which that str call would change to |
Removing the cast to str doesn't change the error (importlib_metadata still finds the path):
|
I think you have to skip paths that aren't
|
Ugh. The docs are contradictory on the topic, stating that it's a list of strings, but implying that bytes are supported by saying that types other than bytes and str are ignored. I'm not sure I want to add support for bytes unless a real world use case demonstrates the need. |
I agree that would stop it from discovering metadata on paths indicated by Path objects. It also would affect discovery by paths not on I'm not sure what is the right behavior here. I'm inclined to sit on this one for now until importlib has settled on what should happen about sys.path, but even if it decides to retain the behavior that only str/bytes are allowed on sys.path, I'd lean toward importlib metadata supporting any paths that are str or Path-like. What was the use-case that triggered this report? Is it something that can't be easily worked around? |
I was writing a test for pandas that mutates sys.path https://github.com/pandas-dev/pandas/pull/46302/files#diff-a363ecff783b66b30c1c2ea2481145430bba2e2c7a2afc279a1db24912eab756R130 and noticed the discrepancy |
so it turns out bytes don't actually work in gist here https://gist.github.com/graingert/3422e812b0aa243c9719884f86be52ff 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(os.fsencode(tmp_path))
import module
assert module.function() == 1
ep = next(
iter(importlib_metadata.entry_points(name="name", group="group")), None
)
print(ep)
print(ep.load())
if __name__ == "__main__":
sys.exit(main())
|
In the referenced commit, I've documented the current behavior. It's my opinion that the other importlib machinery should support this behavior, but I'll be happy to revisit this issue at such a time that Python is more explicit about what types are allowed. In the meantime, I'd advise to just not put |
demo script:
results in:
however if I
os.fsdecode
thetmp_path
- before appending it to thesys.path
I get:see also https://github.com/python/cpython/blob/23dcea5de736b367c0244042aaca10971538b2b4/Lib/importlib/_bootstrap_external.py#L1460-L1461
and https://bugs.python.org/issue32642
The text was updated successfully, but these errors were encountered: