-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
gh-121111: Fix zipimport incorrectly dealing with namespace packages
#121161
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
Changes from all commits
3fe135e
439db09
3027488
11cdb6b
b8a2936
518d952
f5d85a5
a9c8e28
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -305,7 +305,18 @@ def __repr__(self): | |
| # Given a module name, return the potential file path in the | ||
| # archive (without extension). | ||
| def _get_module_path(self, fullname): | ||
| return self.prefix + fullname.rpartition('.')[2] | ||
| path = self.prefix + fullname.rpartition(".")[2] | ||
|
|
||
| # Here be dragons. | ||
| # Originally, this *only* used rpartition('.')[2] to find | ||
| # the last item in a namespace package, but that made it basically | ||
| # impossible to use nested submodules. | ||
| for suffix, _, _ in [*_zip_searchorder, (path_sep, False, False)]: | ||
| if (path + suffix) in self._get_files(): | ||
| # OK, we found it the old way. Let's return it. | ||
| return path | ||
|
|
||
| return self.prefix + fullname.replace(".", path_sep) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As https://github.com/python/cpython/pull/121161/files#r1660062444 described, this patch has no effect, shoud patch
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
From what I found, there's no problem with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For namespace package's dealing and operation, there has already clearly explained in the source code comment. You can see them in And, why your test with If you like to test into zipimport functions, it should be def testImportSubmodulesInZip(self):
with ZipFile(TEMP_ZIP, "w") as z:
z.writestr("a/__init__.py", b'')
z.writestr("a/b/c/__init__.py", b'def foo(): return "foo"')
importer = zipimport.zipimporter(TEMP_ZIP + "/a/")
spec = importer.find_spec("a.b")
self.assertEqual(spec.loader, None)
self.assertEqual(spec.submodule_search_locations,
[(TEMP_ZIP + "/a/b").replace("/", zipimport.path_sep)])
self.assertRaises(zipimport.ZipImportError, importer.get_code, "a.b")
self.assertEqual(importer.get_data("a/b/"), b"")
sys.path.insert(0, TEMP_ZIP)
try:
import a.b.c
self.assertIn('namespace', str(a.b).lower())
self.assertEqual(a.b.c.foo(), "foo")
finally:
del sys.path[0]
sys.modules.pop('a.b.c', None)
sys.modules.pop('a.b', None)
sys.modules.pop('a', None)
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| # Does this path represent a directory? | ||
| def _is_dir(self, path): | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| Fixed ``zipimport.zipimporter`` improperly handling nested submodules inside | ||
| of a zip file. |
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.
If here test the namespace module in zip,
mkdir()must be removed, this bug is triggered by no directory entry in zip.And don't do test via zipimport, that always fail/succeed, because find functons depend the loader's path prefix. Direct import namespace module can cover all cases.
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'm a bit confused on what you want here - the test passes, why should
mkdir()be removed?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.
Again, this bug is triggered by no directory entry in zip. If the directory entry is already exists, everything is OK.