22 __all__ = (
"Registry",
"makeRegistry",
"RegistryField",
"registerConfig",
"registerConfigurable")
24 import collections.abc
27 from .config
import Config, FieldValidationError, _typeStr
28 from .configChoiceField
import ConfigInstanceDict, ConfigChoiceField
32 """A wrapper for configurables. 34 Used for configurables that don't contain a ``ConfigClass`` attribute, 35 or contain one that is being overridden. 43 return self.
_target(*args, **kwargs)
47 """A base class for global registries, which map names to configurables. 49 A registry acts like a read-only dictionary with an additional `register` 50 method to add targets. Targets in the registry are configurables (see 55 configBaseType : `lsst.pex.config.Config`-type 56 The base class for config classes in the registry. 60 A configurable is a callable with call signature ``(config, *args)`` 61 Configurables typically create an algorithm or are themselves the 62 algorithm. Often configurables are `lsst.pipe.base.Task` subclasses, but 65 A ``Registry`` has these requirements: 67 - All configurables added to a particular registry have the same call 69 - All configurables in a registry typically share something important 70 in common. For example, all configurables in ``psfMatchingRegistry`` 71 return a PSF matching class that has a ``psfMatch`` method with a 72 particular call signature. 76 This examples creates a configurable class ``Foo`` and adds it to a 77 registry. First, creating the configurable: 79 >>> from lsst.pex.config import Registry, Config 80 >>> class FooConfig(Config): 81 ... val = Field(dtype=int, default=3, doc="parameter for Foo") 84 ... ConfigClass = FooConfig 85 ... def __init__(self, config): 86 ... self.config = config 87 ... def addVal(self, num): 88 ... return self.config.val + num 91 Next, create a ``Registry`` instance called ``registry`` and register the 92 ``Foo`` configurable under the ``"foo"`` key: 94 >>> registry = Registry() 95 >>> registry.register("foo", Foo) 96 >>> print(list(registry.keys())) 99 Now ``Foo`` is conveniently accessible from the registry itself. 101 Finally, use the registry to get the configurable class and create an 104 >>> FooConfigurable = registry["foo"] 105 >>> foo = FooConfigurable(FooConfigurable.ConfigClass()) 111 if not issubclass(configBaseType, Config):
112 raise TypeError(
"configBaseType=%s must be a subclass of Config" % _typeStr(configBaseType,))
116 def register(self, name, target, ConfigClass=None):
117 """Add a new configurable target to the registry. 122 Name that the ``target`` is registered under. The target can 123 be accessed later with `dict`-like patterns using ``name`` as 126 A configurable type, usually a subclass of `lsst.pipe.base.Task`. 127 ConfigClass : `lsst.pex.config.Config`-type, optional 128 A subclass of `lsst.pex.config.Config` used to configure the 129 configurable. If `None` then the configurable's ``ConfigClass`` 135 Raised if an item with ``name`` is already in the registry. 137 Raised if ``ConfigClass`` is `None` and ``target`` does not have 138 a ``ConfigClass`` attribute. 142 If ``ConfigClass`` is provided then the ``target`` configurable is 143 wrapped in a new object that forwards function calls to it. Otherwise 144 the original ``target`` is stored. 146 if name
in self.
_dict:
147 raise RuntimeError(
"An item with name %r already exists" % name)
148 if ConfigClass
is None:
153 raise TypeError(
"ConfigClass=%s is not a subclass of %r" %
155 self.
_dict[name] = wrapper
158 return self.
_dict[key]
161 return len(self.
_dict)
164 return iter(self.
_dict)
167 return key
in self.
_dict 169 def makeField(self, doc, default=None, optional=False, multi=False):
170 """Create a `RegistryField` configuration field from this registry. 175 A description of the field. 176 default : object, optional 177 The default target for the field. 178 optional : `bool`, optional 179 When `False`, `lsst.pex.config.Config.validate` fails if the 180 field's value is `None`. 181 multi : `bool`, optional 182 A flag to allow multiple selections in the `RegistryField` if 187 field : `lsst.pex.config.RegistryField` 188 `~lsst.pex.config.RegistryField` Configuration field. 194 """Private class that makes a `Registry` behave like the thing a 195 `~lsst.pex.config.ConfigChoiceField` expects. 199 registry : `Registry` 220 """Dictionary of instantiated configs, used to populate a `RegistryField`. 224 config : `lsst.pex.config.Config` 225 Configuration instance. 226 field : `RegistryField` 231 ConfigInstanceDict.__init__(self, config, field)
234 def _getTarget(self):
237 "Multi-selection field has no attribute 'target'")
240 target = property(_getTarget)
242 def _getTargets(self):
245 "Single-selection field has no attribute 'targets'")
248 targets = property(_getTargets)
251 """Call the active target(s) with the active config as a keyword arg 253 If this is a multi-selection field, return a list obtained by calling 254 each active target with its corresponding active config. 256 Additional arguments will be passed on to the configurable target(s) 259 msg =
"No selection has been made. Options: %s" % \
260 (
" ".join(list(self.
_field.typemap.registry.keys())))
265 retvals.append(self.
_field.typemap.registry[c](*args, config=self[c], **kw))
268 return self.
_field.typemap.registry[self.
name](*args, config=self[self.
name], **kw)
271 if attr ==
"registry":
272 object.__setattr__(self, attr, value)
274 ConfigInstanceDict.__setattr__(self, attr, value)
278 """A configuration field whose options are defined in a `Registry`. 283 A description of the field. 284 registry : `Registry` 285 The registry that contains this field. 286 default : `str`, optional 287 The default target key. 288 optional : `bool`, optional 289 When `False`, `lsst.pex.config.Config.validate` fails if the field's 291 multi : `bool`, optional 292 If `True`, the field allows multiple selections. The default is 308 instanceDictClass = RegistryInstanceDict
309 """Class used to hold configurable instances in the field. 312 def __init__(self, doc, registry, default=None, optional=False, multi=False):
315 ConfigChoiceField.__init__(self, doc, types, default, optional, multi)
318 """Customize deep-copying, want a reference to the original registry. 320 WARNING: this must be overridden by subclasses if they change the 321 constructor signature! 323 other = type(self)(doc=self.
doc, registry=self.
registry,
324 default=copy.deepcopy(self.
default),
326 other.source = self.
source 331 """Create a `Registry`. 336 Docstring for the created `Registry` (this is set as the ``__doc__`` 337 attribute of the `Registry` instance. 338 configBaseType : `lsst.pex.config.Config`-type 339 Base type of config classes in the `Registry` 340 (`lsst.pex.config.Registry.configBaseType`). 344 registry : `Registry` 345 Registry with ``__doc__`` and `~Registry.configBaseType` attributes 348 cls = type(
"Registry", (Registry,), {
"__doc__": doc})
349 return cls(configBaseType=configBaseType)
353 """A decorator that adds a class as a configurable in a `Registry` 359 Name of the target (the decorated class) in the ``registry``. 360 registry : `Registry` 361 The `Registry` instance that the decorated class is added to. 362 ConfigClass : `lsst.pex.config.Config`-type, optional 363 Config class associated with the configurable. If `None`, the class's 364 ``ConfigClass`` attribute is used instead. 372 Internally, this decorator runs `Registry.register`. 375 registry.register(name, target=cls, ConfigClass=ConfigClass)
381 """Decorator that adds a class as a ``ConfigClass`` in a `Registry` and 382 associates it with the given configurable. 387 Name of the ``target`` in the ``registry``. 388 registry : `Registry` 389 The registry containing the ``target``. 391 A configurable type, such as a subclass of `lsst.pipe.base.Task`. 399 Internally, this decorator runs `Registry.register`. 402 registry.register(name, target=target, ConfigClass=cls)
def __call__(self, args, kwargs)
def registerConfigurable(name, registry, ConfigClass=None)
def registerConfig(name, registry, target)
def __contains__(self, key)
def makeField(self, doc, default=None, optional=False, multi=False)
def __init__(self, registry)
def __deepcopy__(self, memo)
def __setattr__(self, attr, value)
def apply(self, args, kw)
def __init__(self, target, ConfigClass)
def __contains__(self, k)
def __init__(self, doc, registry, default=None, optional=False, multi=False)
def __init__(self, config, field)
def register(self, name, target, ConfigClass=None)
def __getitem__(self, key)
def makeRegistry(doc, configBaseType=Config)
def __init__(self, configBaseType=Config)