-
-
Notifications
You must be signed in to change notification settings - Fork 29.2k
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
Unexpected exception with zip importer #89346
Comments
The attached file demonstrates the problem: If importlib.invalidate_caches() is called while the zipfile used by the zip importer is not available the import system breaks entirely. I found this in a testsuite that accedently did this (it should have updated sys.path). I get the following exception: $ python3.10 t.py
Traceback (most recent call last):
File "/Users/ronald/Projects/modulegraph2/t.py", line 27, in <module>
import uu
File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
File "<frozen importlib._bootstrap>", line 1002, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 945, in _find_spec
File "<frozen importlib._bootstrap_external>", line 1430, in find_spec
File "<frozen importlib._bootstrap_external>", line 1402, in _get_spec
File "<frozen zipimport>", line 168, in find_spec
File "<frozen zipimport>", line 375, in _get_module_info
TypeError: argument of type 'NoneType' is not iterable This exception is not very friendly.... This particular exception is caused by setting self._files to None in the importer's invalidate_caches method, while not checking for None in _get_modules_info. I'm not sure what the best fix would be, setting self._files to an empty list would likely be the easiest fix. Note that the script runs without errors in Python 3.9. |
I bisected this to: 3abf6f0 is the first bad commit
Doc/library/zipimport.rst | 9 + Which is https://bugs.python.org/issue14678 |
Brett, can you take a look when you have some time? |
I just noticed that I'm unnecessarily obtuse in my description of a possible fix, the diff (without test update): % git diff Lib/zipimport.py (main)cpython
diff --git a/Lib/zipimport.py b/Lib/zipimport.py
index c55fec6aa1..43ac6cbe57 100644
--- a/Lib/zipimport.py
+++ b/Lib/zipimport.py
@@ -334,7 +334,7 @@ def invalidate_caches(self):
_zip_directory_cache[self.archive] = self._files
except ZipImportError:
_zip_directory_cache.pop(self.archive, None)
- self._files = None
+ self._files = {}
def __repr__(self): With that change the exception should not happen, and the now stale zipimporter would be ignored when flushing the cache while the zipfile referenced by the zip importer instance has been removed. That said, I haven't tested this and won't create a PR because my local tree is (still) a mess. |
The proposed fix seems to be the right one based on my reading of the code. |
I decided that find_spec() saying something wasn't available in a finder made sense even though it was because a zip file no longer existed as the loader would still fail as appropriate. |
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: