]> granicus.if.org Git - python/commitdiff
bpo-31072: Add filter to zipapp (#3021)
authorJeffrey Rackauckas <jeffreyrack@gmail.com>
Wed, 9 Aug 2017 13:37:17 +0000 (06:37 -0700)
committerPaul Moore <p.f.moore@gmail.com>
Wed, 9 Aug 2017 13:37:17 +0000 (14:37 +0100)
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

Doc/library/zipapp.rst
Lib/test/test_zipapp.py
Lib/zipapp.py
Misc/ACKS
Misc/NEWS.d/next/Library/2017-08-09-13-45-23.bpo-31072.NLXDPV.rst [new file with mode: 0644]

index 71753cb9a0d7c299907d2d1c37a6381f890085da..993c2ccc39883a84e3a49a80c9a44dcc8e6d0c94 100644 (file)
@@ -98,7 +98,8 @@ Python API
 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
    of the following:
@@ -143,6 +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.
+
    If a file object is specified for *source* or *target*, it is the
    caller's responsibility to close it after calling create_archive.
 
index d8d44375bdd222b57ad457b44ab367aa7e98f4c5..47eed5f4a6cf83f4e99f9f4db4bf746e234c8a0c 100644 (file)
@@ -53,6 +53,23 @@ class ZipAppTest(unittest.TestCase):
             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)
+        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):
         # Test packing a directory to the default name.
         source = self.tmpdir / 'source'
index c23b788d1c9b7dcc5fb3686a33183e24c8c963f6..bf15b6806dd217e0f2c5e87a07b6cb8368f60451 100644 (file)
@@ -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)
 
 
-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.
 
     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:
             for child in source.rglob('*'):
                 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:
                 z.writestr('__main__.py', main_py.encode('utf-8'))
 
index e340392d8e1655629ad11448d508dc584284a2e4..d6088b3f5d987b4fd4cbc166fa9767d4054b8fe4 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1253,6 +1253,7 @@ Brian Quinlan
 Anders Qvist
 Thomas Rachel
 Ram Rachum
+Jeffrey Rackauckas
 Jérôme Radix
 Burton Radons
 Abhilash Raj
diff --git a/Misc/NEWS.d/next/Library/2017-08-09-13-45-23.bpo-31072.NLXDPV.rst b/Misc/NEWS.d/next/Library/2017-08-09-13-45-23.bpo-31072.NLXDPV.rst
new file mode 100644 (file)
index 0000000..8c96201
--- /dev/null
@@ -0,0 +1 @@
+Add an ``include_file`` parameter to ``zipapp.create_archive()``