mirror of
https://github.com/python/cpython.git
synced 2025-11-26 21:33:10 +00:00
bpo-31072: Add filter to zipapp (#3021)
bpo-31072: Add a filter argument to zipapp.create_archive (GH-3021) * Add an include_file argument to allow callers to decide which files to include * Document the new argument
This commit is contained in:
parent
9b0d1d647e
commit
b811d664de
5 changed files with 29 additions and 3 deletions
|
|
@ -98,7 +98,8 @@ Python API
|
||||||
The module defines two convenience functions:
|
The module defines two convenience functions:
|
||||||
|
|
||||||
|
|
||||||
.. function:: create_archive(source, target=None, interpreter=None, main=None)
|
.. function:: create_archive(source, target=None, interpreter=None, main=None,
|
||||||
|
include_file=None)
|
||||||
|
|
||||||
Create an application archive from *source*. The source can be any
|
Create an application archive from *source*. The source can be any
|
||||||
of the following:
|
of the following:
|
||||||
|
|
@ -143,6 +144,10 @@ The module defines two convenience functions:
|
||||||
contain a ``__main__.py`` file, as otherwise the resulting archive
|
contain a ``__main__.py`` file, as otherwise the resulting archive
|
||||||
would not be executable.
|
would not be executable.
|
||||||
|
|
||||||
|
The *include_file* argument specifies a callback function that is passed the
|
||||||
|
relative path to the file in order to determine which files to store when
|
||||||
|
being called against a directory.
|
||||||
|
|
||||||
If a file object is specified for *source* or *target*, it is the
|
If a file object is specified for *source* or *target*, it is the
|
||||||
caller's responsibility to close it after calling create_archive.
|
caller's responsibility to close it after calling create_archive.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,23 @@ class ZipAppTest(unittest.TestCase):
|
||||||
self.assertIn('foo/', z.namelist())
|
self.assertIn('foo/', z.namelist())
|
||||||
self.assertIn('bar/', z.namelist())
|
self.assertIn('bar/', z.namelist())
|
||||||
|
|
||||||
|
def test_create_archive_with_include_file(self):
|
||||||
|
# Test packing a directory and using include_file to specify which files to include.
|
||||||
|
def skip_pyc_files(file):
|
||||||
|
return '.pyc' not in str(file)
|
||||||
|
source = self.tmpdir / 'source'
|
||||||
|
source.mkdir()
|
||||||
|
(source / '__main__.py').touch()
|
||||||
|
(source / 'test.py').touch()
|
||||||
|
(source / 'test.pyc').touch()
|
||||||
|
target = self.tmpdir / 'source.pyz'
|
||||||
|
|
||||||
|
zipapp.create_archive(source, target, include_file=skip_pyc_files)
|
||||||
|
with zipfile.ZipFile(target, 'r') as z:
|
||||||
|
self.assertIn('__main__.py', z.namelist())
|
||||||
|
self.assertIn('test.py', z.namelist())
|
||||||
|
self.assertNotIn('test.pyc', z.namelist())
|
||||||
|
|
||||||
def test_create_archive_default_target(self):
|
def test_create_archive_default_target(self):
|
||||||
# Test packing a directory to the default name.
|
# Test packing a directory to the default name.
|
||||||
source = self.tmpdir / 'source'
|
source = self.tmpdir / 'source'
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,8 @@ def _copy_archive(archive, new_archive, interpreter=None):
|
||||||
os.chmod(new_archive, os.stat(new_archive).st_mode | stat.S_IEXEC)
|
os.chmod(new_archive, os.stat(new_archive).st_mode | stat.S_IEXEC)
|
||||||
|
|
||||||
|
|
||||||
def create_archive(source, target=None, interpreter=None, main=None):
|
def create_archive(source, target=None, interpreter=None, main=None,
|
||||||
|
include_file=None):
|
||||||
"""Create an application archive from SOURCE.
|
"""Create an application archive from SOURCE.
|
||||||
|
|
||||||
The SOURCE can be the name of a directory, or a filename or a file-like
|
The SOURCE can be the name of a directory, or a filename or a file-like
|
||||||
|
|
@ -135,7 +136,8 @@ def create_archive(source, target=None, interpreter=None, main=None):
|
||||||
with zipfile.ZipFile(fd, 'w') as z:
|
with zipfile.ZipFile(fd, 'w') as z:
|
||||||
for child in source.rglob('*'):
|
for child in source.rglob('*'):
|
||||||
arcname = child.relative_to(source).as_posix()
|
arcname = child.relative_to(source).as_posix()
|
||||||
z.write(child, arcname)
|
if include_file is None or include_file(pathlib.Path(arcname)):
|
||||||
|
z.write(child, arcname)
|
||||||
if main_py:
|
if main_py:
|
||||||
z.writestr('__main__.py', main_py.encode('utf-8'))
|
z.writestr('__main__.py', main_py.encode('utf-8'))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1253,6 +1253,7 @@ Brian Quinlan
|
||||||
Anders Qvist
|
Anders Qvist
|
||||||
Thomas Rachel
|
Thomas Rachel
|
||||||
Ram Rachum
|
Ram Rachum
|
||||||
|
Jeffrey Rackauckas
|
||||||
Jérôme Radix
|
Jérôme Radix
|
||||||
Burton Radons
|
Burton Radons
|
||||||
Abhilash Raj
|
Abhilash Raj
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Add an ``include_file`` parameter to ``zipapp.create_archive()``
|
||||||
Loading…
Add table
Add a link
Reference in a new issue