aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/utils/universal.py
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2023-03-09 10:20:57 -0800
committerEli Schwartz <eschwartz93@gmail.com>2023-03-09 19:03:44 -0500
commit7c2ac4f8fe2bda306adc73572d8f8e43010456cb (patch)
tree97c23889e0aec53ff81e12ddc19acfae00e26267 /mesonbuild/utils/universal.py
parent62c269d08859747ba558e90bc98505e6325ef678 (diff)
downloadmeson-7c2ac4f8fe2bda306adc73572d8f8e43010456cb.zip
meson-7c2ac4f8fe2bda306adc73572d8f8e43010456cb.tar.gz
meson-7c2ac4f8fe2bda306adc73572d8f8e43010456cb.tar.bz2
utils: fix annotation of pickle_load
It's actually Generic, and we should use Generic annotations to get the correct result. This means that we don't have to assert or cast the return type, because mypy just knowns
Diffstat (limited to 'mesonbuild/utils/universal.py')
-rw-r--r--mesonbuild/utils/universal.py31
1 files changed, 26 insertions, 5 deletions
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