bpo-29901: Improve support of path-like objects in zipapp. (#815)
authorSerhiy Storchaka <storchaka@gmail.com>
Sat, 25 Mar 2017 11:05:23 +0000 (13:05 +0200)
committerGitHub <noreply@github.com>
Sat, 25 Mar 2017 11:05:23 +0000 (13:05 +0200)
Now general path-like objects are supported, not just pathlib.Path.

Doc/library/zipapp.rst
Lib/zipapp.py
Misc/NEWS

index 9dee9a5ac07e2f2621558865769605bd92860cb0..71753cb9a0d7c299907d2d1c37a6381f890085da 100644 (file)
@@ -103,11 +103,11 @@ The module defines two convenience functions:
    Create an application archive from *source*.  The source can be any
    of the following:
 
-   * The name of a directory, or a :class:`pathlib.Path` object referring
+   * The name of a directory, or a :term:`path-like object` referring
      to a directory, in which case a new application archive will be
      created from the content of that directory.
-   * The name of an existing application archive file, or a :class:`pathlib.Path`
-     object referring to such a file, in which case the file is copied to
+   * The name of an existing application archive file, or a :term:`path-like object`
+     referring to such a file, in which case the file is copied to
      the target (modifying it to reflect the value given for the *interpreter*
      argument).  The file name should include the ``.pyz`` extension, if required.
    * A file object open for reading in bytes mode.  The content of the
@@ -117,7 +117,7 @@ The module defines two convenience functions:
    The *target* argument determines where the resulting archive will be
    written:
 
-   * If it is the name of a file, or a :class:`pathlb.Path` object,
+   * If it is the name of a file, or a :term:`path-like object`,
      the archive will be written to that file.
    * If it is an open file object, the archive will be written to that
      file object, which must be open for writing in bytes mode.
index eceb91de1aa455e4f20542ecaaf0aa0b88780ee0..c23b788d1c9b7dcc5fb3686a33183e24c8c963f6 100644 (file)
@@ -36,9 +36,7 @@ class ZipAppError(ValueError):
 
 @contextlib.contextmanager
 def _maybe_open(archive, mode):
-    if isinstance(archive, pathlib.Path):
-        archive = str(archive)
-    if isinstance(archive, str):
+    if isinstance(archive, (str, os.PathLike)):
         with open(archive, mode) as f:
             yield f
     else:
@@ -135,10 +133,9 @@ def create_archive(source, target=None, interpreter=None, main=None):
     with _maybe_open(target, 'wb') as fd:
         _write_file_prefix(fd, interpreter)
         with zipfile.ZipFile(fd, 'w') as z:
-            root = pathlib.Path(source)
-            for child in root.rglob('*'):
-                arcname = str(child.relative_to(root))
-                z.write(str(child), arcname)
+            for child in source.rglob('*'):
+                arcname = child.relative_to(source).as_posix()
+                z.write(child, arcname)
             if main_py:
                 z.writestr('__main__.py', main_py.encode('utf-8'))
 
index a5653c8524ff4e2e6bf9e062f15dfc7df840bbd8..8360abbdb7bae3c4b93eb53801d1af2ff93fa8dd 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -291,6 +291,9 @@ Extension Modules
 Library
 -------
 
+- bpo-29901: The zipapp module now supports general path-like objects, not
+  just pathlib.Path.
+
 - bpo-25803: Avoid incorrect errors raised by Path.mkdir(exist_ok=True)
   when the OS gives priority to errors such as EACCES over EEXIST.