Barry Warsaw pushed to branch master at mailman / Mailman Core
Commits:
c1060c9d by J08nY at 2017-08-30T13:11:24+02:00
Instantiate components only in add_components, not at lower levels.
- The scan_module and find_components functions are also useful
when they don't instantiate the components they load, and
instantiation is left to add_components.
- - - - -
a7c82290 by Barry Warsaw at 2017-08-30T13:48:04+00:00
Merge branch 'modules-no-instantiate' into 'master'
Instantiate components only in add_components, not at lower levels.
See merge request !300
- - - - -
2 changed files:
- src/mailman/utilities/modules.py
- src/mailman/utilities/tests/test_modules.py
Changes:
=====================================
src/mailman/utilities/modules.py
=====================================
--- a/src/mailman/utilities/modules.py
+++ b/src/mailman/utilities/modules.py
@@ -97,19 +97,18 @@ def hacked_sys_modules(name, module):
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__:
@@ -125,22 +124,22 @@ 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
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)
@@ -198,9 +197,9 @@ def add_components(subpackage, interface, mapping):
in the given subpackage, relative to the 'mailman' parent package,
and all the plugin names, that match the 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.
+ 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 subpackage: The subpackage path to search.
:type subpackage: str
@@ -213,7 +212,8 @@ def add_components(subpackage, interface, mapping):
containment tests (e.g. `in` and `not in`) and `__setitem__()`.
:raises RuntimeError: when a duplicate key is found.
"""
- for component in find_pluggable_components(subpackage, interface):
+ for component_class in find_pluggable_components(subpackage, interface):
+ component = component_class()
if component.name in mapping:
raise RuntimeError( # pragma: nocover
'Duplicate key "{}" found in {}; previously {}'.format(
=====================================
src/mailman/utilities/tests/test_modules.py
=====================================
--- a/src/mailman/utilities/tests/test_modules.py
+++ b/src/mailman/utilities/tests/test_modules.py
@@ -105,8 +105,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.
View it on GitLab:
https://gitlab.com/mailman/mailman/compare/057bc0704ab6d975e327c11cac204decfb478c4d...a7c82290f87554e07481eb048445e2587ad3bf9a
---
View it on GitLab:
https://gitlab.com/mailman/mailman/compare/057bc0704ab6d975e327c11cac204decfb478c4d...a7c82290f87554e07481eb048445e2587ad3bf9a
You're receiving this email because of your account on gitlab.com.
_______________________________________________
Mailman-checkins mailing list
[email protected]
Unsubscribe:
https://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org