-
-
Notifications
You must be signed in to change notification settings - Fork 30.4k
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
bytes do not work on sys.path #91181
Comments
importing a module with bytes in File "<frozen importlib._bootstrap_external>", line 182, in _path_isabs (see reproducer in attached demo.py) however bytes are allowed in PathFinder._find_spec cpython/Lib/importlib/_bootstrap_external.py Lines 1460 to 1462 in 2cf7f86
see also: |
In case it helps anyone: On Windows 3.11.0a5+ the full traceback is: $ ./python.bat demo.py
Running Debug|x64 interpreter...
Traceback (most recent call last):
File "...\demo.py", line 23, in <module>
sys.exit(main())
^^^^^^
File "...\Lib\contextlib.py", line 155, in __exit__
self.gen.throw(typ, value, traceback)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "...\demo.py", line 11, in _tmp_path
yield pathlib.Path(tmp_dir)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "...\demo.py", line 18, in main
import module
^^^^^^^^^^^^^
File "<frozen importlib._bootstrap>", line 1178, in _find_and_load
File "<frozen importlib._bootstrap>", line 1140, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 1080, in _find_spec
File "<frozen importlib._bootstrap_external>", line 1487, in find_spec
File "<frozen importlib._bootstrap_external>", line 1459, in _get_spec
File "<frozen importlib._bootstrap_external>", line 1596, in find_spec
File "<frozen importlib._bootstrap_external>", line 1656, in _fill_cache
TypeError: a bytes-like object is required, not 'str' And on cygwin 3.8.12: $ python demo.py
Traceback (most recent call last):
File "<frozen importlib._bootstrap_external>", line 1346, in _path_importer_cache
KeyError: b'/tmp/tmprpymgive'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "demo.py", line 23, in <module>
sys.exit(main())
File "demo.py", line 18, in main
import module
File "<frozen importlib._bootstrap>", line 991, in _find_and_load
File "<frozen importlib._bootstrap>", line 971, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 914, in _find_spec
File "<frozen importlib._bootstrap_external>", line 1407, in find_spec
File "<frozen importlib._bootstrap_external>", line 1376, in _get_spec
File "<frozen importlib._bootstrap_external>", line 1348, in _path_importer_cache
File "<frozen importlib._bootstrap_external>", line 1324, in _path_hooks
File "<frozen importlib._bootstrap_external>", line 1594, in path_hook_for_FileFinder
File "<frozen importlib._bootstrap_external>", line 1469, in __init__
File "<frozen importlib._bootstrap_external>", line 177, in _path_isabs
TypeError: startswith first arg must be bytes or a tuple of bytes, not str |
this is a regression from 3.2:
|
https://docs.python.org/3/reference/import.html#path-entry-finders says "The encoding of bytes entries is determined by the individual path entry finders." see 82c1c78 |
interestingly bytes filenames pointing to zip files on sys.path do support bytes (see zipfile_demo.py) |
In Windows, bytes paths in sys.path do not work in 3.2+. I didn't test 3.0 and 3.1, but practically one can say that bytes paths were never supported in Python 3 on Windows. |
zipimporter.zipimporter handles non-bytes paths here: Lines 65 to 67 in 2cf7f86
|
I'd advocate for not supporting bytes paths and instead updating the documentation to require strings. |
I've got PR #76115 started to do this |
I think it depends on whether we want to say the standard/included/built-in import mechanisms don't support byte paths, or byte paths are entirely not supported even for 3rd-party code? I definitely think we should at least do the former, but I'm hesitant to close the door for those that need it by doing the latter. |
Looking at the tracebacks that Eric provided, these are caused by: cpython/Lib/importlib/_bootstrap_external.py Lines 1681 to 1683 in 605e9c6
cpython/Lib/importlib/_bootstrap_external.py Lines 176 to 177 in 605e9c6
cpython/Lib/importlib/_bootstrap_external.py Line 182 in 605e9c6
It's basically bad assumptions in importlib where string constants are used instead of string or bytes constants based on what's being compared against. As for decoding, https://docs.python.org/3/library/sys.html#sys.getfilesystemencoding suggests it's the right way to go like @graingert has in his PR. It probably isn't fully backwards-compatible as I bet we used to not care about the bytes involved and just did a straight comparison, but in this instance you have bigger problems if your file paths are not decoding appropriately based on what Python believes is your file system encoding. But, this has been broken since at least Python 3.6 based on Eric's |
Which PR? There's two: one to drop support in general, and one to wedge support back into FileFinder? |
|
After thinking about it, I think we should add support back, so I'm reviewing #31897 and I'm going to close the PR to drop bytes support. |
https://discuss.python.org/t/drop-supporting-bytes-on-sys-path/17225 I'm now suggesting dropping bytes support in And for bookkeeping, the PR to drop bytes support is #31934 (which I closed, so it can be reopened if things go towards dropping support). |
FYI it's looking good to drop bytes support! I will give the topic on discuss.python.org a little while longer, but my expectation is we will go with #31934 and backport it 3.11 and 3.10 since it's already broken in those versions. I will then add a What's New entry in 3.11 to help get the word out. |
Support for bytes broke sometime between Python 3.2 and 3.6 and has been broken ever since. Trying to bring back supports is surprisingly difficult in the face of -b and checking for keys in sys.path_importer_cache. Since the support was broken for so long, trying to overcome the difficulty of bringing back the support has been deemed not worth it. Co-authored-by: Eryk Sun <eryksun@gmail.com> Co-authored-by: Brett Cannon <brett@python.org>
Support for bytes broke sometime between Python 3.2 and 3.6 and has been broken ever since. Trying to bring back supports is surprisingly difficult in the face of -b and checking for keys in sys.path_importer_cache. Since the support was broken for so long, trying to overcome the difficulty of bringing back the support has been deemed not worth it. Co-authored-by: Eryk Sun <eryksun@gmail.com> Co-authored-by: Brett Cannon <brett@python.org> (cherry picked from commit 6da988a) Co-authored-by: Thomas Grainger <tagrain@gmail.com>
Support for bytes broke sometime between Python 3.2 and 3.6 and has been broken ever since. Trying to bring back supports is surprisingly difficult in the face of -b and checking for keys in sys.path_importer_cache. Since the support was broken for so long, trying to overcome the difficulty of bringing back the support has been deemed not worth it. Co-authored-by: Eryk Sun <eryksun@gmail.com> Co-authored-by: Brett Cannon <brett@python.org> (cherry picked from commit 6da988a) Co-authored-by: Thomas Grainger <tagrain@gmail.com>
The fix for I'm going to leave this issue open to remind me to write up a What's New entry for 3.11 (which still needs to go into |
… `sys.path` (pythonGH-94918) (cherry picked from commit ec4745b) Co-authored-by: Brett Cannon <brett@python.org>
#94919 is the What's New entry for 3.11 and it's set to auto-merge, so I consider this issue done! Thanks everyone! |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: