Skip to content

Commit

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

bpo-31072: Rename the new filter argument for zipapp.create_archive (GH-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

1 comment on commit 0780bf7

@irmen
Copy link

@irmen irmen commented on 0780bf7 Aug 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for implementing this Paul (I couldn't respond on the bug tracker)

Please sign in to comment.