Provide a better way to avoid instantiating some components
While reviewing !287 (merged) I was reminded of the FIXME from 2010 in
src/mailman/core/chains.py
. There we had to explicitly name the component
classes we didn't want to instantiate because they are "abstract", i.e. used
for purposes other than actual components. In that case, they were base
classes.
That smells like a tech debt. Since !287 (merged) has to do something similar with
pipelines, I thought about it a bit and came up with the following approach.
We can decorate such abstract components, and then modify scan_module()
to
avoid yielding those classes. Further, scan_module()
itself needn't be
public, and it can actually do the instantiation.
There's one tricky bit to the implementation, as described in the comment. We
can't use getattr()
and friends to check for the existence of the marker
attribute (the value doesn't matter) because those always follow the mro, so
it propagates to subclasses. Thus we have to check the __dict__
of the
component class directly, so subclasses can still be instantiated.
There's a potential further refinement I'm thinking about. The common use pattern (almost?) always puts the instantiated object into a global config collection, after first checking for uniqueness based on the name. It seems natural that we could refactor this part too. I'll think about that before merging this branch.
This should make !287 (merged) a small bit better.