def __new__(cls, name, bases, dictionary): # pylint: disable=I0021,arguments-differ _checkBases(name, bases) if "__slots__" not in dictionary: dictionary["__slots__"] = () if "named_child" in dictionary: named_child = dictionary["named_child"] if type(named_child) is not str: raise NuitkaNodeDesignError( name, "Class named_child attribute must be string not", type(named_child), ) dictionary["__slots__"] += (intern("subnode_" + dictionary["named_child"]), ) if "named_children" in dictionary: if len(dictionary["named_children"]) <= 1: raise NuitkaNodeDesignError( name, "Use ExpressionChildHaving for one child node classes") assert type(dictionary["named_children"]) is tuple dictionary["__slots__"] += tuple( intern("subnode_" + named_child) for named_child in dictionary["named_children"]) # Not a method: if "checker" in dictionary: dictionary["checker"] = staticmethod(dictionary["checker"]) # false alarm, pylint: disable=I0021,too-many-function-args return ABCMeta.__new__(cls, name, bases, dictionary)
def __init__(self, values): assert (type(self.named_children) is tuple and self.named_children), self.named_children # TODO: Make this true. # assert len(self.named_children) > 1, self.kind # Check for completeness of given values, everything should be there # but of course, might be put to None. if set(values.keys()) != set(self.named_children): raise NuitkaNodeDesignError( "Must pass named children in value dictionary", set(values.keys()), set(self.named_children), ) for name, value in values.items(): if name in self.checkers: value = self.checkers[name](value) if type(value) is tuple: assert None not in value, name for val in value: val.parent = self elif value is None: pass else: value.parent = self attr_name = "subnode_" + name setattr(self, attr_name, value)
def __init__(cls, name, bases, dictionary): # @NoSelf if not name.endswith("Base"): if "kind" not in dictionary: raise NuitkaNodeDesignError( name, "Must provide class variable 'kind'") kind = dictionary["kind"] assert type(kind) is str, name assert kind not in NodeCheckMetaClass.kinds, (name, kind) NodeCheckMetaClass.kinds[kind] = cls NodeCheckMetaClass.kinds[name] = cls kind_to_name_part = "".join([x.title() for x in kind.split("_")]) assert name.endswith(kind_to_name_part), (name, kind_to_name_part) # Automatically add checker methods for everything to the common # base class checker_method = "is" + kind_to_name_part # TODO: How about making these two functions, one to statically # return True and False, and put one in the base class, and one # in the new class, would be slightly faster. def checkKind(self): return self.kind == kind # Add automatic checker methods to the node base class. from .NodeBases import NodeBase if not hasattr(NodeBase, checker_method): setattr(NodeBase, checker_method, checkKind) ABCMeta.__init__(cls, name, bases, dictionary)
def _checkBases(name, bases): # Avoid duplicate base classes. assert len(bases) == len(set(bases)), (name, bases) # Insist on mixins being in proper place for inheritance. last_mixin = None for base in bases: base_name = base.__name__ is_mixin = base_name.endswith("Mixin") if is_mixin and last_mixin is False: raise NuitkaNodeDesignError( name, "Mixins must come first in base classes.", bases) last_mixin = is_mixin if base is not object and "__slots__" not in base.__dict__: raise NuitkaNodeDesignError(name, "All bases must have __slots__.", base)