This is an automated email from the ASF dual-hosted git repository.

csantanapr pushed a commit to branch master
in repository 
https://gitbox.apache.org/repos/asf/incubator-openwhisk-utilities.git


The following commit(s) were added to refs/heads/master by this push:
     new 42a8f98  If a cycle is detected, ignore it rather than raise an 
exception. (#61)
42a8f98 is described below

commit 42a8f9843fc655e677fb8e9fb1e53e1992fe1cb3
Author: rodric rabbah <[email protected]>
AuthorDate: Tue Apr 9 18:41:57 2019 -0400

    If a cycle is detected, ignore it rather than raise an exception. (#61)
---
 scancode/lib/util.py | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/scancode/lib/util.py b/scancode/lib/util.py
index c5bcd7b..ac6e0a9 100644
--- a/scancode/lib/util.py
+++ b/scancode/lib/util.py
@@ -32,7 +32,7 @@ _registered_patterns = {}
 registered pattern factory (``callable``).
 """
 
-def iter_tree(root, on_error=None, follow_links=None):
+def iter_tree(root, on_error=None, follow_links=None, ignore_cycles=True):
        """
        Walks the specified directory for all files.
 
@@ -48,7 +48,11 @@ def iter_tree(root, on_error=None, follow_links=None):
        to walk symbolik links that resolve to directories. Default is
        :data:`None` for :data:`True`.
 
-       Raises :exc:`RecursionError` if recursion is detected.
+       *ignore_cycles* (:class:`bool`) ignores any detected cycles during tree
+       discovery. Default is :data:`True`.
+
+       Raises :exc:`RecursionError` if recursion is detected and 
*ignore_cycles*
+       is :data:`False`.
 
        Returns an :class:`~collections.abc.Iterable` yielding the path to
        each file (:class:`str`) relative to *root*.
@@ -59,10 +63,10 @@ def iter_tree(root, on_error=None, follow_links=None):
        if follow_links is None:
                follow_links = True
 
-       for file_rel in _iter_tree_next(os.path.abspath(root), '', {}, 
on_error, follow_links):
+       for file_rel in _iter_tree_next(os.path.abspath(root), '', {}, 
on_error, follow_links, ignore_cycles):
                yield file_rel
 
-def _iter_tree_next(root_full, dir_rel, memo, on_error, follow_links):
+def _iter_tree_next(root_full, dir_rel, memo, on_error, follow_links, 
ignore_cycles):
        """
        Scan the directory for all descendant files.
 
@@ -80,6 +84,9 @@ def _iter_tree_next(root_full, dir_rel, memo, on_error, 
follow_links):
 
        *follow_links* (:class:`bool`) is whether to walk symbolik links that
        resolve to directories.
+
+       *ignore_cycles* (:class:`bool`) skips any detected cycles, otherwise
+       raises an exception.
        """
        dir_full = os.path.join(root_full, dir_rel)
        dir_real = os.path.realpath(dir_full)
@@ -89,6 +96,9 @@ def _iter_tree_next(root_full, dir_rel, memo, on_error, 
follow_links):
        # recursion has occurred.
        if dir_real not in memo:
                memo[dir_real] = dir_rel
+       elif ignore_cycles:
+               return
+               yield
        else:
                raise RecursionError(real_path=dir_real, 
first_path=memo[dir_real], second_path=dir_rel)
 
@@ -119,7 +129,7 @@ def _iter_tree_next(root_full, dir_rel, memo, on_error, 
follow_links):
                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, on_error, follow_links):
+                       for file_rel in _iter_tree_next(root_full, node_rel, 
memo, on_error, follow_links, ignore_cycles):
                                yield file_rel
 
                elif stat.S_ISREG(node_stat.st_mode):

Reply via email to