Hello community,
here is the log from the commit of package python-pathspec for openSUSE:Factory
checked in at 2019-02-27 17:28:07
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pathspec (Old)
and /work/SRC/openSUSE:Factory/.python-pathspec.new.28833 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pathspec"
Wed Feb 27 17:28:07 2019 rev:3 rq:674890 version:0.5.9
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pathspec/python-pathspec.changes
2018-12-24 11:40:57.821474922 +0100
+++
/work/SRC/openSUSE:Factory/.python-pathspec.new.28833/python-pathspec.changes
2019-02-27 17:28:09.147342220 +0100
@@ -1,0 +2,13 @@
+Thu Feb 14 07:08:42 UTC 2019 - John Vandenberg <[email protected]>
+
+- Update to v0.5.9
+ * Fixed file system error handling.
+- from v0.5.8
+ * Improved type checking.
+ * Created scripts to test Python 2.6 because Tox removed support for it.
+ * Improved byte string handling in Python 3.
+ * Handle dangling symlinks.
+- from v0.5.7
+ * Fix collections deprecation warning.
+
+-------------------------------------------------------------------
Old:
----
pathspec-0.5.6.tar.gz
New:
----
pathspec-0.5.9.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-pathspec.spec ++++++
--- /var/tmp/diff_new_pack.3imZU2/_old 2019-02-27 17:28:09.615342053 +0100
+++ /var/tmp/diff_new_pack.3imZU2/_new 2019-02-27 17:28:09.615342053 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-pathspec
#
-# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
%bcond_without test
Name: python-pathspec
-Version: 0.5.6
+Version: 0.5.9
Release: 0
Summary: Utility library for gitignore style pattern matching of file
paths
License: MPL-2.0
++++++ pathspec-0.5.6.tar.gz -> pathspec-0.5.9.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pathspec-0.5.6/CHANGES.rst
new/pathspec-0.5.9/CHANGES.rst
--- old/pathspec-0.5.6/CHANGES.rst 2018-04-06 15:20:27.000000000 +0200
+++ new/pathspec-0.5.9/CHANGES.rst 2018-09-15 19:51:01.000000000 +0200
@@ -3,6 +3,31 @@
==============
+0.5.9 (2018-09-15)
+------------------
+
+- Fixed file system error handling.
+
+
+0.5.8 (2018-09-15)
+------------------
+
+- Improved type checking.
+- Created scripts to test Python 2.6 because Tox removed support for it.
+- Improved byte string handling in Python 3.
+- `Issue #22`_: Handle dangling symlinks.
+
+.. _`Issue #22`: https://github.com/cpburnz/python-path-specification/issues/22
+
+
+0.5.7 (2018-08-14)
+------------------
+
+- `Issue #21`_: Fix collections deprecation warning.
+
+.. _`Issue #21`: https://github.com/cpburnz/python-path-specification/issues/21
+
+
0.5.6 (2018-04-06)
------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pathspec-0.5.6/PKG-INFO new/pathspec-0.5.9/PKG-INFO
--- old/pathspec-0.5.6/PKG-INFO 2018-04-06 15:24:14.000000000 +0200
+++ new/pathspec-0.5.9/PKG-INFO 2018-09-15 19:51:49.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: pathspec
-Version: 0.5.6
+Version: 0.5.9
Summary: Utility library for gitignore style pattern matching of file paths.
Home-page: https://github.com/cpburnz/python-path-specification
Author: Caleb P. Burns
@@ -163,6 +163,31 @@
==============
+ 0.5.9 (2018-09-15)
+ ------------------
+
+ - Fixed file system error handling.
+
+
+ 0.5.8 (2018-09-15)
+ ------------------
+
+ - Improved type checking.
+ - Created scripts to test Python 2.6 because Tox removed support for
it.
+ - Improved byte string handling in Python 3.
+ - `Issue #22`_: Handle dangling symlinks.
+
+ .. _`Issue #22`:
https://github.com/cpburnz/python-path-specification/issues/22
+
+
+ 0.5.7 (2018-08-14)
+ ------------------
+
+ - `Issue #21`_: Fix collections deprecation warning.
+
+ .. _`Issue #21`:
https://github.com/cpburnz/python-path-specification/issues/21
+
+
0.5.6 (2018-04-06)
------------------
@@ -315,6 +340,7 @@
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Software Development :: Libraries :: Python Modules
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pathspec-0.5.6/pathspec/__init__.py
new/pathspec-0.5.9/pathspec/__init__.py
--- old/pathspec-0.5.6/pathspec/__init__.py 2018-04-06 15:20:32.000000000
+0200
+++ new/pathspec-0.5.9/pathspec/__init__.py 2018-09-15 19:45:07.000000000
+0200
@@ -39,13 +39,15 @@
"adrienverge <https://github.com/adrienverge>",
"AndersBlomdell <https://github.com/AndersBlomdell>",
"highb <https://github.com/highb>",
+ "thmxv <https://github.com/thmxv>",
+ "wimglenn <https://github.com/wimglenn>",
]
__email__ = "[email protected]"
__license__ = "MPL 2.0"
__project__ = "pathspec"
__status__ = "Development"
-__updated__ = "2018-04-06"
-__version__ = "0.5.6"
+__updated__ = "2018-09-15"
+__version__ = "0.5.9"
from .pathspec import PathSpec
from .pattern import Pattern, RegexPattern
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pathspec-0.5.6/pathspec/compat.py
new/pathspec-0.5.9/pathspec/compat.py
--- old/pathspec-0.5.6/pathspec/compat.py 2017-07-01 21:45:51.000000000
+0200
+++ new/pathspec-0.5.9/pathspec/compat.py 2018-08-17 02:22:35.000000000
+0200
@@ -27,3 +27,10 @@
def iterkeys(mapping):
return mapping.keys()
+
+try:
+ # Python 3.6+.
+ from collections.abc import Collection as collection_type
+except ImportError:
+ # Python 2.6 - 3.5.
+ from collections import Container as collection_type
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pathspec-0.5.6/pathspec/pathspec.py
new/pathspec-0.5.9/pathspec/pathspec.py
--- old/pathspec-0.5.6/pathspec/pathspec.py 2017-10-06 04:10:20.000000000
+0200
+++ new/pathspec-0.5.9/pathspec/pathspec.py 2018-09-15 18:14:23.000000000
+0200
@@ -4,10 +4,8 @@
of files.
"""
-import collections
-
from . import util
-from .compat import iterkeys, izip_longest, string_types, unicode
+from .compat import collection_type, iterkeys, izip_longest, string_types,
unicode
class PathSpec(object):
@@ -20,13 +18,13 @@
"""
Initializes the :class:`PathSpec` instance.
- *patterns* (:class:`~collections.Container` or
:class:`~collections.Iterable`)
+ *patterns* (:class:`~collections.abc.Collection` or
:class:`~collections.abc.Iterable`)
yields each compiled pattern (:class:`.Pattern`).
"""
- self.patterns = patterns if isinstance(patterns,
collections.Container) else list(patterns)
+ self.patterns = patterns if isinstance(patterns,
collection_type) else list(patterns)
"""
- *patterns* (:class:`~collections.Container` of
:class:`.Pattern`)
+ *patterns* (:class:`~collections.abc.Collection` of
:class:`.Pattern`)
contains the compiled patterns.
"""
@@ -54,11 +52,11 @@
Compiles the pattern lines.
*pattern_factory* can be either the name of a registered pattern
- factory (:class:`str`), or a :class:`~collections.Callable`
used to
- compile patterns. It must accept an uncompiled pattern
(:class:`str`)
+ factory (:class:`str`), or a :class:`~collections.abc.Callable`
used
+ to compile patterns. It must accept an uncompiled pattern
(:class:`str`)
and return the compiled pattern (:class:`.Pattern`).
- *lines* (:class:`~collections.Iterable`) yields each uncompiled
+ *lines* (:class:`~collections.abc.Iterable`) yields each
uncompiled
pattern (:class:`str`). This simply has to yield each line so
it can
be a :class:`file` (e.g., from :func:`open` or
:class:`io.StringIO`)
or the result from :meth:`str.splitlines`.
@@ -83,7 +81,7 @@
*file* (:class:`str`) is the file path to be matched against
:attr:`self.patterns <PathSpec.patterns>`.
- *separators* (:class:`~collections.Container` of :class:`str`)
+ *separators* (:class:`~collections.abc.Collection` of
:class:`str`)
optionally contains the path separators to normalize. See
:func:`~pathspec.util.normalize_file` for more information.
@@ -96,15 +94,16 @@
"""
Matches the files to this path-spec.
- *files* (:class:`~collections.Iterable` of :class:`str`)
contains
+ *files* (:class:`~collections.abc.Iterable` of :class:`str`)
contains
the file paths to be matched against :attr:`self.patterns
<PathSpec.patterns>`.
- *separators* (:class:`~collections.Container` of :class:`str`)
- optionally contains the path separators to normalize. See
- :func:`~pathspec.util.normalize_file` for more information.
+ *separators* (:class:`~collections.abc.Collection` of
:class:`str`;
+ or :data:`None`) optionally contains the path separators to
+ normalize. See :func:`~pathspec.util.normalize_file` for more
+ information.
- Returns the matched files (:class:`~collections.Iterable` of
+ Returns the matched files (:class:`~collections.abc.Iterable` of
:class:`str`).
"""
if isinstance(files, (bytes, unicode)):
@@ -115,15 +114,24 @@
for path in matched_files:
yield file_map[path]
- def match_tree(self, root):
+ def match_tree(self, root, on_error=None, follow_links=None):
"""
Walks the specified root path for all files and matches them to
this
path-spec.
*root* (:class:`str`) is the root directory to search for files.
- Returns the matched files (:class:`~collections.Iterable` of
+ *on_error* (:class:`~collections.abc.Callable` or :data:`None`)
+ optionally is the error handler for file-system exceptions. See
+ :func:`~pathspec.util.iter_tree` for more information.
+
+
+ *follow_links* (:class:`bool` or :data:`None`) optionally is
whether
+ to walk symbolik links that resolve to directories. See
+ :func:`~pathspec.util.iter_tree` for more information.
+
+ Returns the matched files (:class:`~collections.abc.Iterable` of
:class:`str`).
"""
- files = util.iter_tree(root)
+ files = util.iter_tree(root, on_error=on_error,
follow_links=follow_links)
return self.match_files(files)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pathspec-0.5.6/pathspec/pattern.py
new/pathspec-0.5.9/pathspec/pattern.py
--- old/pathspec-0.5.6/pathspec/pattern.py 2017-09-09 05:52:26.000000000
+0200
+++ new/pathspec-0.5.9/pathspec/pattern.py 2018-08-15 17:43:12.000000000
+0200
@@ -36,11 +36,11 @@
"""
Matches this pattern against the specified files.
- *files* (:class:`~collections.Iterable` of :class:`str`)
contains
+ *files* (:class:`~collections.abc.Iterable` of :class:`str`)
contains
each file relative to the root directory (e.g.,
``"relative/path/to/file"``).
- Returns an :class:`~collections.Iterable` yielding each matched
file
- path (:class:`str`).
+ Returns an :class:`~collections.abc.Iterable` yielding each
matched
+ file path (:class:`str`).
"""
raise NotImplementedError("{0}.{1} must override
match().".format(self.__class__.__module__, self.__class__.__name__))
@@ -117,11 +117,11 @@
"""
Matches this pattern against the specified files.
- *files* (:class:`~collections.Iterable` of :class:`str`)
contains
- each file relative to the root directory (e.g.,
"relative/path/to/file").
+ *files* (:class:`~collections.abc.Iterable` of :class:`str`)
+ contains each file relative to the root directory (e.g.,
"relative/path/to/file").
- Returns an :class:`~collections.Iterable` yielding each matched
file
- path (:class:`str`).
+ Returns an :class:`~collections.abc.Iterable` yielding each
matched
+ file path (:class:`str`).
"""
if self.include is not None:
for path in files:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pathspec-0.5.6/pathspec/patterns/gitwildmatch.py
new/pathspec-0.5.9/pathspec/patterns/gitwildmatch.py
--- old/pathspec-0.5.6/pathspec/patterns/gitwildmatch.py 2017-09-09
05:50:56.000000000 +0200
+++ new/pathspec-0.5.9/pathspec/patterns/gitwildmatch.py 2018-08-18
19:03:26.000000000 +0200
@@ -14,7 +14,7 @@
from ..pattern import RegexPattern
#: The encoding to use when parsing a byte string pattern.
-_BYTES_ENCODING = 'CP1252'
+_BYTES_ENCODING = 'latin1'
class GitWildMatchPattern(RegexPattern):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pathspec-0.5.6/pathspec/tests/test_gitwildmatch.py
new/pathspec-0.5.9/pathspec/tests/test_gitwildmatch.py
--- old/pathspec-0.5.6/pathspec/tests/test_gitwildmatch.py 2017-10-06
03:54:18.000000000 +0200
+++ new/pathspec-0.5.9/pathspec/tests/test_gitwildmatch.py 2018-08-18
20:37:46.000000000 +0200
@@ -8,13 +8,18 @@
import sys
try:
+ # Python 2.6.
import unittest2 as unittest
except ImportError:
import unittest
+import pathspec.patterns.gitwildmatch
import pathspec.util
from pathspec.patterns.gitwildmatch import GitWildMatchPattern
+if sys.version_info[0] >= 3:
+ unichr = chr
+
class GitWildMatchTest(unittest.TestCase):
"""
@@ -384,6 +389,22 @@
"""
self.assertIs(pathspec.util.lookup_pattern('gitignore'),
pathspec.GitIgnorePattern)
+ def test_07_encode_bytes(self):
+ """
+ Test encoding bytes.
+ """
+ encoded = "".join(map(unichr,
range(0,256))).encode(pathspec.patterns.gitwildmatch._BYTES_ENCODING)
+ expected =
b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f
!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+ self.assertEqual(encoded, expected)
+
+ def test_07_decode_bytes(self):
+ """
+ Test decoding bytes.
+ """
+ decoded =
bytes(bytearray(range(0,256))).decode(pathspec.patterns.gitwildmatch._BYTES_ENCODING)
+ expected =
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f
!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+ self.assertEqual(decoded, expected)
+
def test_07_match_bytes_and_bytes(self):
"""
Test byte string patterns matching byte string paths.
@@ -392,6 +413,16 @@
results = set(pattern.match([b'a.py']))
self.assertEqual(results, set([b'a.py']))
+ def test_07_match_bytes_and_bytes_complete(self):
+ """
+ Test byte string patterns matching byte string paths.
+ """
+ encoded = bytes(bytearray(range(0,256)))
+ escaped = b"".join(b"\\" + encoded[i:i+1] for i in
range(len(encoded)))
+ pattern = GitWildMatchPattern(escaped)
+ results = set(pattern.match([encoded]))
+ self.assertEqual(results, set([encoded]))
+
@unittest.skipIf(sys.version_info[0] >= 3, "Python 3 is strict")
def test_07_match_bytes_and_unicode(self):
"""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pathspec-0.5.6/pathspec/tests/test_util.py
new/pathspec-0.5.9/pathspec/tests/test_util.py
--- old/pathspec-0.5.6/pathspec/tests/test_util.py 2017-09-08
03:26:10.000000000 +0200
+++ new/pathspec-0.5.9/pathspec/tests/test_util.py 2018-09-15
18:22:40.000000000 +0200
@@ -3,6 +3,7 @@
This script tests utility functions.
"""
+import errno
import os
import os.path
import shutil
@@ -178,6 +179,7 @@
('bx', 'b'),
('Dir/cx', 'Dir/c'),
('Dir/dx', 'Dir/d'),
+ ('DirX', 'Dir'),
])
results = set(iter_tree(self.temp_dir))
self.assertEqual(results, set(map(self.ospath, [
@@ -189,6 +191,10 @@
'Dir/cx',
'Dir/d',
'Dir/dx',
+ 'DirX/c',
+ 'DirX/cx',
+ 'DirX/d',
+ 'DirX/dx',
])))
def test_2_3_sideways_links(self):
@@ -276,3 +282,62 @@
'B': self.ospath('B/Cx/Ax/Bx'),
'C': self.ospath('C/Ax/Bx/Cx'),
}[context.exception.first_path])
+
+ def test_2_6_detect_broken_links(self):
+ """
+ Tests that broken links are detected
+ """
+ def reraise(e):
+ raise e
+
+ self.require_symlink()
+ self.make_links([
+ ('A', 'DOES_NOT_EXIST')
+ ])
+ with self.assertRaises(OSError) as context:
+ set(iter_tree(self.temp_dir, on_error=reraise))
+ self.assertEqual(context.exception.errno, errno.ENOENT)
+
+ def test_2_7_ignore_broken_links(self):
+ """
+ Tests that broken links are ignored.
+ """
+ self.require_symlink()
+ self.make_links([
+ ('A', 'DOES_NOT_EXIST')
+ ])
+ results = set(iter_tree(self.temp_dir))
+ self.assertEqual(results, set())
+
+ def test_2_8_no_follow_links(self):
+ """
+ Tests to make sure directory links can be ignored.
+ """
+ self.require_symlink()
+ self.make_dirs([
+ 'Dir',
+ ])
+ self.make_files([
+ 'A',
+ 'B',
+ 'Dir/C',
+ 'Dir/D',
+ ])
+ self.make_links([
+ ('Ax', 'A'),
+ ('Bx', 'B'),
+ ('Dir/Cx', 'Dir/C'),
+ ('Dir/Dx', 'Dir/D'),
+ ('DirX', 'Dir'),
+ ])
+ results = set(iter_tree(self.temp_dir, follow_links=False))
+ self.assertEqual(results, set(map(self.ospath, [
+ 'A',
+ 'Ax',
+ 'B',
+ 'Bx',
+ 'Dir/C',
+ 'Dir/Cx',
+ 'Dir/D',
+ 'Dir/Dx',
+ ])))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pathspec-0.5.6/pathspec/util.py
new/pathspec-0.5.9/pathspec/util.py
--- old/pathspec-0.5.6/pathspec/util.py 2018-03-31 03:40:39.000000000 +0200
+++ new/pathspec-0.5.9/pathspec/util.py 2018-09-15 19:44:58.000000000 +0200
@@ -3,13 +3,12 @@
This module provides utility methods for dealing with path-specs.
"""
-import collections
import os
import os.path
import posixpath
import stat
-from .compat import string_types
+from .compat import collection_type, string_types
NORMALIZE_PATH_SEPS = [sep for sep in [os.sep, os.altsep] if sep and sep !=
posixpath.sep]
"""
@@ -25,21 +24,37 @@
registered pattern factory (``callable``).
"""
-def iter_tree(root):
+def iter_tree(root, on_error=None, follow_links=None):
"""
Walks the specified directory for all files.
*root* (:class:`str`) is the root directory to search for files.
+ *on_error* (:class:`~collections.abc.Callable` or :data:`None`)
+ optionally is the error handler for file-system exceptions. It will be
+ called with the exception (:exc:`OSError`). Reraise the exception to
+ abort the walk. Default is :data:`None` to ignore file-system
+ exceptions.
+
+ *follow_links* (:class:`bool` or :data:`None`) optionally is whether
+ to walk symbolik links that resolve to directories. Default is
+ :data:`None` for :data:`True`.
+
Raises :exc:`RecursionError` if recursion is detected.
- Returns an :class:`~collections.Iterable` yielding the path to each
- file (:class:`str`) relative to *root*.
+ Returns an :class:`~collections.abc.Iterable` yielding the path to
+ each file (:class:`str`) relative to *root*.
"""
- for file_rel in _iter_tree_next(os.path.abspath(root), '', {}):
+ if on_error is not None and not callable(on_error):
+ raise TypeError("on_error:{0!r} is not
callable.".format(on_error))
+
+ if follow_links is None:
+ follow_links = True
+
+ for file_rel in _iter_tree_next(os.path.abspath(root), '', {},
on_error, follow_links):
yield file_rel
-def _iter_tree_next(root_full, dir_rel, memo):
+def _iter_tree_next(root_full, dir_rel, memo, on_error, follow_links):
"""
Scan the directory for all descendant files.
@@ -51,6 +66,12 @@
*memo* (:class:`dict`) keeps track of ancestor directories
encountered. Maps each ancestor real path (:class:`str``) to relative
path (:class:`str`).
+
+ *on_error* (:class:`~collections.abc.Callable` or :data:`None`)
+ optionally is the error handler for file-system exceptions.
+
+ *follow_links* (:class:`bool`) is whether to walk symbolik links that
+ resolve to directories.
"""
dir_full = os.path.join(root_full, dir_rel)
dir_real = os.path.realpath(dir_full)
@@ -66,12 +87,31 @@
for node in os.listdir(dir_full):
node_rel = os.path.join(dir_rel, node)
node_full = os.path.join(root_full, node_rel)
- node_stat = os.stat(node_full)
- if stat.S_ISDIR(node_stat.st_mode):
+ # Inspect child node.
+ try:
+ node_stat = os.lstat(node_full)
+ except OSError as e:
+ if on_error is not None:
+ on_error(e)
+ continue
+
+ if stat.S_ISLNK(node_stat.st_mode):
+ # Child node is a link, inspect the target node.
+ is_link = True
+ try:
+ node_stat = os.stat(node_full)
+ except OSError as e:
+ if on_error is not None:
+ on_error(e)
+ continue
+ else:
+ is_link = False
+
+ if stat.S_ISDIR(node_stat.st_mode) and (follow_links or not
is_link):
# Child node is a directory, recurse into it and yield
its
# decendant files.
- for file_rel in _iter_tree_next(root_full, node_rel,
memo):
+ for file_rel in _iter_tree_next(root_full, node_rel,
memo, on_error, follow_links):
yield file_rel
elif stat.S_ISREG(node_stat.st_mode):
@@ -91,7 +131,7 @@
*name* (:class:`str`) is the name of the pattern factory.
- Returns the registered pattern factory (:class:`~collections.Callable`).
+ Returns the registered pattern factory
(:class:`~collections.abc.Callable`).
If no pattern factory is registered, raises :exc:`KeyError`.
"""
return _registered_patterns[name]
@@ -100,7 +140,7 @@
"""
Matches the file to the patterns.
- *patterns* (:class:`~collections.Iterable` of
:class:`~pathspec.pattern.Pattern`)
+ *patterns* (:class:`~collections.abc.Iterable` of
:class:`~pathspec.pattern.Pattern`)
contains the patterns to use.
*file* (:class:`str`) is the normalized file path to be matched
@@ -119,15 +159,15 @@
"""
Matches the files to the patterns.
- *patterns* (:class:`~collections.Iterable` of
:class:`~pathspec.pattern.Pattern`)
+ *patterns* (:class:`~collections.abc.Iterable` of
:class:`~pathspec.pattern.Pattern`)
contains the patterns to use.
- *files* (:class:`~collections.Iterable` of :class:`str`) contains the
- normalized file paths to be matched against *patterns*.
+ *files* (:class:`~collections.abc.Iterable` of :class:`str`) contains
+ the normalized file paths to be matched against *patterns*.
Returns the matched files (:class:`set` of :class:`str`).
"""
- all_files = files if isinstance(files, collections.Container) else
list(files)
+ all_files = files if isinstance(files, collection_type) else list(files)
return_files = set()
for pattern in patterns:
if pattern.include is not None:
@@ -144,12 +184,12 @@
*file* (:class:`str`) is the file path.
- *separators* (:class:`~collections.Container` of :class:`str`)
- optionally contains the path separators to normalize. This does not
- need to include the POSIX path separator (``'/'``), but including it
- will not affect the results. Default is :data:`None` for
:data:`NORMALIZE_PATH_SEPS`.
- To prevent normalization, pass an empty container (e.g., an empty
- tuple ``()``).
+ *separators* (:class:`~collections.abc.Collection` of :class:`str`; or
+ :data:`None`) optionally contains the path separators to normalize.
+ This does not need to include the POSIX path separator (``'/'``), but
+ including it will not affect the results. Default is :data:`None` for
+ :data:`NORMALIZE_PATH_SEPS`. To prevent normalization, pass an empty
+ container (e.g., an empty tuple ``()``).
Returns the normalized file path (:class:`str`).
"""
@@ -170,12 +210,12 @@
"""
Normalizes the file paths to use the POSIX path separator.
- *files* (:class:`~collections.Iterable` of :class:`str`) contains the
- file paths to be normalized.
+ *files* (:class:`~collections.abc.Iterable` of :class:`str`) contains
+ the file paths to be normalized.
- *separators* (:class:`~collections.Container` of :class:`str`)
- optionally contains the path separators to normalize. See
:func:`normalize_file`
- for more information.
+ *separators* (:class:`~collections.abc.Collection` of :class:`str`; or
+ :data:`None`) optionally contains the path separators to normalize.
+ See :func:`normalize_file` for more information.
Returns a :class:`dict` mapping the each normalized file path
(:class:`str`)
to the original file path (:class:`str`)
@@ -192,14 +232,14 @@
*name* (:class:`str`) is the name to register the pattern factory
under.
- *pattern_factory* (:class:`~collections.Callable`) is used to compile
- patterns. It must accept an uncompiled pattern (:class:`str`) and
- return the compiled pattern (:class:`.Pattern`).
-
- *override* (:class:`bool`) optionally is whether to allow overriding
- an already registered pattern under the same name (:data:`True`),
- instead of raising an :exc:`AlreadyRegisteredError` (:data:`False`).
- Default is :data:`None` for :data:`False`.
+ *pattern_factory* (:class:`~collections.abc.Callable`) is used to
+ compile patterns. It must accept an uncompiled pattern (:class:`str`)
+ and return the compiled pattern (:class:`.Pattern`).
+
+ *override* (:class:`bool` or :data:`None`) optionally is whether to
+ allow overriding an already registered pattern under the same name
+ (:data:`True`), instead of raising an :exc:`AlreadyRegisteredError`
+ (:data:`False`). Default is :data:`None` for :data:`False`.
"""
if not isinstance(name, string_types):
raise TypeError("name:{0!r} is not a string.".format(name))
@@ -222,8 +262,8 @@
*name* (:class:`str`) is the name of the registered pattern.
- *pattern_factory* (:class:`~collections.Callable`) is the
registered
- pattern factory.
+ *pattern_factory* (:class:`~collections.abc.Callable`) is the
+ registered pattern factory.
"""
super(AlreadyRegisteredError, self).__init__(name,
pattern_factory)
@@ -247,8 +287,8 @@
@property
def pattern_factory(self):
"""
- *pattern_factory* (:class:`~collections.Callable`) is the
registered
- pattern factory.
+ *pattern_factory* (:class:`~collections.abc.Callable`) is the
+ registered pattern factory.
"""
return self.args[1]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pathspec-0.5.6/pathspec.egg-info/PKG-INFO
new/pathspec-0.5.9/pathspec.egg-info/PKG-INFO
--- old/pathspec-0.5.6/pathspec.egg-info/PKG-INFO 2018-04-06
15:24:14.000000000 +0200
+++ new/pathspec-0.5.9/pathspec.egg-info/PKG-INFO 2018-09-15
19:51:49.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: pathspec
-Version: 0.5.6
+Version: 0.5.9
Summary: Utility library for gitignore style pattern matching of file paths.
Home-page: https://github.com/cpburnz/python-path-specification
Author: Caleb P. Burns
@@ -163,6 +163,31 @@
==============
+ 0.5.9 (2018-09-15)
+ ------------------
+
+ - Fixed file system error handling.
+
+
+ 0.5.8 (2018-09-15)
+ ------------------
+
+ - Improved type checking.
+ - Created scripts to test Python 2.6 because Tox removed support for
it.
+ - Improved byte string handling in Python 3.
+ - `Issue #22`_: Handle dangling symlinks.
+
+ .. _`Issue #22`:
https://github.com/cpburnz/python-path-specification/issues/22
+
+
+ 0.5.7 (2018-08-14)
+ ------------------
+
+ - `Issue #21`_: Fix collections deprecation warning.
+
+ .. _`Issue #21`:
https://github.com/cpburnz/python-path-specification/issues/21
+
+
0.5.6 (2018-04-06)
------------------
@@ -315,6 +340,7 @@
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Software Development :: Libraries :: Python Modules
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pathspec-0.5.6/setup.py new/pathspec-0.5.9/setup.py
--- old/pathspec-0.5.6/setup.py 2017-07-01 18:50:26.000000000 +0200
+++ new/pathspec-0.5.9/setup.py 2018-08-14 15:25:55.000000000 +0200
@@ -34,6 +34,7 @@
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
+ "Programming Language :: Python :: 3.7",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Topic :: Software Development :: Libraries :: Python Modules",