Hello community, here is the log from the commit of package python-zipp for openSUSE:Factory checked in at 2019-05-16 22:00:03 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-zipp (Old) and /work/SRC/openSUSE:Factory/.python-zipp.new.5148 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-zipp" Thu May 16 22:00:03 2019 rev:3 rq:703034 version:0.5.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-zipp/python-zipp.changes 2019-05-07 23:12:20.084087736 +0200 +++ /work/SRC/openSUSE:Factory/.python-zipp.new.5148/python-zipp.changes 2019-05-16 22:00:06.010775974 +0200 @@ -1,0 +2,7 @@ +Tue May 14 23:13:22 UTC 2019 - [email protected] + +- Update to 0.5.0 + * no changelog found + * Added runtime dependencies python-unittest2 and python-contextlib2 + +------------------------------------------------------------------- Old: ---- zipp-0.4.0.tar.gz New: ---- zipp-0.5.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-zipp.spec ++++++ --- /var/tmp/diff_new_pack.h89Uij/_old 2019-05-16 22:00:08.134774768 +0200 +++ /var/tmp/diff_new_pack.h89Uij/_new 2019-05-16 22:00:08.178774743 +0200 @@ -12,13 +12,13 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# Please submit bugfixes or comments via http://bugs.opensuse.org/ # %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-zipp -Version: 0.4.0 +Version: 0.5.0 Release: 0 Summary: Pathlib-compatible object wrapper for zip files License: MIT @@ -29,7 +29,9 @@ BuildRequires: %{python_module setuptools_scm >= 1.15.0} BuildRequires: %{python_module setuptools} BuildRequires: fdupes +BuildRequires: python-contextlib2 BuildRequires: python-rpm-macros +BuildRequires: python-unittest2 BuildArch: noarch %python_subpackages ++++++ zipp-0.4.0.tar.gz -> zipp-0.5.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zipp-0.4.0/CHANGES.rst new/zipp-0.5.0/CHANGES.rst --- old/zipp-0.4.0/CHANGES.rst 2019-04-28 19:12:35.000000000 +0200 +++ new/zipp-0.5.0/CHANGES.rst 2019-05-08 20:41:19.000000000 +0200 @@ -1,3 +1,10 @@ +v0.5.0 +====== + +Add ``.joinpath()`` method and ``.parent`` property. + +Now a backport release of the ``zipfile.Path`` class. + v0.4.0 ====== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zipp-0.4.0/PKG-INFO new/zipp-0.5.0/PKG-INFO --- old/zipp-0.4.0/PKG-INFO 2019-04-28 19:12:54.000000000 +0200 +++ new/zipp-0.5.0/PKG-INFO 2019-05-08 20:41:39.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: zipp -Version: 0.4.0 +Version: 0.5.0 Summary: Pathlib-compatible object wrapper for zip files Home-page: https://github.com/jaraco/zipp Author: Jason R. Coombs @@ -30,5 +30,5 @@ Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Requires-Python: >=2.7 -Provides-Extra: testing Provides-Extra: docs +Provides-Extra: testing diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zipp-0.4.0/conftest.py new/zipp-0.5.0/conftest.py --- old/zipp-0.4.0/conftest.py 2019-04-28 19:12:35.000000000 +0200 +++ new/zipp-0.5.0/conftest.py 2019-05-08 20:41:19.000000000 +0200 @@ -1,66 +0,0 @@ -# coding: utf-8 - -import io -import zipfile -import posixpath - -import pytest -from more_itertools import consume - - -def add_dirs(zipfile): - """ - Given a writable zipfile, inject directory entries for - any directories implied by the presence of children. - """ - names = zipfile.namelist() - consume( - zipfile.writestr(name + '/', '') - for name in map(posixpath.dirname, names) - if name - and name + '/' not in names - ) - return zipfile - - [email protected](params=[add_dirs, lambda x: x]) -def zipfile_abcde(request): - """ - Build the abcde zipfile with and without dir entries. - """ - return request.param(build_abcde_files()) - - [email protected] -def zipfile_abcde_full(): - return add_dirs(build_abcde_files()) - - -def build_abcde_files(): - """ - Create a zip file with this structure: - - . - ├── a.txt - └── b - ├── c.txt - └── d - └── e.txt - """ - data = io.BytesIO() - zf = zipfile.ZipFile(data, 'w') - zf.writestr('a.txt', 'content of a') - zf.writestr('b/c.txt', 'content of c') - zf.writestr('b/d/e.txt', 'content of e') - zf.filename = 'abcde.zip' - return zf - - [email protected] -def zipfile_ondisk(zipfile_abcde, tmpdir): - buffer = zipfile_abcde.fp - zipfile_abcde.close() - path = tmpdir / zipfile_abcde.filename - with path.open('wb') as strm: - strm.write(buffer.getvalue()) - return path diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zipp-0.4.0/pin-pip.py new/zipp-0.5.0/pin-pip.py --- old/zipp-0.4.0/pin-pip.py 2019-04-28 19:12:35.000000000 +0200 +++ new/zipp-0.5.0/pin-pip.py 2019-05-08 20:41:19.000000000 +0200 @@ -10,11 +10,8 @@ def main(): - subprocess.check_call(shlex.split( - 'python -m pip install pip<19.1' - )) - subprocess.check_call(shlex.split( - 'python -m pip install') + sys.argv[1:]) + subprocess.check_call(shlex.split("python -m pip install pip<19.1")) + subprocess.check_call(shlex.split("python -m pip install") + sys.argv[1:]) -__name__ == '__main__' and main() +__name__ == "__main__" and main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zipp-0.4.0/setup.cfg new/zipp-0.5.0/setup.cfg --- old/zipp-0.4.0/setup.cfg 2019-04-28 19:12:54.000000000 +0200 +++ new/zipp-0.5.0/setup.cfg 2019-05-08 20:41:39.000000000 +0200 @@ -26,12 +26,10 @@ [options.extras_require] testing = - pytest >= 3.5, !=3.7.3 - pytest-checkdocs - pytest-flake8 pathlib2 - more_itertools + contextlib2 + unittest2 docs = sphinx jaraco.packaging >= 3.2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zipp-0.4.0/test_zipp.py new/zipp-0.5.0/test_zipp.py --- old/zipp-0.4.0/test_zipp.py 2019-04-28 19:12:35.000000000 +0200 +++ new/zipp-0.5.0/test_zipp.py 2019-05-08 20:41:19.000000000 +0200 @@ -1,70 +1,172 @@ +# coding: utf-8 + from __future__ import division, unicode_literals +import io +import zipfile +import posixpath +import contextlib +import tempfile +import shutil try: import pathlib except ImportError: import pathlib2 as pathlib -import zipp +try: + from contextlib import ExitStack +except ImportError: + from contextlib2 import ExitStack +try: + import unittest -def test_iterdir_istype(zipfile_abcde): - root = zipp.Path(zipfile_abcde) - assert root.is_dir() - a, b = root.iterdir() - assert a.is_file() - assert b.is_dir() - c, d = b.iterdir() - assert c.is_file() - e, = d.iterdir() - assert e.is_file() - - -def test_open(zipfile_abcde): - root = zipp.Path(zipfile_abcde) - a, b = root.iterdir() - with a.open() as strm: - data = strm.read() - assert data == b'content of a' - - -def test_read(zipfile_abcde): - root = zipp.Path(zipfile_abcde) - a, b = root.iterdir() - assert a.read_text() == 'content of a' - assert a.read_bytes() == b'content of a' - - -def test_traverse_truediv(zipfile_abcde): - root = zipp.Path(zipfile_abcde) - a = root / 'a' - assert a.is_file() - e = root / 'b' / 'd' / 'e.txt' - assert e.read_text() == 'content of e' + unittest.TestCase.subTest +except AttributeError: + import unittest2 as unittest +import zipp -def test_traverse_simplediv(zipfile_abcde): +__metaclass__ = type +consume = tuple + + +def add_dirs(zipfile): """ - Disable the __future__.division when testing traversal. + Given a writable zipfile, inject directory entries for + any directories implied by the presence of children. """ - code = compile( - source="zipp.Path(zipfile_abcde) / 'a'", - filename='(test)', - mode='eval', - dont_inherit=True, + names = zipfile.namelist() + consume( + zipfile.writestr(name + "/", b"") + for name in map(posixpath.dirname, names) + if name and name + "/" not in names ) - eval(code) + return zipfile -def test_pathlike_construction(zipfile_ondisk): - """ - zipp.Path should be constructable from a path-like object +def build_abcde_files(): """ - pathlike = pathlib.Path(str(zipfile_ondisk)) - zipp.Path(pathlike) + Create a zip file with this structure: - -def test_traverse_pathlike(zipfile_abcde): - root = zipp.Path(zipfile_abcde) - root / pathlib.Path('a') + . + ├── a.txt + └── b + ├── c.txt + └── d + └── e.txt + """ + data = io.BytesIO() + zf = zipfile.ZipFile(data, "w") + zf.writestr("a.txt", b"content of a") + zf.writestr("b/c.txt", b"content of c") + zf.writestr("b/d/e.txt", b"content of e") + zf.filename = "abcde.zip" + return zf + + [email protected] +def tempdir(): + tmpdir = tempfile.mkdtemp() + try: + yield pathlib.Path(tmpdir) + finally: + shutil.rmtree(tmpdir) + + +class TestEverything(unittest.TestCase): + def setUp(self): + self.fixtures = ExitStack() + self.addCleanup(self.fixtures.close) + + def zipfile_abcde(self): + with self.subTest(): + yield build_abcde_files() + with self.subTest(): + yield add_dirs(build_abcde_files()) + + def zipfile_ondisk(self): + tmpdir = self.fixtures.enter_context(tempdir()) + for zipfile_abcde in self.zipfile_abcde(): + buffer = zipfile_abcde.fp + zipfile_abcde.close() + path = tmpdir / zipfile_abcde.filename + with path.open("wb") as strm: + strm.write(buffer.getvalue()) + yield path + + def test_iterdir_istype(self): + for zipfile_abcde in self.zipfile_abcde(): + root = zipp.Path(zipfile_abcde) + assert root.is_dir() + a, b = root.iterdir() + assert a.is_file() + assert b.is_dir() + c, d = b.iterdir() + assert c.is_file() + e, = d.iterdir() + assert e.is_file() + + def test_open(self): + for zipfile_abcde in self.zipfile_abcde(): + root = zipp.Path(zipfile_abcde) + a, b = root.iterdir() + with a.open() as strm: + data = strm.read() + assert data == b"content of a" + + def test_read(self): + for zipfile_abcde in self.zipfile_abcde(): + root = zipp.Path(zipfile_abcde) + a, b = root.iterdir() + assert a.read_text() == "content of a" + assert a.read_bytes() == b"content of a" + + def test_joinpath(self): + for zipfile_abcde in self.zipfile_abcde(): + root = zipp.Path(zipfile_abcde) + a = root.joinpath("a") + assert a.is_file() + e = root.joinpath("b").joinpath("d").joinpath("e.txt") + assert e.read_text() == "content of e" + + def test_traverse_truediv(self): + for zipfile_abcde in self.zipfile_abcde(): + root = zipp.Path(zipfile_abcde) + a = root / "a" + assert a.is_file() + e = root / "b" / "d" / "e.txt" + assert e.read_text() == "content of e" + + def test_traverse_simplediv(self): + """ + Disable the __future__.division when testing traversal. + """ + for zipfile_abcde in self.zipfile_abcde(): + code = compile( + source="zipp.Path(zipfile_abcde) / 'a'", + filename="(test)", + mode="eval", + dont_inherit=True, + ) + eval(code) + + def test_pathlike_construction(self): + """ + zipp.Path should be constructable from a path-like object + """ + for zipfile_ondisk in self.zipfile_ondisk(): + pathlike = pathlib.Path(str(zipfile_ondisk)) + zipp.Path(pathlike) + + def test_traverse_pathlike(self): + for zipfile_abcde in self.zipfile_abcde(): + root = zipp.Path(zipfile_abcde) + root / pathlib.Path("a") + + def test_parent(self): + for zipfile_abcde in self.zipfile_abcde(): + root = zipp.Path(zipfile_abcde) + assert (root / 'a').parent.at == '' + assert (root / 'a' / 'b').parent.at == 'a/' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zipp-0.4.0/tox.ini new/zipp-0.5.0/tox.ini --- old/zipp-0.4.0/tox.ini 2019-04-28 19:12:35.000000000 +0200 +++ new/zipp-0.5.0/tox.ini 2019-05-08 20:41:19.000000000 +0200 @@ -9,7 +9,7 @@ deps = setuptools>=31.0.1 commands = - pytest {posargs} + python -m unittest discover usedevelop = True extras = testing diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zipp-0.4.0/zipp.egg-info/PKG-INFO new/zipp-0.5.0/zipp.egg-info/PKG-INFO --- old/zipp-0.4.0/zipp.egg-info/PKG-INFO 2019-04-28 19:12:53.000000000 +0200 +++ new/zipp-0.5.0/zipp.egg-info/PKG-INFO 2019-05-08 20:41:39.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: zipp -Version: 0.4.0 +Version: 0.5.0 Summary: Pathlib-compatible object wrapper for zip files Home-page: https://github.com/jaraco/zipp Author: Jason R. Coombs @@ -30,5 +30,5 @@ Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Requires-Python: >=2.7 -Provides-Extra: testing Provides-Extra: docs +Provides-Extra: testing diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zipp-0.4.0/zipp.egg-info/requires.txt new/zipp-0.5.0/zipp.egg-info/requires.txt --- old/zipp-0.4.0/zipp.egg-info/requires.txt 2019-04-28 19:12:53.000000000 +0200 +++ new/zipp-0.5.0/zipp.egg-info/requires.txt 2019-05-08 20:41:39.000000000 +0200 @@ -5,8 +5,6 @@ rst.linker>=1.9 [testing] -pytest!=3.7.3,>=3.5 -pytest-checkdocs -pytest-flake8 pathlib2 -more_itertools +contextlib2 +unittest2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zipp-0.4.0/zipp.py new/zipp-0.5.0/zipp.py --- old/zipp-0.4.0/zipp.py 2019-04-28 19:12:35.000000000 +0200 +++ new/zipp-0.5.0/zipp.py 2019-05-08 20:41:19.000000000 +0200 @@ -1,26 +1,4 @@ -""" ->>> root = Path(getfixture('zipfile_abcde_full')) ->>> a, b = root.iterdir() ->>> a -Path('abcde.zip', 'a.txt') ->>> b -Path('abcde.zip', 'b/') ->>> b.name -'b' ->>> c = b / 'c.txt' ->>> c -Path('abcde.zip', 'b/c.txt') ->>> c.name -'c.txt' ->>> c.read_text() -'content of c' ->>> c.exists() -True ->>> (b / 'missing.txt').exists() -False ->>> str(c) -'abcde.zip/b/c.txt' -""" +# coding: utf-8 from __future__ import division @@ -34,11 +12,78 @@ class Path: - __repr = '{self.__class__.__name__}({self.root.filename!r}, {self.at!r})' + """ + A pathlib-compatible interface for zip files. - def __init__(self, root, at=''): - self.root = root if isinstance(root, zipfile.ZipFile) \ + Consider a zip file with this structure:: + + . + ├── a.txt + └── b + ├── c.txt + └── d + └── e.txt + + >>> data = io.BytesIO() + >>> zf = zipfile.ZipFile(data, 'w') + >>> zf.writestr('a.txt', 'content of a') + >>> zf.writestr('b/c.txt', 'content of c') + >>> zf.writestr('b/d/e.txt', 'content of e') + >>> zf.filename = 'abcde.zip' + + Path accepts the zipfile object itself or a filename + + >>> root = Path(zf) + + From there, several path operations are available. + + Directory iteration (including the zip file itself): + + >>> a, b = root.iterdir() + >>> a + Path('abcde.zip', 'a.txt') + >>> b + Path('abcde.zip', 'b/') + + name property: + + >>> b.name + 'b' + + join with divide operator: + + >>> c = b / 'c.txt' + >>> c + Path('abcde.zip', 'b/c.txt') + >>> c.name + 'c.txt' + + Read text: + + >>> c.read_text() + 'content of c' + + existence: + + >>> c.exists() + True + >>> (b / 'missing.txt').exists() + False + + Coersion to string: + + >>> str(c) + 'abcde.zip/b/c.txt' + """ + + __repr = "{self.__class__.__name__}({self.root.filename!r}, {self.at!r})" + + def __init__(self, root, at=""): + self.root = ( + root + if isinstance(root, zipfile.ZipFile) else zipfile.ZipFile(self._pathlib_compat(root)) + ) self.at = at @staticmethod @@ -58,7 +103,7 @@ @property def name(self): - return posixpath.basename(self.at.rstrip('/')) + return posixpath.basename(self.at.rstrip("/")) def read_text(self, *args, **kwargs): with self.open() as strm: @@ -69,13 +114,13 @@ return strm.read() def _is_child(self, path): - return posixpath.dirname(path.at.rstrip('/')) == self.at.rstrip('/') + return posixpath.dirname(path.at.rstrip("/")) == self.at.rstrip("/") def _next(self, at): return Path(self.root, at) def is_dir(self): - return not self.at or self.at.endswith('/') + return not self.at or self.at.endswith("/") def is_file(self): return not self.is_dir() @@ -95,24 +140,30 @@ def __repr__(self): return self.__repr.format(self=self) - def __truediv__(self, add): + def joinpath(self, add): add = self._pathlib_compat(add) next = posixpath.join(self.at, add) - next_dir = posixpath.join(self.at, add, '') + next_dir = posixpath.join(self.at, add, "") names = self._names() - return self._next( - next_dir if next not in names and next_dir in names else next - ) + return self._next(next_dir if next not in names and next_dir in names else next) + + __truediv__ = joinpath @staticmethod def _add_implied_dirs(names): return names + [ - name + '/' + name + "/" for name in map(posixpath.dirname, names) - if name - and name + '/' not in names + if name and name + "/" not in names ] + @property + def parent(self): + parent_at = posixpath.dirname(self.at) + if parent_at: + parent_at += '/' + return self._next(parent_at) + def _names(self): return self._add_implied_dirs(self.root.namelist())
