-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
importlib.readers not valid until python 3.10 #9609
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
Conversation
Thanks, this LGTM. Since I have no idea about the underlying importlib stuff, I'll leave it to someone else to actually approve, maybe @gaborbernat who added it (#9173), or @asottile who knows about this stuff. I do notice that latest python says this about Maybe we can be forward-compatible with Python 3.11 already by importing from |
And if someone knows how to test this that would be great as well (though not necessary for this PR). |
Not surgical, but this test has my reproducer in it. If desired I can push this, or feel free to make edits to the PR
|
src/_pytest/assertion/rewrite.py
Outdated
@@ -273,7 +273,7 @@ def get_data(self, pathname: Union[str, bytes]) -> bytes: | |||
with open(pathname, "rb") as f: | |||
return f.read() | |||
|
|||
if sys.version_info >= (3, 9): | |||
if sys.version_info >= (3, 10): | |||
|
|||
def get_resource_reader(self, name: str) -> importlib.abc.TraversableResources: # type: ignore | |||
from types import SimpleNamespace |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about we move these two imports outside the function? This would at least caught the error in the correct Python versions.
if sys.version_info >= (3, 10):
from types import SimpleNamespace
from importlib.readers import FileReader
def get_resource_reader(self, name: str) -> importlib.abc.TraversableResources: # type: ignore
return FileReader(SimpleNamespace(path=self._rewritten_names[name]))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm nevermind that, that conditional import does not work.
Took the liberty of moving the import to the global level, and adding a CHANGELOG so this is "ready to go", but still would like to hear from someone who knows "importlib" stuff better. |
I'm a bit confused by two things here:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the test in the original review passes in 3.9 because the implementation of importlib.resources doesn't attempt get_resource_reader
and just utilizes the .submodule_search_locations
of the module's spec
so the (3, 9)
vs. (3, 10)
difference is ~mostly harmless -- is there a place where you're seeing this break?
@@ -273,13 +277,10 @@ def get_data(self, pathname: Union[str, bytes]) -> bytes: | |||
with open(pathname, "rb") as f: | |||
return f.read() | |||
|
|||
if sys.version_info >= (3, 9): | |||
if sys.version_info >= (3, 10): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that this should be changed to (3, 10)
since FileReader
isn't needed there
Not sure about the others reporting #9608, but this specifically occurs for us in a test file that imports
In the full traceback shown in #9608 we see it hitting this in https://github.com/pypa/pip/blob/44018de50cafba25445a225c1a1986d6312e1ef3/src/pip/_vendor/certifi/core.py#L50 which calls this |
ah yeah this was the whole 3.9.3 fiasco where the resources api was partially rewritten and reverted in a patch version but some of the apis use the readers already I think if you take the test that was in the previous PR and use so I guess to move forward, I would inline the conditional import and personally I wouldn't make it version-specific but that's up to you there isn't really a way to test this "regression" because the feature itself doesn't exist in previous versions |
@nicoddemus @bluetech so what would ya'll like to do. It sounds like @asottile would like us to revert the move of the import outside the function. |
@kdelee Can you move the imports back into the function? Then I think we can merge. |
@bluetech done, lmk if anything else is needed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😬 well not sure what those tests are blowing up about |
The failures are not due to this PR, it suddenly started to happen, we're not sure why yet. We will rerun the tests once this is resolved. |
This exists https://github.com/python/cpython/blob/3.10/Lib/importlib/readers.py and FileReader is in there This is a 404 https://github.com/python/cpython/blob/3.9/Lib/importlib/readers.py This change needs to get backported to the 7.0.z branch(s) too Fixes pytest-dev#9608
Co-authored-by: Elijah DeLee <[email protected]>
Co-authored-by: Ran Benita <[email protected]>
re: review from @asottile that this should only get imported in the function modify the else/if logic since inside the function we already know the python version is >= 3.10, and just have to know if it is 3.11 or greater
for more information, see https://pre-commit.ci
(Should have squashed instead of merged - oops) |
Thanks... 🙇 Do you mind to push a dot release and may be yank 7.0.0 on PyPI as this is making CI fails all over? That would be awesome! |
#9654 is up, if no other maintainer would like to include another fix, we can release it. (But doesn't make sense to yank 7.0.0 if we are releasing 7.0.1 right away). |
You rock 🎸 |
@@ -273,13 +273,15 @@ def get_data(self, pathname: Union[str, bytes]) -> bytes: | |||
with open(pathname, "rb") as f: | |||
return f.read() | |||
|
|||
if sys.version_info >= (3, 9): | |||
if sys.version_info >= (3, 10): | |||
|
|||
def get_resource_reader(self, name: str) -> importlib.abc.TraversableResources: # type: ignore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey, I'm currently writing a code analysis tool for Python projects. It pointed me to this code part, which I find quite interesting. Hence, I would have some questions about it:
- Where exactly is the
get_resource_reader()
function called? I can't find any references to it. - Why is the function defined by a condition? Would it make sense to move the version check inside the function with an early return? (As there is already a version check within it) As the function is public, it would keep the interface of the
AssertionRewritingHook
independent to the Python version.
I think these questions may be adressed to @kdelee or @nicoddemus? I would be really happy to hear from you as this would give me some qualitative insights on the reports of my tool.
Kind regards,
Matthias
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's called by the python import machinery itself. this function isn't valid until 3.10 (it breaks 3.9)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw the Github issue on the FileReader import causing the break for 3.9
Before, the import statement in the function was without any version check. But having the check sys.version_info >= (3, 10)
within the function with an early return shouldn't break anything as the import statement would never be reached for 3.9.
Or am I overlooking anything why the function would be invalid otherwise?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there's backports of parts of importlib which would reach into this and if the function is defined try and call it (and then error) -- by not defining the function, those backports won't even attempt to call it and therefore won't crash
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh ok I understand. Thanky you very much for your explanation, this helps me a lot!
This exists https://github.com/python/cpython/blob/3.10/Lib/importlib/readers.py and FileReader is in there
This is a 404 https://github.com/python/cpython/blob/3.9/Lib/importlib/readers.py
This change needs to get backported to the 7.0.z branch(s) too
closes #9608
I'm going to go ahead and open this PR, if you think we need a changelog for this LMK