mirror of
https://github.com/python/cpython.git
synced 2025-12-23 09:19:18 +00:00
[3.12] gh-121735: Fix module-adjacent references in zip files (gh-123037) (#124011)
This commit is contained in:
parent
10cf0b8caf
commit
c60d97805f
4 changed files with 45 additions and 12 deletions
|
|
@ -31,8 +31,10 @@ class FileReader(abc.TraversableResources):
|
|||
|
||||
class ZipReader(abc.TraversableResources):
|
||||
def __init__(self, loader, module):
|
||||
_, _, name = module.rpartition('.')
|
||||
self.prefix = loader.prefix.replace('\\', '/') + name + '/'
|
||||
self.prefix = loader.prefix.replace('\\', '/')
|
||||
if loader.is_package(module):
|
||||
_, _, name = module.rpartition('.')
|
||||
self.prefix += name + '/'
|
||||
self.archive = loader.archive
|
||||
|
||||
def open_resource(self, resource):
|
||||
|
|
|
|||
|
|
@ -108,6 +108,42 @@ class ImplicitContextFilesTests(SiteDir, unittest.TestCase):
|
|||
_path.build(spec, self.site_dir)
|
||||
assert importlib.import_module('somepkg').val == 'resources are the best'
|
||||
|
||||
def test_implicit_files_zip_submodule(self):
|
||||
"""
|
||||
Special test for gh-121735 for Python 3.12.
|
||||
"""
|
||||
import os
|
||||
import zipfile
|
||||
|
||||
def create_zip_from_directory(source_dir, zip_filename):
|
||||
with zipfile.ZipFile(zip_filename, 'w') as zipf:
|
||||
for root, _, files in os.walk(source_dir):
|
||||
for file in files:
|
||||
file_path = os.path.join(root, file)
|
||||
# Ensure files are at the root
|
||||
arcname = os.path.relpath(file_path, source_dir)
|
||||
zipf.write(file_path, arcname)
|
||||
|
||||
set_val = textwrap.dedent(
|
||||
"""
|
||||
import importlib.resources as res
|
||||
val = res.files().joinpath('res.txt').read_text(encoding='utf-8')
|
||||
"""
|
||||
)
|
||||
spec = {
|
||||
'somepkg': {
|
||||
'__init__.py': set_val,
|
||||
'submod.py': set_val,
|
||||
'res.txt': 'resources are the best',
|
||||
},
|
||||
}
|
||||
build_dir = self.fixtures.enter_context(os_helper.temp_dir())
|
||||
_path.build(spec, build_dir)
|
||||
zip_file = os.path.join(self.site_dir, 'thepkg.zip')
|
||||
create_zip_from_directory(build_dir, zip_file)
|
||||
self.fixtures.enter_context(import_helper.DirsOnSysPath(zip_file))
|
||||
assert importlib.import_module('somepkg.submod').val == 'resources are the best'
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
|||
|
|
@ -254,17 +254,9 @@ class zipimporter(_bootstrap_external._LoaderBasics):
|
|||
|
||||
|
||||
def get_resource_reader(self, fullname):
|
||||
"""Return the ResourceReader for a package in a zip file.
|
||||
|
||||
If 'fullname' is a package within the zip file, return the
|
||||
'ResourceReader' object for the package. Otherwise return None.
|
||||
"""
|
||||
try:
|
||||
if not self.is_package(fullname):
|
||||
return None
|
||||
except ZipImportError:
|
||||
return None
|
||||
"""Return the ResourceReader for a module in a zip file."""
|
||||
from importlib.readers import ZipReader
|
||||
|
||||
return ZipReader(self, fullname)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
When working with zip archives, importlib.resources now properly honors
|
||||
module-adjacent references (e.g. ``files(pkg.mod)`` and not just
|
||||
``files(pkg)``).
|
||||
Loading…
Add table
Add a link
Reference in a new issue