2 from collections
import OrderedDict
7 from attrdict
import AttrDict
as ConfigDict
9 from warnings
import warn
10 warn(
"Could not import AttrDict, config values not accessible as attributes")
13 from ..param
import ConfigParam, ParamError, AnyValue, Iterable, InstanceOf, Scalar
15 logger = logging.getLogger(
'factory.creator.base')
19 subscribed_observers = OrderedDict()
25 "Proxy class to stand in place of ConfigParam defitions in Creator instances, to allow accessing as if a method of the creator class" 27 def __init__(self, param_name, param_def, creator):
35 "Retrieve a parameter from the configuration definition" 44 raise KeyError(
"The parameter name %s requested from config definition by %s was not found and is required" % (self.
param_name, self.
creator_name))
49 return self.
param_def.evaluate(param_val, **kwargs)
50 except ParamError
as exc:
54 return self.
value(**kwargs)
57 "Base creator object that handles ensuring the contract of creators parameters is kept and type checking parameters requested" 59 def __init__(self, config_def, common_store=None):
62 if common_store
is not None:
63 if not isinstance(common_store, dict):
64 raise TypeError(
"The common store passed must be a instance of a dict")
70 if isinstance(config_def, dict):
73 raise TypeError(
"The config definition (config_def) argument passed to %s should be of type dict" % self.__class__.__name__)
79 logger.debug(
"Initialized creator %s with parameters: %s" % (self.__class__.__name__, self.
parameters.keys()))
81 def _process_config(self, in_config_def):
82 "Process config definition, create nested Creators" 86 for config_name, config_val
in in_config_def.items():
87 if isinstance(config_val, dict)
and "creator" in config_val:
88 logger.debug(
"Initializing nested creator %s for %s" % (config_name, self.__class__.__name__))
89 out_config_def[config_name] = config_val[
"creator"](config_val, common_store=self.
common_store)
91 out_config_def[config_name] = config_val
98 setattr(self, param_name, param_proxy)
100 def _load_parameters(self):
101 "Gather class parameter types and ensure config_def has necessary items" 106 for attr_name
in dir(self):
107 attr_val = getattr(self, attr_name)
108 if isinstance(attr_val, ConfigParam):
111 def param(self, param_name, **kwargs):
112 "Retrieve a parameter from the configuration definition" 118 raise KeyError(
"Unregistered parameter %s requested by %s" % (param_name, self.__class__.__name__))
120 return param_proxy.value(**kwargs)
123 dispatch_list = subscribed_observers.get(RfType, [])
124 dispatch_list.append(self)
125 subscribed_observers[RfType] = dispatch_list
131 for obj_type, dispatch_list
in subscribed_observers.items():
132 if self
in dispatch_list:
133 dispatch_list.remove(self)
135 dispatch_list = subscribed_observers.get(RfType, [])
136 if self
in dispatch_list:
137 dispatch_list.remove(self)
141 for obj_type
in subscribed_observers.keys():
142 if len(subscribed_observers[obj_type]) == 0:
143 types_to_del.append(obj_type)
145 for obj_type
in types_to_del:
146 del subscribed_observers[obj_type]
148 def _dispatch(self, rf_obj):
149 "Called when the creator's object has been created to be sent to other creators who have registered to recieve objects of that type" 151 for RfType, dispatch_list
in subscribed_observers.items():
152 if isinstance(rf_obj, RfType):
153 for observer
in dispatch_list:
154 observer.receive(rf_obj)
157 "Recieves a dispatched object, needs to be implemented in inheriting class" 161 "Implements the action to create the object referred to by the Creator class. Should not be called directly." 162 raise NotImplementedError(
"Create must be defined in inheriting Creator classes")
165 """Turns creators into callables so that they can be evaluated by ConfigParam as any other callable without it 166 needing to know any details of this class.""" 168 result = self.
create(**kwargs)
170 if isinstance(result, list):
171 for result_item
in result:
173 elif isinstance(result, dict):
174 for result_item
in result.items():
186 "Base class for creators that iterate over their parameters" 190 def __init__(self, config_def, param_order=None, **kwargs):
191 super().
__init__(config_def, **kwargs)
193 if param_order
is None:
195 param_order = self.
param(
"order")
202 for param_name
in param_order:
203 if param_name !=
"creator":
211 "Evaluates and passes configurations parameter through as the creator result" 217 logger.debug(
"Passing through parameter %s" % param_name)
218 result[param_name] = self.
param(param_name, **kwargs)
223 "Evaluates parameters and saves them into the common store, creator has no return value" 229 logger.debug(
"Saving to the common store parameter %s" % param_name)
230 result[param_name] = self.
param(param_name, **kwargs)
236 "Simply picks one of many nested child elements and returns that, can be used as a place holder before implementing some sort of choice logic Creator"
def deregister_to_receive(self, RfType=None)
def __call__(self, kwargs)
def __init__(self, param_name, param_def, creator)
def receive(self, rf_obj)
def _dispatch(self, rf_obj)
def __call__(self, kwargs)
def _load_parameters(self)
def register_parameter(self, param_name, param_def)
def param(self, param_name, kwargs)
def _process_config(self, in_config_def)
def __init__(self, config_def, common_store=None)
def register_to_receive(self, RfType)
def __init__(self, config_def, param_order=None, kwargs)