From 4aec9a8be2f2574f249008eb8be76c070fea37eb Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 25 Mar 2017 13:05:23 +0200 Subject: [PATCH] bpo-29901: Improve support of path-like objects in zipapp. (#815) Now general path-like objects are supported, not just pathlib.Path. --- Doc/library/zipapp.rst | 8 ++++---- Lib/zipapp.py | 11 ++++------- Misc/NEWS | 3 +++ 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Doc/library/zipapp.rst b/Doc/library/zipapp.rst index 9dee9a5ac07..71753cb9a0d 100644 --- a/Doc/library/zipapp.rst +++ b/Doc/library/zipapp.rst @@ -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. diff --git a/Lib/zipapp.py b/Lib/zipapp.py index eceb91de1aa..c23b788d1c9 100644 --- a/Lib/zipapp.py +++ b/Lib/zipapp.py @@ -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')) diff --git a/Misc/NEWS b/Misc/NEWS index a5653c8524f..8360abbdb7b 100644 --- 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.