Skip to content

Commit

Permalink
bpo-31072: Rename the new filter argument for zipapp.create_archive. (p…
Browse files Browse the repository at this point in the history
…ython#3049)

bpo-31072: Rename the new filter argument for zipapp.create_archive (pythonGH-3049)

* Rename the new argument to "filter"
* Improve tests for the new functionality
* Add a "What's New" entry.
  • Loading branch information
pfmoore authored Aug 26, 2017
1 parent a5b4ea1 commit 0780bf7
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 13 deletions.
12 changes: 8 additions & 4 deletions Doc/library/zipapp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ The module defines two convenience functions:


.. function:: create_archive(source, target=None, interpreter=None, main=None,
include_file=None)
filter=None)

Create an application archive from *source*. The source can be any
of the following:
Expand Down Expand Up @@ -144,9 +144,10 @@ The module defines two convenience functions:
contain a ``__main__.py`` file, as otherwise the resulting archive
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.
The optional *filter* argument specifies a callback function that
is passed a Path object representing the path to the file being added
(relative to the source directory). It should return ``True`` if the
file is to be added.

If a file object is specified for *source* or *target*, it is the
caller's responsibility to close it after calling create_archive.
Expand All @@ -157,6 +158,9 @@ The module defines two convenience functions:
passed to the ``zipfile.ZipFile`` class, and must supply the methods
needed by that class.

.. versionadded:: 3.7
Added the *filter* argument.

.. function:: get_interpreter(archive)

Return the interpreter specified in the ``#!`` line at the start of the
Expand Down
7 changes: 7 additions & 0 deletions Doc/whatsnew/3.7.rst
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,13 @@ Function :func:`~uu.encode` now accepts an optional *backtick*
keyword argument. When it's true, zeros are represented by ``'`'``
instead of spaces. (Contributed by Xiang Zhang in :issue:`30103`.)

zipapp
------

Function :func:`zipapp.create_archive` now accepts an optional *filter*
argument, to allow the user to select which files should be included in the
archive.


Optimizations
=============
Expand Down
31 changes: 26 additions & 5 deletions Lib/test/test_zipapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,23 +53,44 @@ def test_create_archive_with_subdirs(self):
self.assertIn('foo/', 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)
def test_create_archive_with_filter(self):
# Test packing a directory and using filter to specify
# which files to include.
def skip_pyc_files(path):
return path.suffix != '.pyc'
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)
zipapp.create_archive(source, target, filter=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_filter_exclude_dir(self):
# Test packing a directory and using a filter to exclude a
# subdirectory (ensures that the path supplied to include
# is relative to the source location, as expected).
def skip_dummy_dir(path):
return path.parts[0] != 'dummy'
source = self.tmpdir / 'source'
source.mkdir()
(source / '__main__.py').touch()
(source / 'test.py').touch()
(source / 'dummy').mkdir()
(source / 'dummy' / 'test2.py').touch()
target = self.tmpdir / 'source.pyz'

zipapp.create_archive(source, target, filter=skip_dummy_dir)
with zipfile.ZipFile(target, 'r') as z:
self.assertEqual(len(z.namelist()), 2)
self.assertIn('__main__.py', z.namelist())
self.assertIn('test.py', z.namelist())

def test_create_archive_default_target(self):
# Test packing a directory to the default name.
source = self.tmpdir / 'source'
Expand Down
8 changes: 4 additions & 4 deletions Lib/zipapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def _copy_archive(archive, new_archive, interpreter=None):


def create_archive(source, target=None, interpreter=None, main=None,
include_file=None):
filter=None):
"""Create an application archive from SOURCE.
The SOURCE can be the name of a directory, or a filename or a file-like
Expand Down Expand Up @@ -135,9 +135,9 @@ def create_archive(source, target=None, interpreter=None, main=None,
_write_file_prefix(fd, interpreter)
with zipfile.ZipFile(fd, 'w') as z:
for child in source.rglob('*'):
arcname = child.relative_to(source).as_posix()
if include_file is None or include_file(pathlib.Path(arcname)):
z.write(child, arcname)
arcname = child.relative_to(source)
if filter is None or filter(arcname):
z.write(child, arcname.as_posix())
if main_py:
z.writestr('__main__.py', main_py.encode('utf-8'))

Expand Down

0 comments on commit 0780bf7

Please sign in to comment.