summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mailman/utilities/modules.py27
-rw-r--r--src/mailman/utilities/tests/test_modules.py4
2 files changed, 16 insertions, 15 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(
diff --git a/src/mailman/utilities/tests/test_modules.py b/src/mailman/utilities/tests/test_modules.py
index 82d44cff4..08ec3848a 100644
--- a/src/mailman/utilities/tests/test_modules.py
+++ b/src/mailman/utilities/tests/test_modules.py
@@ -99,8 +99,8 @@ class BadStyle:
in find_components('mypackage', IStyle)]
self.assertEqual(names, ['good-style'])
- def test_find_components_no_instantiate(self):
- # find_components() now instantiates the class unless it's been
+ def test_find_components_abstract_component(self):
+ # find_components() finds the class unless it's been
# decorated with the @abstract_component decorator.
with ExitStack() as resources:
# Creating a temporary directory and adding it to sys.path.