diff options
author | Daniel Mensinger <daniel@mensinger-ka.de> | 2021-06-16 23:55:06 +0200 |
---|---|---|
committer | Daniel Mensinger <daniel@mensinger-ka.de> | 2021-06-18 23:48:33 +0200 |
commit | 66b32a45915238230557d8591e4521bdd7ecdb3b (patch) | |
tree | e32a6695f079c3de1d6d51362d9044b1a90e596c /mesonbuild/interpreterbase/baseobjects.py | |
parent | d601227cb2e00e8d4279f8dae27184fdbb0895e2 (diff) | |
download | meson-66b32a45915238230557d8591e4521bdd7ecdb3b.zip meson-66b32a45915238230557d8591e4521bdd7ecdb3b.tar.gz meson-66b32a45915238230557d8591e4521bdd7ecdb3b.tar.bz2 |
holders: Introduce HoldableObject
Diffstat (limited to 'mesonbuild/interpreterbase/baseobjects.py')
-rw-r--r-- | mesonbuild/interpreterbase/baseobjects.py | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/mesonbuild/interpreterbase/baseobjects.py b/mesonbuild/interpreterbase/baseobjects.py index b08da2f..d910e51 100644 --- a/mesonbuild/interpreterbase/baseobjects.py +++ b/mesonbuild/interpreterbase/baseobjects.py @@ -15,24 +15,33 @@ from .. import mparser from .exceptions import InvalidCode from .helpers import flatten +from ..mesonlib import HoldableObject import typing as T +if T.TYPE_CHECKING: + # Object holders need the actual interpreter + from ..interpreter import Interpreter + TV_fw_var = T.Union[str, int, bool, list, dict, 'InterpreterObject'] TV_fw_args = T.List[T.Union[mparser.BaseNode, TV_fw_var]] TV_fw_kwargs = T.Dict[str, T.Union[mparser.BaseNode, TV_fw_var]] TV_func = T.TypeVar('TV_func', bound=T.Callable[..., T.Any]) -TYPE_elementary = T.Union[str, int, bool] -TYPE_var = T.Union[TYPE_elementary, T.List[T.Any], T.Dict[str, T.Any], 'InterpreterObject'] +TYPE_elementary = T.Union[str, int, bool, T.List[T.Any], T.Dict[str, T.Any]] +TYPE_var = T.Union[TYPE_elementary, HoldableObject, 'MesonInterpreterObject'] TYPE_nvar = T.Union[TYPE_var, mparser.BaseNode] +TYPE_kwargs = T.Dict[str, TYPE_var] TYPE_nkwargs = T.Dict[str, TYPE_nvar] TYPE_key_resolver = T.Callable[[mparser.BaseNode], str] class InterpreterObject: def __init__(self, *, subproject: T.Optional[str] = None) -> None: - self.methods = {} # type: T.Dict[str, T.Callable[[T.List[TYPE_nvar], TYPE_nkwargs], TYPE_var]] + self.methods: T.Dict[ + str, + T.Callable[[T.List[TYPE_var], TYPE_kwargs], TYPE_var] + ] = {} # 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 @@ -41,8 +50,8 @@ class InterpreterObject: def method_call( self, method_name: str, - args: TV_fw_args, - kwargs: TV_fw_kwargs + args: T.List[TYPE_var], + kwargs: TYPE_kwargs ) -> TYPE_var: if method_name in self.methods: method = self.methods[method_name] @@ -52,20 +61,23 @@ class InterpreterObject: raise InvalidCode('Unknown method "%s" in object.' % method_name) class MesonInterpreterObject(InterpreterObject): - ''' All non-elementary objects should be derived from this ''' + ''' All non-elementary objects and non-object-holders should be derived from this ''' class MutableInterpreterObject: ''' Dummy class to mark the object type as mutable ''' -TV_InterpreterObject = T.TypeVar('TV_InterpreterObject') +InterpreterObjectTypeVar = T.TypeVar('InterpreterObjectTypeVar', bound=HoldableObject) -class ObjectHolder(MesonInterpreterObject, T.Generic[TV_InterpreterObject]): - def __init__(self, obj: TV_InterpreterObject, *, subproject: T.Optional[str] = None) -> None: - super().__init__(subproject=subproject) +class ObjectHolder(InterpreterObject, T.Generic[InterpreterObjectTypeVar]): + def __init__(self, obj: InterpreterObjectTypeVar, interpreter: 'Interpreter') -> None: + super().__init__(subproject=interpreter.subproject) + assert isinstance(obj, HoldableObject), f'This is a bug: Trying to hold object of type `{type(obj).__name__}` that is not an `HoldableObject`' self.held_object = obj + self.interpreter = interpreter + self.env = self.interpreter.environment def __repr__(self) -> str: - return f'<Holder: {self.held_object!r}>' + return f'<[{type(self).__name__}] holds [{type(self.held_object).__name__}]: {self.held_object!r}>' class RangeHolder(MesonInterpreterObject): def __init__(self, start: int, stop: int, step: int, *, subproject: T.Optional[str] = None) -> None: |