src/pyams_utils/container.py
changeset 444 72ceed22e639
parent 408 cf2304af0fab
equal deleted inserted replaced
443:582c60757939 444:72ceed22e639
   103         # then yield container items
   103         # then yield container items
   104         if IContainer.providedBy(context):
   104         if IContainer.providedBy(context):
   105             yield from context.values()
   105             yield from context.values()
   106 
   106 
   107 
   107 
   108 def find_objects_matching(root, condition, ignore_root=False):
   108 def find_objects_matching(root, condition, ignore_root=False, with_depth=False, initial_depth=0):
   109     """Find all objects in root that match the condition
   109     """Find all objects in root that match the condition
   110 
   110 
   111     The condition is a Python callable object that takes an object as
   111     The condition is a Python callable object that takes an object as
   112     argument and must return a boolean result.
   112     argument and must return a boolean result.
   113 
   113 
   116     :param object root: the parent object from which search is started
   116     :param object root: the parent object from which search is started
   117     :param callable condition: a callable object which may return true for a given
   117     :param callable condition: a callable object which may return true for a given
   118         object to be selected
   118         object to be selected
   119     :param boolean ignore_root: if *True*, the root object will not be returned, even if it matches
   119     :param boolean ignore_root: if *True*, the root object will not be returned, even if it matches
   120         the given condition
   120         the given condition
       
   121     :param boolean with_depth: if *True*, results are tuples which include items depth
       
   122     :param int initial_depth: initial depth, when depth is required
   121     :return: an iterator for all root's sub-objects matching condition
   123     :return: an iterator for all root's sub-objects matching condition
   122     """
   124     """
   123     if (not ignore_root) and condition(root):
   125     if (not ignore_root) and condition(root):
   124         yield root
   126         yield (root, initial_depth) if with_depth else root
   125     locations = ISublocations(root, None)
   127     locations = ISublocations(root, None)
   126     if locations is not None:
   128     if locations is not None:
   127         for location in locations.sublocations():  # pylint: disable=too-many-function-args
   129         for location in locations.sublocations():  # pylint: disable=too-many-function-args
   128             if condition(location):
   130             if condition(location):
   129                 yield location
   131                 yield (location, initial_depth+1) if with_depth else location
   130             yield from find_objects_matching(location, condition, ignore_root=True)
   132             yield from find_objects_matching(location, condition,
       
   133                                              ignore_root=True,
       
   134                                              with_depth=with_depth,
       
   135                                              initial_depth=initial_depth+1)
   131 
   136 
   132 
   137 
   133 def find_objects_providing(root, interface):
   138 def find_objects_providing(root, interface, with_depth=False):
   134     """Find all objects in root that provide the specified interface
   139     """Find all objects in root that provide the specified interface
   135 
   140 
   136     All sub-objects of the root will also be searched recursively.
   141     All sub-objects of the root will also be searched recursively.
   137 
   142 
   138     :param object root: object; the parent object from which search is started
   143     :param object root: object; the parent object from which search is started
   139     :param Interface interface: interface; an interface that sub-objects should provide
   144     :param Interface interface: interface; an interface that sub-objects should provide
       
   145     :param boolean with_depth: if *True*, results include
   140     :return: an iterator for all root's sub-objects that provide the given interface
   146     :return: an iterator for all root's sub-objects that provide the given interface
   141     """
   147     """
   142     yield from find_objects_matching(root, interface.providedBy)
   148     yield from find_objects_matching(root, interface.providedBy, with_depth=with_depth)