aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/coredata.py4
-rw-r--r--mesonbuild/minstall.py4
-rw-r--r--mesonbuild/utils/universal.py31
3 files changed, 28 insertions, 11 deletions
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index 62c81ff..38d6fcf 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -1056,9 +1056,7 @@ def major_versions_differ(v1: str, v2: str) -> bool:
def load(build_dir: str) -> CoreData:
filename = os.path.join(build_dir, 'meson-private', 'coredata.dat')
- obj = pickle_load(filename, 'Coredata', CoreData)
- assert isinstance(obj, CoreData), 'for mypy'
- return obj
+ return pickle_load(filename, 'Coredata', CoreData)
def save(obj: CoreData, build_dir: str) -> str:
diff --git a/mesonbuild/minstall.py b/mesonbuild/minstall.py
index 969e09e..6922c38 100644
--- a/mesonbuild/minstall.py
+++ b/mesonbuild/minstall.py
@@ -131,9 +131,7 @@ class DirMaker:
def load_install_data(fname: str) -> InstallData:
- obj = pickle_load(fname, 'InstallData', InstallData)
- assert isinstance(obj, InstallData), 'fo mypy'
- return obj
+ return pickle_load(fname, 'InstallData', InstallData)
def is_executable(path: str, follow_symlinks: bool = False) -> bool:
'''Checks whether any of the "x" bits are set in the source file mode.'''
diff --git a/mesonbuild/utils/universal.py b/mesonbuild/utils/universal.py
index b0cc252..bd136ba 100644
--- a/mesonbuild/utils/universal.py
+++ b/mesonbuild/utils/universal.py
@@ -37,13 +37,26 @@ from mesonbuild import mlog
from .core import MesonException, HoldableObject
if T.TYPE_CHECKING:
- from typing_extensions import Literal
+ from typing_extensions import Literal, Protocol
from .._typing import ImmutableListProtocol
from ..build import ConfigurationData
from ..coredata import KeyedOptionDictType, UserOption
+ from ..environment import Environment
from ..compilers.compilers import Compiler
+ class _EnvPickleLoadable(Protocol):
+
+ environment: Environment
+
+ class _VerPickleLoadable(Protocol):
+
+ version: str
+
+ # A generic type for pickle_load. This allows any type that has either a
+ # .version or a .environment to be passed.
+ _PL = T.TypeVar('_PL', bound=T.Union[_EnvPickleLoadable, _VerPickleLoadable])
+
FileOrString = T.Union['File', str]
_T = T.TypeVar('_T')
@@ -2326,7 +2339,8 @@ class OptionKey:
"""Convenience method to check if this is a base option."""
return self.type is OptionType.BASE
-def pickle_load(filename: str, object_name: str, object_type: T.Type) -> T.Any:
+
+def pickle_load(filename: str, object_name: str, object_type: T.Type[_PL]) -> _PL:
load_fail_msg = f'{object_name} file {filename!r} is corrupted. Try with a fresh build tree.'
try:
with open(filename, 'rb') as f:
@@ -2342,11 +2356,18 @@ def pickle_load(filename: str, object_name: str, object_type: T.Type) -> T.Any:
f'meson setup {build_dir} --wipe')
if not isinstance(obj, object_type):
raise MesonException(load_fail_msg)
+
+ # Because these Protocols are not available at runtime (and cannot be made
+ # available at runtime until we drop support for Python < 3.8), we have to
+ # do a bit of hackery so that mypy understands what's going on here
+ version: str
+ if hasattr(obj, 'version'):
+ version = T.cast('_VerPickleLoadable', obj).version
+ else:
+ version = T.cast('_EnvPickleLoadable', obj).environment.coredata.version
+
from ..coredata import version as coredata_version
from ..coredata import major_versions_differ, MesonVersionMismatchException
- version = getattr(obj, 'version', None)
- if version is None:
- version = obj.environment.coredata.version
if major_versions_differ(version, coredata_version):
raise MesonVersionMismatchException(version, coredata_version)
return obj