23 __all__ = (
"Registry",
"makeRegistry",
"RegistryField",
"registerConfig",
"registerConfigurable")
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. 43 return self.
_target(*args, **kwargs)
47 """A base class for global registries, mapping names to configurables. 49 There are no hard requirements on configurable, but they typically create an algorithm 50 or are themselves the algorithm, and typical usage is as follows: 51 - configurable is a callable whose call signature is (config, ...extra arguments...) 52 - All configurables added to a particular registry will have the same call signature 53 - All configurables in a registry will typically share something important in common. 54 For example all configurables in psfMatchingRegistry return a psf matching 55 class that has a psfMatch method with a particular call signature. 57 A registry acts like a read-only dictionary with an additional register method to add items. 58 The dict contains configurables and each configurable has an instance ConfigClass. 62 class FooConfig(Config): 63 val = Field(dtype=int, default=3, doc="parameter for Foo") 65 ConfigClass = FooConfig 66 def __init__(self, config): 68 def addVal(self, num): 69 return self.config.val + num 70 registry.register("foo", Foo) 71 names = registry.keys() # returns ("foo",) 72 fooConfigurable = registry["foo"] 73 fooConfig = fooItem.ConfigClass() 74 foo = fooConfigurable(fooConfig) 75 foo.addVal(5) # returns config.val + 5 79 """Construct a registry of name: configurables 81 @param configBaseType: base class for config classes in registry 83 if not issubclass(configBaseType, Config):
84 raise TypeError(
"configBaseType=%s must be a subclass of Config" % _typeStr(configBaseType,))
88 def register(self, name, target, ConfigClass=None):
89 """Add a new item to the registry. 91 @param target A callable 'object that takes a Config instance as its first argument. 92 This may be a Python type, but is not required to be. 93 @param ConfigClass A subclass of pex_config Config used to configure the configurable; 94 if None then configurable.ConfigClass is used. 96 @note: If ConfigClass is provided then then 'target' is wrapped in a new object that forwards 97 function calls to it. Otherwise the original 'target' is stored. 99 @raise AttributeError if ConfigClass is None and target does not have attribute ConfigClass 101 if name
in self.
_dict:
102 raise RuntimeError(
"An item with name %r already exists" % name)
103 if ConfigClass
is None:
108 raise TypeError(
"ConfigClass=%s is not a subclass of %r" %
110 self.
_dict[name] = wrapper
113 return self.
_dict[key]
116 return len(self.
_dict)
119 return iter(self.
_dict)
122 return key
in self.
_dict 124 def makeField(self, doc, default=None, optional=False, multi=False):
129 """Private class that makes a Registry behave like the thing a ConfigChoiceField expects.""" 149 ConfigInstanceDict.__init__(self, config, field)
152 def _getTarget(self):
155 "Multi-selection field has no attribute 'target'")
157 target = property(_getTarget)
159 def _getTargets(self):
162 "Single-selection field has no attribute 'targets'")
164 targets = property(_getTargets)
167 """Call the active target(s) with the active config as a keyword arg 169 If this is a multi-selection field, return a list obtained by calling 170 each active target with its corresponding active config. 172 Additional arguments will be passed on to the configurable target(s) 175 msg =
"No selection has been made. Options: %s" % \
176 (
" ".join(list(self.
_field.typemap.registry.keys())))
181 retvals.append(self.
_field.typemap.registry[c](*args, config=self[c], **kw))
184 return self.
_field.typemap.registry[self.
name](*args, config=self[self.
name], **kw)
187 if attr ==
"registry":
188 object.__setattr__(self, attr, value)
190 ConfigInstanceDict.__setattr__(self, attr, value)
194 instanceDictClass = RegistryInstanceDict
196 def __init__(self, doc, registry, default=None, optional=False, multi=False):
199 ConfigChoiceField.__init__(self, doc, types, default, optional, multi)
202 """Customize deep-copying, want a reference to the original registry. 203 WARNING: this must be overridden by subclasses if they change the 204 constructor signature! 206 other = type(self)(doc=self.
doc, registry=self.
registry,
207 default=copy.deepcopy(self.
default),
209 other.source = self.
source 214 """A convenience function to create a new registry. 216 The returned value is an instance of a trivial subclass of Registry whose only purpose is to 217 customize its doc string and set attrList. 219 cls = type(
"Registry", (Registry,), {
"__doc__": doc})
220 return cls(configBaseType=configBaseType)
224 """A decorator that adds a class as a configurable in a Registry. 226 If the 'ConfigClass' argument is None, the class's ConfigClass attribute will be used. 229 registry.register(name, target=cls, ConfigClass=ConfigClass)
235 """A decorator that adds a class as a ConfigClass in a Registry, and associates it with the given 239 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)
def register(self, name, target, ConfigClass=None)
def __getitem__(self, key)