summaryrefslogtreecommitdiff
path: root/mesonbuild/interpreterbase/baseobjects.py
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild/interpreterbase/baseobjects.py')
-rw-r--r--mesonbuild/interpreterbase/baseobjects.py33
1 files changed, 24 insertions, 9 deletions
diff --git a/mesonbuild/interpreterbase/baseobjects.py b/mesonbuild/interpreterbase/baseobjects.py
index 32c36f538..928d03861 100644
--- a/mesonbuild/interpreterbase/baseobjects.py
+++ b/mesonbuild/interpreterbase/baseobjects.py
@@ -35,19 +35,34 @@ TYPE_op_func = T.Callable[[TYPE_op_arg, TYPE_op_arg], TYPE_var]
SubProject = T.NewType('SubProject', str)
class InterpreterObject:
+ TRIVIAL_OPERATORS: T.Dict[
+ MesonOperator,
+ T.Tuple[
+ T.Union[T.Type, T.Tuple[T.Type, ...]],
+ TYPE_op_func
+ ]
+ ] = {}
+
+ def __init_subclass__(cls: T.Type[InterpreterObject], **kwargs: T.Any) -> None:
+ super().__init_subclass__(**kwargs)
+ saved_trivial_operators = cls.TRIVIAL_OPERATORS
+ cls.TRIVIAL_OPERATORS = {}
+
+ # Compute inherited operators according to the Python resolution order
+ # Reverse the result of mro() because update() will overwrite operators
+ # that are set by the superclass with those that are set by the subclass
+ for superclass in reversed(cls.mro()[1:]):
+ if issubclass(superclass, InterpreterObject):
+ cls.TRIVIAL_OPERATORS.update(superclass.TRIVIAL_OPERATORS)
+
+ cls.TRIVIAL_OPERATORS.update(saved_trivial_operators)
+
def __init__(self, *, subproject: T.Optional['SubProject'] = None) -> None:
self.methods: T.Dict[
str,
T.Callable[[T.List[TYPE_var], TYPE_kwargs], TYPE_var]
] = {}
self.operators: T.Dict[MesonOperator, TYPE_op_func] = {}
- self.trivial_operators: T.Dict[
- MesonOperator,
- T.Tuple[
- T.Union[T.Type, T.Tuple[T.Type, ...]],
- TYPE_op_func
- ]
- ] = {}
# Current node set during a method call. This can be used as location
# when printing a warning message during a method call.
self.current_node: mparser.BaseNode = None
@@ -79,8 +94,8 @@ class InterpreterObject:
raise InvalidCode(f'Unknown method "{method_name}" in object {self} of type {type(self).__name__}.')
def operator_call(self, operator: MesonOperator, other: TYPE_var) -> TYPE_var:
- if operator in self.trivial_operators:
- op = self.trivial_operators[operator]
+ if operator in self.TRIVIAL_OPERATORS:
+ op = self.TRIVIAL_OPERATORS[operator]
if op[0] is None and other is not None:
raise MesonBugException(f'The unary operator `{operator.value}` of {self.display_name()} was passed the object {other} of type {type(other).__name__}')
if op[0] is not None and not isinstance(other, op[0]):