23 __all__ = (
"Registry",
"makeRegistry",
"RegistryField",
"registerConfig",
"registerConfigurable")
25 import collections.abc
28 from .config
import Config, FieldValidationError, _typeStr
29 from .configChoiceField
import ConfigInstanceDict, ConfigChoiceField
33 """A wrapper for configurables. 35 Used for configurables that don't contain a ``ConfigClass`` attribute, 36 or contain one that is being overridden. 44 return self.
_target(*args, **kwargs)
48 """A base class for global registries, which map names to configurables. 50 A registry acts like a read-only dictionary with an additional `register` 51 method to add targets. Targets in the registry are configurables (see 56 configBaseType : `lsst.pex.config.Config`-type 57 The base class for config classes in the registry. 61 A configurable is a callable with call signature ``(config, *args)`` 62 Configurables typically create an algorithm or are themselves the 63 algorithm. Often configurables are `lsst.pipe.base.Task` subclasses, but 66 A ``Registry`` has these requirements: 68 - All configurables added to a particular registry have the same call 70 - All configurables in a registry typically share something important 71 in common. For example, all configurables in ``psfMatchingRegistry`` 72 return a PSF matching class that has a ``psfMatch`` method with a 73 particular call signature. 77 This examples creates a configurable class ``Foo`` and adds it to a 78 registry. First, creating the configurable: 80 >>> from lsst.pex.config import Registry, Config 81 >>> class FooConfig(Config): 82 ... val = Field(dtype=int, default=3, doc="parameter for Foo") 85 ... ConfigClass = FooConfig 86 ... def __init__(self, config): 87 ... self.config = config 88 ... def addVal(self, num): 89 ... return self.config.val + num 92 Next, create a ``Registry`` instance called ``registry`` and register the 93 ``Foo`` configurable under the ``"foo"`` key: 95 >>> registry = Registry() 96 >>> registry.register("foo", Foo) 97 >>> print(list(registry.keys())) 100 Now ``Foo`` is conveniently accessible from the registry itself. 102 Finally, use the registry to get the configurable class and create an 105 >>> FooConfigurable = registry["foo"] 106 >>> foo = FooConfigurable(FooConfigurable.ConfigClass()) 112 if not issubclass(configBaseType, Config):
113 raise TypeError(
"configBaseType=%s must be a subclass of Config" % _typeStr(configBaseType,))
117 def register(self, name, target, ConfigClass=None):
118 """Add a new configurable target to the registry. 123 Name that the ``target`` is registered under. The target can 124 be accessed later with `dict`-like patterns using ``name`` as 127 A configurable type, usually a subclass of `lsst.pipe.base.Task`. 128 ConfigClass : `lsst.pex.config.Config`-type, optional 129 A subclass of `lsst.pex.config.Config` used to configure the 130 configurable. If `None` then the configurable's ``ConfigClass`` 136 Raised if an item with ``name`` is already in the registry. 138 Raised if ``ConfigClass`` is `None` and ``target`` does not have 139 a ``ConfigClass`` attribute. 143 If ``ConfigClass`` is provided then the ``target`` configurable is 144 wrapped in a new object that forwards function calls to it. Otherwise 145 the original ``target`` is stored. 147 if name
in self.
_dict:
148 raise RuntimeError(
"An item with name %r already exists" % name)
149 if ConfigClass
is None:
154 raise TypeError(
"ConfigClass=%s is not a subclass of %r" %
156 self.
_dict[name] = wrapper
159 return self.
_dict[key]
162 return len(self.
_dict)
165 return iter(self.
_dict)
168 return key
in self.
_dict 170 def makeField(self, doc, default=None, optional=False, multi=False):
171 """Create a `RegistryField` configuration field from this registry. 176 A description of the field. 177 default : object, optional 178 The default target for the field. 179 optional : `bool`, optional 180 When `False`, `lsst.pex.config.Config.validate` fails if the 181 field's value is `None`. 182 multi : `bool`, optional 183 A flag to allow multiple selections in the `RegistryField` if 188 field : `lsst.pex.config.RegistryField` 189 `~lsst.pex.config.RegistryField` Configuration field. 195 """Private class that makes a `Registry` behave like the thing a 196 `~lsst.pex.config.ConfigChoiceField` expects. 200 registry : `Registry` 221 """Dictionary of instantiated configs, used to populate a `RegistryField`. 225 config : `lsst.pex.config.Config` 226 Configuration instance. 227 field : `RegistryField` 232 ConfigInstanceDict.__init__(self, config, field)
235 def _getTarget(self):
238 "Multi-selection field has no attribute 'target'")
241 target = property(_getTarget)
243 def _getTargets(self):
246 "Single-selection field has no attribute 'targets'")
249 targets = property(_getTargets)
252 """Call the active target(s) with the active config as a keyword arg 254 If this is a multi-selection field, return a list obtained by calling 255 each active target with its corresponding active config. 257 Additional arguments will be passed on to the configurable target(s) 260 msg =
"No selection has been made. Options: %s" % \
261 (
" ".join(
list(self.
_field.typemap.registry.keys())))
266 retvals.append(self.
_field.typemap.registry[c](*args, config=self[c], **kw))
269 return self.
_field.typemap.registry[self.
name](*args, config=self[self.
name], **kw)
272 if attr ==
"registry":
273 object.__setattr__(self, attr, value)
275 ConfigInstanceDict.__setattr__(self, attr, value)
279 """A configuration field whose options are defined in a `Registry`. 284 A description of the field. 285 registry : `Registry` 286 The registry that contains this field. 287 default : `str`, optional 288 The default target key. 289 optional : `bool`, optional 290 When `False`, `lsst.pex.config.Config.validate` fails if the field's 292 multi : `bool`, optional 293 If `True`, the field allows multiple selections. The default is 309 instanceDictClass = RegistryInstanceDict
310 """Class used to hold configurable instances in the field. 313 def __init__(self, doc, registry, default=None, optional=False, multi=False):
316 ConfigChoiceField.__init__(self, doc, types, default, optional, multi)
319 """Customize deep-copying, want a reference to the original registry. 321 WARNING: this must be overridden by subclasses if they change the 322 constructor signature! 325 default=copy.deepcopy(self.
default),
327 other.source = self.
source 332 """Create a `Registry`. 337 Docstring for the created `Registry` (this is set as the ``__doc__`` 338 attribute of the `Registry` instance. 339 configBaseType : `lsst.pex.config.Config`-type 340 Base type of config classes in the `Registry` 341 (`lsst.pex.config.Registry.configBaseType`). 345 registry : `Registry` 346 Registry with ``__doc__`` and `~Registry.configBaseType` attributes 349 cls =
type(
"Registry", (Registry,), {
"__doc__": doc})
350 return cls(configBaseType=configBaseType)
354 """A decorator that adds a class as a configurable in a `Registry` 360 Name of the target (the decorated class) in the ``registry``. 361 registry : `Registry` 362 The `Registry` instance that the decorated class is added to. 363 ConfigClass : `lsst.pex.config.Config`-type, optional 364 Config class associated with the configurable. If `None`, the class's 365 ``ConfigClass`` attribute is used instead. 373 Internally, this decorator runs `Registry.register`. 376 registry.register(name, target=cls, ConfigClass=ConfigClass)
382 """Decorator that adds a class as a ``ConfigClass`` in a `Registry` and 383 associates it with the given configurable. 388 Name of the ``target`` in the ``registry``. 389 registry : `Registry` 390 The registry containing the ``target``. 392 A configurable type, such as a subclass of `lsst.pipe.base.Task`. 400 Internally, this decorator runs `Registry.register`. 403 registry.register(name, target=target, ConfigClass=cls)
def __setattr__(self, attr, value)
def registerConfig(name, registry, target)
def registerConfigurable(name, registry, ConfigClass=None)
def __deepcopy__(self, memo)
def __init__(self, configBaseType=Config)
def __init__(self, registry)
def __call__(self, args, kwargs)
def apply(self, args, kw)
def __init__(self, doc, registry, default=None, optional=False, multi=False)
def makeField(self, doc, default=None, optional=False, multi=False)
def __contains__(self, k)
def __init__(self, config, field)
def makeRegistry(doc, configBaseType=Config)
def __contains__(self, key)
def __init__(self, target, ConfigClass)
daf::base::PropertyList * list
def register(self, name, target, ConfigClass=None)
def __getitem__(self, key)