Hello community, here is the log from the commit of package python-pathlib2 for openSUSE:Factory checked in at 2019-07-28 10:17:37 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pathlib2 (Old) and /work/SRC/openSUSE:Factory/.python-pathlib2.new.4126 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pathlib2" Sun Jul 28 10:17:37 2019 rev:10 rq:717895 version:2.3.4 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pathlib2/python-pathlib2.changes 2019-03-12 09:46:16.887623378 +0100 +++ /work/SRC/openSUSE:Factory/.python-pathlib2.new.4126/python-pathlib2.changes 2019-07-28 10:17:42.300600311 +0200 @@ -1,0 +2,8 @@ +Tue Jul 23 13:19:03 UTC 2019 - Tomáš Chvátal <tchva...@suse.com> + +- Update to 2.3.4: + * Do not raise windows error when calling resolve on a non-existing path in Python 2.7, to match behaviour on Python 3.x (see issue #54). + * Use the new collections.abc when possible (see issue #53). + * Sync with upstream pathlib (see issues #47 and #51). + +------------------------------------------------------------------- Old: ---- pathlib2-2.3.3.tar.gz New: ---- pathlib2-2.3.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pathlib2.spec ++++++ --- /var/tmp/diff_new_pack.pvGvjp/_old 2019-07-28 10:17:44.692600405 +0200 +++ /var/tmp/diff_new_pack.pvGvjp/_new 2019-07-28 10:17:44.704600405 +0200 @@ -15,6 +15,7 @@ # Please submit bugfixes or comments via https://bugs.opensuse.org/ # + %if 0%{?suse_version} >= 1500 %bcond_without test %else @@ -23,12 +24,12 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %define oldpython python Name: python-pathlib2 -Version: 2.3.3 +Version: 2.3.4 Release: 0 Summary: Object-oriented filesystem paths License: MIT Group: Development/Languages/Python -URL: https://pypi.python.org/pypi/pathlib2/ +URL: https://github.com/mcmtroffaes/pathlib2 Source: https://files.pythonhosted.org/packages/source/p/pathlib2/pathlib2-%{version}.tar.gz BuildRequires: %{python_module setuptools} %if %{with test} ++++++ pathlib2-2.3.3.tar.gz -> pathlib2-2.3.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pathlib2-2.3.3/CHANGELOG.rst new/pathlib2-2.3.4/CHANGELOG.rst --- old/pathlib2-2.3.3/CHANGELOG.rst 2018-11-29 13:47:52.000000000 +0100 +++ new/pathlib2-2.3.4/CHANGELOG.rst 2019-06-25 11:05:20.000000000 +0200 @@ -1,6 +1,16 @@ History ------- +Version 2.3.4 +^^^^^^^^^^^^^ + +- Do not raise windows error when calling resolve on a non-existing + path in Python 2.7, to match behaviour on Python 3.x (see issue #54). + +- Use the new collections.abc when possible (see issue #53). + +- Sync with upstream pathlib (see issues #47 and #51). + Version 2.3.3 ^^^^^^^^^^^^^ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pathlib2-2.3.3/PKG-INFO new/pathlib2-2.3.4/PKG-INFO --- old/pathlib2-2.3.3/PKG-INFO 2018-11-29 13:48:26.000000000 +0100 +++ new/pathlib2-2.3.4/PKG-INFO 2019-06-25 11:06:22.000000000 +0200 @@ -1,12 +1,11 @@ Metadata-Version: 1.1 Name: pathlib2 -Version: 2.3.3 +Version: 2.3.4 Summary: Object-oriented filesystem paths -Home-page: https://pypi.python.org/pypi/pathlib2/ +Home-page: https://github.com/mcmtroffaes/pathlib2 Author: Matthias C. M. Troffaes Author-email: matthias.troff...@gmail.com License: MIT -Download-URL: https://pypi.python.org/pypi/pathlib2/ Description: The `old pathlib <https://bitbucket.org/pitrou/pathlib>`_ module on bitbucket is in bugfix-only mode. The goal of pathlib2 is to provide a backport of @@ -40,6 +39,20 @@ `standard pathlib <http://docs.python.org/dev/library/pathlib.html>`_ documentation. + Known Issues + ------------ + + For historic reasons, pathlib2 still uses bytes to represent file paths internally. + Unfortunately, on Windows with Python 2.7, the file system encoder (``mcbs``) + has only poor support for non-ascii characters, + and can silently replace non-ascii characters without warning. + For example, ``u'тест'.encode(sys.getfilesystemencoding())`` results in ``????`` + which is obviously completely useless. + + Therefore, on Windows with Python 2.7, until this problem is fixed upstream, + unfortunately you cannot rely on pathlib2 to support the full unicode range for filenames. + See `issue #56 <https://github.com/mcmtroffaes/pathlib2/issues/56>`_ for more details. + .. |travis| image:: https://travis-ci.org/mcmtroffaes/pathlib2.png?branch=develop :target: https://travis-ci.org/mcmtroffaes/pathlib2 :alt: travis-ci diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pathlib2-2.3.3/README.rst new/pathlib2-2.3.4/README.rst --- old/pathlib2-2.3.3/README.rst 2017-01-09 16:21:33.000000000 +0100 +++ new/pathlib2-2.3.4/README.rst 2019-06-17 12:46:21.000000000 +0200 @@ -38,6 +38,20 @@ `standard pathlib <http://docs.python.org/dev/library/pathlib.html>`_ documentation. +Known Issues +------------ + +For historic reasons, pathlib2 still uses bytes to represent file paths internally. +Unfortunately, on Windows with Python 2.7, the file system encoder (``mcbs``) +has only poor support for non-ascii characters, +and can silently replace non-ascii characters without warning. +For example, ``u'тест'.encode(sys.getfilesystemencoding())`` results in ``????`` +which is obviously completely useless. + +Therefore, on Windows with Python 2.7, until this problem is fixed upstream, +unfortunately you cannot rely on pathlib2 to support the full unicode range for filenames. +See `issue #56 <https://github.com/mcmtroffaes/pathlib2/issues/56>`_ for more details. + .. |travis| image:: https://travis-ci.org/mcmtroffaes/pathlib2.png?branch=develop :target: https://travis-ci.org/mcmtroffaes/pathlib2 :alt: travis-ci diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pathlib2-2.3.3/VERSION new/pathlib2-2.3.4/VERSION --- old/pathlib2-2.3.3/VERSION 2018-11-29 13:47:52.000000000 +0100 +++ new/pathlib2-2.3.4/VERSION 2019-06-25 11:03:12.000000000 +0200 @@ -1 +1 @@ -2.3.3 +2.3.4 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pathlib2-2.3.3/pathlib2/__init__.py new/pathlib2-2.3.4/pathlib2/__init__.py --- old/pathlib2-2.3.3/pathlib2/__init__.py 2018-04-19 12:15:38.000000000 +0200 +++ new/pathlib2-2.3.4/pathlib2/__init__.py 2019-06-17 12:46:14.000000000 +0200 @@ -12,12 +12,18 @@ import re import six import sys -from collections import Sequence -from errno import EINVAL, ENOENT, ENOTDIR, EEXIST, EPERM, EACCES -from operator import attrgetter +from errno import EINVAL, ENOENT, ENOTDIR, EBADF +from errno import EEXIST, EPERM, EACCES +from operator import attrgetter from stat import ( S_ISDIR, S_ISLNK, S_ISREG, S_ISSOCK, S_ISBLK, S_ISCHR, S_ISFIFO) + +try: + from collections.abc import Sequence +except ImportError: + from collections import Sequence + try: from urllib import quote as urlquote_from_bytes except ImportError: @@ -54,6 +60,18 @@ # Internals # +# EBADF - guard agains macOS `stat` throwing EBADF +_IGNORED_ERROS = (ENOENT, ENOTDIR, EBADF) + +_IGNORED_WINERRORS = ( + 21, # ERROR_NOT_READY - drive exists but is not accessible +) + + +def _ignore_error(exception): + return (getattr(exception, 'errno', None) in _IGNORED_ERROS or + getattr(exception, 'winerror', None) in _IGNORED_WINERRORS) + def _py2_fsencode(parts): # py2 => minimal unicode support @@ -90,9 +108,25 @@ try_func() except FileNotFoundError as exc: except_func(exc) + elif os.name != 'nt': + try: + try_func() + except EnvironmentError as exc: + if exc.errno != ENOENT: + raise + else: + except_func(exc) else: try: try_func() + except WindowsError as exc: + # errno contains winerror + # 2 = file not found + # 3 = path not found + if exc.errno not in (2, 3): + raise + else: + except_func(exc) except EnvironmentError as exc: if exc.errno != ENOENT: raise @@ -336,16 +370,26 @@ else: # End of the path after the first one not found tail_parts = [] + + def _try_func(): + result[0] = self._ext_to_normal(_getfinalpathname(s)) + # if there was no exception, set flag to 0 + result[1] = 0 + + def _exc_func(exc): + pass + while True: - try: - s = self._ext_to_normal(_getfinalpathname(s)) - except FileNotFoundError: + result = [None, 1] + _try_except_filenotfounderror(_try_func, _exc_func) + if result[1] == 1: # file not found exception raised previous_s = s s, tail = os.path.split(s) tail_parts.append(tail) if previous_s == s: return path else: + s = result[0] return os.path.join(s, *reversed(tail_parts)) # Means fallback on absolute return None @@ -715,7 +759,13 @@ def try_iter(): entries = list(scandir(parent_path)) for entry in entries: - if entry.is_dir() and not entry.is_symlink(): + entry_is_dir = False + try: + entry_is_dir = entry.is_dir() + except OSError as e: + if not _ignore_error(e): + raise + if entry_is_dir and not entry.is_symlink(): path = parent_path._make_child_relpath(entry.name) for p in self._iterate_directories(path, is_dir, scandir): yield p @@ -1026,8 +1076,9 @@ self._parts[:-1] + [name]) def with_suffix(self, suffix): - """Return a new path with the file suffix changed (or added, if - none). + """Return a new path with the file suffix changed. If the path + has no suffix, add given suffix. If the given suffix is an empty + string, remove the suffix from the path. """ # XXX if suffix is None, should the current suffix be removed? f = self._flavour @@ -1173,6 +1224,11 @@ class PureWindowsPath(PurePath): + """PurePath subclass for Windows systems. + + On a Windows system, instantiating a PurePath should return this object. + However, you can also instantiate it directly on any system. + """ _flavour = _windows_flavour __slots__ = () @@ -1181,6 +1237,14 @@ class Path(PurePath): + """PurePath subclass that can make system calls. + + Path represents a filesystem path but unlike PurePath, also offers + methods to do system calls on path objects. Depending on your system, + instantiating a Path will return either a PosixPath or a WindowsPath + object. You can also instantiate a PosixPath or WindowsPath directly, + but cannot instantiate a WindowsPath on a POSIX system or vice versa. + """ __slots__ = ( '_accessor', '_closed', @@ -1286,7 +1350,7 @@ def glob(self, pattern): """Iterate over this subtree and yield all existing files (of any - kind, including directories) matching the given pattern. + kind, including directories) matching the given relative pattern. """ if not pattern: raise ValueError("Unacceptable pattern: {0!r}".format(pattern)) @@ -1300,7 +1364,8 @@ def rglob(self, pattern): """Recursively yield all existing files (of any kind, including - directories) matching the given pattern, anywhere in this subtree. + directories) matching the given relative pattern, anywhere in + this subtree. """ pattern = self._flavour.casefold(pattern) drv, root, pattern_parts = self._flavour.parse_parts((pattern,)) @@ -1339,9 +1404,20 @@ s = self._flavour.resolve(self, strict=strict) if s is None: # No symlink resolution => for consistency, raise an error if - # the path doesn't exist or is forbidden - self.stat() + # the path is forbidden + # but not raise error if file does not exist (see issue #54). + + def _try_func(): + self.stat() + + def _exc_func(exc): + pass + + _try_except_filenotfounderror(_try_func, _exc_func) s = str(self.absolute()) + else: + # ensure s is a string (normpath requires this on older python) + s = str(s) # Now we have no symlinks in the path, it's safe to normalize it. normed = self._flavour.pathmod.normpath(s) obj = self._from_parts((normed,), init=False) @@ -1463,6 +1539,8 @@ try: _try_except_filenotfounderror(_try_func, _exc_func) except OSError: + # Cannot rely on checking for EEXIST, since the operating system + # could give priority to other errors like EACCES or EROFS if not exist_ok or not self.is_dir(): raise @@ -1548,9 +1626,12 @@ try: self.stat() except OSError as e: - if e.errno not in (ENOENT, ENOTDIR): + if not _ignore_error(e): raise return False + except ValueError: + # Non-encodable path + return False return True def is_dir(self): @@ -1560,11 +1641,14 @@ try: return S_ISDIR(self.stat().st_mode) except OSError as e: - if e.errno not in (ENOENT, ENOTDIR): + if not _ignore_error(e): raise # Path doesn't exist or is a broken symlink # (see https://bitbucket.org/pitrou/pathlib/issue/12/) return False + except ValueError: + # Non-encodable path + return False def is_file(self): """ @@ -1574,11 +1658,35 @@ try: return S_ISREG(self.stat().st_mode) except OSError as e: - if e.errno not in (ENOENT, ENOTDIR): + if not _ignore_error(e): raise # Path doesn't exist or is a broken symlink # (see https://bitbucket.org/pitrou/pathlib/issue/12/) return False + except ValueError: + # Non-encodable path + return False + + def is_mount(self): + """ + Check if this path is a POSIX mount point + """ + # Need to exist and be a dir + if not self.exists() or not self.is_dir(): + return False + + parent = Path(self.parent) + try: + parent_dev = parent.stat().st_dev + except OSError: + return False + + dev = self.stat().st_dev + if dev != parent_dev: + return True + ino = self.stat().st_ino + parent_ino = parent.stat().st_ino + return ino == parent_ino def is_symlink(self): """ @@ -1587,10 +1695,13 @@ try: return S_ISLNK(self.lstat().st_mode) except OSError as e: - if e.errno not in (ENOENT, ENOTDIR): + if not _ignore_error(e): raise # Path doesn't exist return False + except ValueError: + # Non-encodable path + return False def is_block_device(self): """ @@ -1599,11 +1710,14 @@ try: return S_ISBLK(self.stat().st_mode) except OSError as e: - if e.errno not in (ENOENT, ENOTDIR): + if not _ignore_error(e): raise # Path doesn't exist or is a broken symlink # (see https://bitbucket.org/pitrou/pathlib/issue/12/) return False + except ValueError: + # Non-encodable path + return False def is_char_device(self): """ @@ -1612,11 +1726,14 @@ try: return S_ISCHR(self.stat().st_mode) except OSError as e: - if e.errno not in (ENOENT, ENOTDIR): + if not _ignore_error(e): raise # Path doesn't exist or is a broken symlink # (see https://bitbucket.org/pitrou/pathlib/issue/12/) return False + except ValueError: + # Non-encodable path + return False def is_fifo(self): """ @@ -1625,11 +1742,14 @@ try: return S_ISFIFO(self.stat().st_mode) except OSError as e: - if e.errno not in (ENOENT, ENOTDIR): + if not _ignore_error(e): raise # Path doesn't exist or is a broken symlink # (see https://bitbucket.org/pitrou/pathlib/issue/12/) return False + except ValueError: + # Non-encodable path + return False def is_socket(self): """ @@ -1638,11 +1758,14 @@ try: return S_ISSOCK(self.stat().st_mode) except OSError as e: - if e.errno not in (ENOENT, ENOTDIR): + if not _ignore_error(e): raise # Path doesn't exist or is a broken symlink # (see https://bitbucket.org/pitrou/pathlib/issue/12/) return False + except ValueError: + # Non-encodable path + return False def expanduser(self): """ Return a new path with expanded ~ and ~user constructs @@ -1657,10 +1780,18 @@ class PosixPath(Path, PurePosixPath): + """Path subclass for non-Windows systems. + + On a POSIX system, instantiating a Path should return this object. + """ __slots__ = () class WindowsPath(Path, PureWindowsPath): + """Path subclass for Windows systems. + + On a Windows system, instantiating a Path should return this object. + """ __slots__ = () def owner(self): @@ -1668,3 +1799,7 @@ def group(self): raise NotImplementedError("Path.group() is unsupported on this system") + + def is_mount(self): + raise NotImplementedError( + "Path.is_mount() is unsupported on this system") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pathlib2-2.3.3/pathlib2.egg-info/PKG-INFO new/pathlib2-2.3.4/pathlib2.egg-info/PKG-INFO --- old/pathlib2-2.3.3/pathlib2.egg-info/PKG-INFO 2018-11-29 13:48:26.000000000 +0100 +++ new/pathlib2-2.3.4/pathlib2.egg-info/PKG-INFO 2019-06-25 11:06:22.000000000 +0200 @@ -1,12 +1,11 @@ Metadata-Version: 1.1 Name: pathlib2 -Version: 2.3.3 +Version: 2.3.4 Summary: Object-oriented filesystem paths -Home-page: https://pypi.python.org/pypi/pathlib2/ +Home-page: https://github.com/mcmtroffaes/pathlib2 Author: Matthias C. M. Troffaes Author-email: matthias.troff...@gmail.com License: MIT -Download-URL: https://pypi.python.org/pypi/pathlib2/ Description: The `old pathlib <https://bitbucket.org/pitrou/pathlib>`_ module on bitbucket is in bugfix-only mode. The goal of pathlib2 is to provide a backport of @@ -40,6 +39,20 @@ `standard pathlib <http://docs.python.org/dev/library/pathlib.html>`_ documentation. + Known Issues + ------------ + + For historic reasons, pathlib2 still uses bytes to represent file paths internally. + Unfortunately, on Windows with Python 2.7, the file system encoder (``mcbs``) + has only poor support for non-ascii characters, + and can silently replace non-ascii characters without warning. + For example, ``u'тест'.encode(sys.getfilesystemencoding())`` results in ``????`` + which is obviously completely useless. + + Therefore, on Windows with Python 2.7, until this problem is fixed upstream, + unfortunately you cannot rely on pathlib2 to support the full unicode range for filenames. + See `issue #56 <https://github.com/mcmtroffaes/pathlib2/issues/56>`_ for more details. + .. |travis| image:: https://travis-ci.org/mcmtroffaes/pathlib2.png?branch=develop :target: https://travis-ci.org/mcmtroffaes/pathlib2 :alt: travis-ci diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pathlib2-2.3.3/setup.py new/pathlib2-2.3.4/setup.py --- old/pathlib2-2.3.3/setup.py 2018-11-29 13:47:52.000000000 +0100 +++ new/pathlib2-2.3.4/setup.py 2019-03-11 10:25:14.000000000 +0100 @@ -40,8 +40,7 @@ 'Topic :: Software Development :: Libraries', 'Topic :: System :: Filesystems', ], - download_url='https://pypi.python.org/pypi/pathlib2/', - url='https://pypi.python.org/pypi/pathlib2/', + url='https://github.com/mcmtroffaes/pathlib2', install_requires=['six'], extras_require={ ':python_version<"3.5"': ['scandir'], diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pathlib2-2.3.3/tests/test_pathlib2.py new/pathlib2-2.3.4/tests/test_pathlib2.py --- old/pathlib2-2.3.3/tests/test_pathlib2.py 2018-04-19 12:15:38.000000000 +0200 +++ new/pathlib2-2.3.4/tests/test_pathlib2.py 2019-06-17 09:46:55.000000000 +0200 @@ -2393,6 +2393,11 @@ check() +# extra test to ensure coverage of issue #54 +def test_resolve_extra(): + pathlib.Path("~/does_not_exist").resolve() + + def main(): unittest.main(__name__)