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) |