https://github.com/python/cpython/commit/698c6e3a0cdbff4150674b0b831cf1ef27efecc8 commit: 698c6e3a0cdbff4150674b0b831cf1ef27efecc8 branch: main author: Johannes Holmberg <johan...@update.uu.se> committer: pfmoore <p.f.mo...@gmail.com> date: 2025-04-29T15:14:46+01:00 summary:
gh-132933: zipapp - apply the filter when creating the list of files to add (gh-132934) files: A Misc/NEWS.d/next/Library/2025-04-25-21-41-45.gh-issue-132933.yO3ySJ.rst M Lib/test/test_zipapp.py M Lib/zipapp.py diff --git a/Lib/test/test_zipapp.py b/Lib/test/test_zipapp.py index ad132839622f48..d4766c59a102db 100644 --- a/Lib/test/test_zipapp.py +++ b/Lib/test/test_zipapp.py @@ -113,6 +113,19 @@ def test_target_overwrites_source_file(self): with self.assertRaises(zipapp.ZipAppError): zipapp.create_archive(source, target) + def test_target_overwrites_filtered_source_file(self): + # If there's a filter that excludes the target, + # the overwrite check shouldn't trigger. + source = self.tmpdir + (source / '__main__.py').touch() + target = source / 'target.pyz' + target.touch() + pyz_filter = lambda p: not p.match('*.pyz') + zipapp.create_archive(source, target, filter=pyz_filter) + with zipfile.ZipFile(target, 'r') as z: + self.assertEqual(len(z.namelist()), 1) + self.assertIn('__main__.py', z.namelist()) + def test_create_archive_filter_exclude_dir(self): # Test packing a directory and using a filter to exclude a # subdirectory (ensures that the path supplied to include diff --git a/Lib/zipapp.py b/Lib/zipapp.py index 4ffacc49fa753d..59b444075a62d0 100644 --- a/Lib/zipapp.py +++ b/Lib/zipapp.py @@ -134,7 +134,11 @@ def create_archive(source, target=None, interpreter=None, main=None, # Create the list of files to add to the archive now, in case # the target is being created in the source directory - we # don't want the target being added to itself - files_to_add = sorted(source.rglob('*')) + files_to_add = {} + for path in sorted(source.rglob('*')): + relative_path = path.relative_to(source) + if filter is None or filter(relative_path): + files_to_add[path] = relative_path # The target cannot be in the list of files to add. If it were, we'd # end up overwriting the source file and writing the archive into @@ -159,10 +163,8 @@ def create_archive(source, target=None, interpreter=None, main=None, compression = (zipfile.ZIP_DEFLATED if compressed else zipfile.ZIP_STORED) with zipfile.ZipFile(fd, 'w', compression=compression) as z: - for child in files_to_add: - arcname = child.relative_to(source) - if filter is None or filter(arcname): - z.write(child, arcname.as_posix()) + for path, relative_path in files_to_add.items(): + z.write(path, relative_path.as_posix()) if main_py: z.writestr('__main__.py', main_py.encode('utf-8')) diff --git a/Misc/NEWS.d/next/Library/2025-04-25-21-41-45.gh-issue-132933.yO3ySJ.rst b/Misc/NEWS.d/next/Library/2025-04-25-21-41-45.gh-issue-132933.yO3ySJ.rst new file mode 100644 index 00000000000000..7d5eb3b0897200 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-04-25-21-41-45.gh-issue-132933.yO3ySJ.rst @@ -0,0 +1 @@ +The zipapp module now applies the filter when creating the list of files to add, rather than waiting until the file is being added to the archive. _______________________________________________ Python-checkins mailing list -- python-checkins@python.org To unsubscribe send an email to python-checkins-le...@python.org https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: arch...@mail-archive.com