diff options
Diffstat (limited to 'src/mailman/utilities/modules.py')
| -rw-r--r-- | src/mailman/utilities/modules.py | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/src/mailman/utilities/modules.py b/src/mailman/utilities/modules.py index 155a34ed2..eb8f7184a 100644 --- a/src/mailman/utilities/modules.py +++ b/src/mailman/utilities/modules.py @@ -71,19 +71,18 @@ def call_name(dotted_name, *args, **kws): def scan_module(module, interface): - """Return all the object in a module that conform to an interface. + """Return all the items in a module that conform to an interface. Scan every item named in the module's `__all__`. If that item conforms to the given interface, *and* the item is not declared as an - `@abstract_component`, then instantiate the item and return the resulting - instance. + `@abstract_component`, then return the item. :param module: A module object. :type module: module :param interface: The interface that returned objects must conform to. :type interface: `Interface` - :return: The sequence of instantiated matching components. - :rtype: instantiated objects implementing `interface` + :return: The sequence of matching components. + :rtype: items implementing `interface` """ missing = object() for name in module.__all__: @@ -99,7 +98,7 @@ def scan_module(module, interface): # where the marker has been placed. The value of # __abstract_component__ doesn't matter, only its presence. and '__abstract_component__' not in component.__dict__): - yield component() + yield component @public @@ -107,15 +106,15 @@ def find_components(package, interface): """Find components which conform to a given interface. Search all the modules in a given package, returning an iterator over all - objects found that conform to the given interface, unless that object is + items found that conform to the given interface, unless that object is decorated with `@abstract_component`. :param package: The package path to search. :type package: string :param interface: The interface that returned objects must conform to. :type interface: `Interface` - :return: The sequence of instantiated matching components. - :rtype: instantiated objects implementing `interface` + :return: The sequence of matching components. + :rtype: items implementing `interface` """ for filename in resource_listdir(package, ''): basename, extension = os.path.splitext(filename) @@ -135,9 +134,10 @@ def add_components(package, interface, mapping): Similarly to `find_components()` this inspects all modules in a given package looking for objects that conform to a given interface. All such - found objects (unless decorated with `@abstract_component`) are added to - the given mapping, keyed by the object's `.name` attribute, which is - required. It is a fatal error if that key already exists in the mapping. + found objects (unless decorated with `@abstract_component`) are + instantiated and added to the given mapping, keyed by the object's `.name` + attribute, which is required. It is a fatal error if that key already + exists in the mapping. :param package: The package path to search. :type package: string @@ -150,7 +150,8 @@ def add_components(package, interface, mapping): containment tests (e.g. `in` and `not in`) and `__setitem__()`. :raises RuntimeError: when a duplicate key is found. """ - for component in find_components(package, interface): + for component_class in find_components(package, interface): + component = component_class() if component.name in mapping: raise RuntimeError( 'Duplicate key "{}" found in {}; previously {}'.format( |
