diff options
author | Dylan Baker <dylan@pnwbakers.com> | 2023-03-09 10:20:57 -0800 |
---|---|---|
committer | Eli Schwartz <eschwartz93@gmail.com> | 2023-03-09 19:03:44 -0500 |
commit | 7c2ac4f8fe2bda306adc73572d8f8e43010456cb (patch) | |
tree | 97c23889e0aec53ff81e12ddc19acfae00e26267 /mesonbuild/utils/universal.py | |
parent | 62c269d08859747ba558e90bc98505e6325ef678 (diff) | |
download | meson-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.py | 31 |
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 |