allow some ObjectHolder subclasses to continue to be generic

ExternalProgram and CustomTarget have some use cases for producing
subclassed interpreter holders with more specific types and methods. In
order for those subclasses to properly refer to their held_object, we
need a shared base class that is still generic, though bound.

For the derived held objects, inherit from the base class and specify
the final types as the module-specific type.
pull/12106/head
Eli Schwartz 1 year ago
parent 13b626b67b
commit 277151450a
No known key found for this signature in database
GPG Key ID: CEB167EFB5722BD6
  1. 18
      mesonbuild/interpreter/interpreterobjects.py
  2. 6
      mesonbuild/modules/hotdoc.py
  3. 8
      mesonbuild/modules/python.py

@ -559,8 +559,10 @@ class DependencyHolder(ObjectHolder[Dependency]):
new_dep = self.held_object.generate_link_whole_dependency()
return new_dep
class ExternalProgramHolder(ObjectHolder[ExternalProgram]):
def __init__(self, ep: ExternalProgram, interpreter: 'Interpreter') -> None:
_EXTPROG = T.TypeVar('_EXTPROG', bound=ExternalProgram)
class _ExternalProgramHolder(ObjectHolder[_EXTPROG]):
def __init__(self, ep: _EXTPROG, interpreter: 'Interpreter') -> None:
super().__init__(ep, interpreter)
self.methods.update({'found': self.found_method,
'path': self.path_method,
@ -606,6 +608,9 @@ class ExternalProgramHolder(ObjectHolder[ExternalProgram]):
def found(self) -> bool:
return self.held_object.found()
class ExternalProgramHolder(_ExternalProgramHolder[ExternalProgram]):
pass
class ExternalLibraryHolder(ObjectHolder[ExternalLibrary]):
def __init__(self, el: ExternalLibrary, interpreter: 'Interpreter'):
super().__init__(el, interpreter)
@ -969,8 +974,10 @@ class CustomTargetIndexHolder(ObjectHolder[build.CustomTargetIndex]):
assert self.interpreter.backend is not None
return self.interpreter.backend.get_target_filename_abs(self.held_object)
class CustomTargetHolder(ObjectHolder[build.CustomTarget]):
def __init__(self, target: 'build.CustomTarget', interp: 'Interpreter'):
_CT = T.TypeVar('_CT', bound=build.CustomTarget)
class _CustomTargetHolder(ObjectHolder[_CT]):
def __init__(self, target: _CT, interp: 'Interpreter'):
super().__init__(target, interp)
self.methods.update({'full_path': self.full_path_method,
'to_list': self.to_list_method,
@ -1007,6 +1014,9 @@ class CustomTargetHolder(ObjectHolder[build.CustomTarget]):
except IndexError:
raise InvalidArguments(f'Index {other} out of bounds of custom target {self.held_object.name} output of size {len(self.held_object)}.')
class CustomTargetHolder(_CustomTargetHolder[build.CustomTarget]):
pass
class RunTargetHolder(ObjectHolder[build.RunTarget]):
pass

@ -28,7 +28,7 @@ from ..interpreterbase import (
InvalidArguments, noPosargs, noKwargs, typed_kwargs, FeatureDeprecated,
ContainerTypeInfo, KwargInfo, typed_pos_args
)
from ..interpreter import CustomTargetHolder
from ..interpreter.interpreterobjects import _CustomTargetHolder
from ..interpreter.type_checking import NoneType
from ..programs import ExternalProgram
@ -364,8 +364,8 @@ class HotdocTargetBuilder:
return (target, install_script)
class HotdocTargetHolder(CustomTargetHolder):
def __init__(self, target, interp):
class HotdocTargetHolder(_CustomTargetHolder['HotdocTarget']):
def __init__(self, target: HotdocTarget, interp):
super().__init__(target, interp)
self.methods.update({'config_path': self.config_path_method})

@ -24,8 +24,8 @@ from ..build import known_shmod_kwargs, CustomTarget, CustomTargetIndex, BuildTa
from ..dependencies import NotFoundDependency
from ..dependencies.detect import get_dep_identifier, find_external_dependency
from ..dependencies.python import BasicPythonExternalProgram, python_factory, _PythonDependencyBase
from ..interpreter import ExternalProgramHolder, extract_required_kwarg, permitted_dependency_kwargs
from ..interpreter import primitives as P_OBJ
from ..interpreter import extract_required_kwarg, permitted_dependency_kwargs, primitives as P_OBJ
from ..interpreter.interpreterobjects import _ExternalProgramHolder
from ..interpreter.type_checking import NoneType, PRESERVE_PATH_KW, SHARED_MOD_KWS
from ..interpreterbase import (
noPosargs, noKwargs, permittedKwargs, ContainerTypeInfo,
@ -114,9 +114,9 @@ _PURE_KW = KwargInfo('pure', (bool, NoneType))
_SUBDIR_KW = KwargInfo('subdir', str, default='')
_DEFAULTABLE_SUBDIR_KW = KwargInfo('subdir', (str, NoneType))
class PythonInstallation(ExternalProgramHolder):
class PythonInstallation(_ExternalProgramHolder['PythonExternalProgram']):
def __init__(self, python: 'PythonExternalProgram', interpreter: 'Interpreter'):
ExternalProgramHolder.__init__(self, python, interpreter)
_ExternalProgramHolder.__init__(self, python, interpreter)
info = python.info
prefix = self.interpreter.environment.coredata.get_option(mesonlib.OptionKey('prefix'))
assert isinstance(prefix, str), 'for mypy'

Loading…
Cancel
Save