def _createChildListProperties(cls, name, bases, dict): """ Introspect the class being created to look for class members which contain 'declarative' [Node] objects. Move these declarations into the child_infos class member, and create getters, setters and properties to provide access to each of the child members. """ list_infos = {} for info_name, v in dict.items(): if isinstance(v, list) and isinstance(v[0], Node): list_infos[info_name] = v removal = [] for info_name in list_infos.keys(): property_name = underscoresToCamelCase(info_name) if info_name != property_name: removal.append(info_name) def _getProperty(self, info_name=info_name): return self._children[info_name] def _setProperty(self, value, info_name=info_name): self._children[info_name] = value if not hasprop(cls, property_name): setattr(cls, property_name, property(_getProperty, _setProperty)) for info_name in removal: delattr(cls, info_name) cls.child_infos.update(list_infos)
def __call__(cls, *args, **kwargs): """ Called when instances of classes with this metaclass. i.e. AstNodes. Consume keyword arguments with the same name as child properties and options then set the appropriate attributes. """ # First create the object obj = type.__call__(cls, *args) for kwarg in kwargs: if hasprop(cls, kwarg): setattr(obj, kwarg, kwargs[kwarg]) else: raise AttributeError("No such property initialiser as '%s' on '%s'" % (kwarg, cls.__name__)) # TODO: Should remove consumed kwargs here return obj