예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
    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)
예제 #4
0
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)