Skip to content

Commit 698c6e3

Browse files
authored
gh-132933: zipapp - apply the filter when creating the list of files to add (gh-132934)
1 parent a64fdc7 commit 698c6e3

File tree

3 files changed

+21
-5
lines changed

3 files changed

+21
-5
lines changed

Lib/test/test_zipapp.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,19 @@ def test_target_overwrites_source_file(self):
113113
with self.assertRaises(zipapp.ZipAppError):
114114
zipapp.create_archive(source, target)
115115

116+
def test_target_overwrites_filtered_source_file(self):
117+
# If there's a filter that excludes the target,
118+
# the overwrite check shouldn't trigger.
119+
source = self.tmpdir
120+
(source / '__main__.py').touch()
121+
target = source / 'target.pyz'
122+
target.touch()
123+
pyz_filter = lambda p: not p.match('*.pyz')
124+
zipapp.create_archive(source, target, filter=pyz_filter)
125+
with zipfile.ZipFile(target, 'r') as z:
126+
self.assertEqual(len(z.namelist()), 1)
127+
self.assertIn('__main__.py', z.namelist())
128+
116129
def test_create_archive_filter_exclude_dir(self):
117130
# Test packing a directory and using a filter to exclude a
118131
# subdirectory (ensures that the path supplied to include

Lib/zipapp.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,11 @@ def create_archive(source, target=None, interpreter=None, main=None,
134134
# Create the list of files to add to the archive now, in case
135135
# the target is being created in the source directory - we
136136
# don't want the target being added to itself
137-
files_to_add = sorted(source.rglob('*'))
137+
files_to_add = {}
138+
for path in sorted(source.rglob('*')):
139+
relative_path = path.relative_to(source)
140+
if filter is None or filter(relative_path):
141+
files_to_add[path] = relative_path
138142

139143
# The target cannot be in the list of files to add. If it were, we'd
140144
# 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,
159163
compression = (zipfile.ZIP_DEFLATED if compressed else
160164
zipfile.ZIP_STORED)
161165
with zipfile.ZipFile(fd, 'w', compression=compression) as z:
162-
for child in files_to_add:
163-
arcname = child.relative_to(source)
164-
if filter is None or filter(arcname):
165-
z.write(child, arcname.as_posix())
166+
for path, relative_path in files_to_add.items():
167+
z.write(path, relative_path.as_posix())
166168
if main_py:
167169
z.writestr('__main__.py', main_py.encode('utf-8'))
168170

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
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.

0 commit comments

Comments
 (0)