diff options
| -rw-r--r-- | mesonbuild/coredata.py | 19 | ||||
| -rw-r--r-- | mesonbuild/mesonlib/universal.py | 22 | ||||
| -rw-r--r-- | mesonbuild/minstall.py | 15 |
3 files changed, 30 insertions, 26 deletions
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 569fe3917..a55d674c5 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -23,6 +23,7 @@ from .mesonlib import ( MesonException, EnvironmentException, MachineChoice, PerMachine, PerMachineDefaultable, default_libdir, default_libexecdir, default_prefix, split_args, OptionKey, OptionType, stringlistify, + pickle_load ) from .wrap import WrapMode import ast @@ -1047,23 +1048,11 @@ 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') - load_fail_msg = f'Coredata file {filename!r} is corrupted. Try with a fresh build tree.' - try: - with open(filename, 'rb') as f: - obj = pickle.load(f) - except (pickle.UnpicklingError, EOFError): - raise MesonException(load_fail_msg) - except (TypeError, ModuleNotFoundError, AttributeError): - raise MesonException( - f"Coredata file {filename!r} references functions or classes that don't " - "exist. This probably means that it was generated with an old " - "version of meson.") - if not isinstance(obj, CoreData): - raise MesonException(load_fail_msg) - if major_versions_differ(obj.version, version): - raise MesonVersionMismatchException(obj.version, version) + obj = pickle_load(filename, 'Coredata', CoreData) + assert isinstance(obj, CoreData), 'for mypy' return obj + def save(obj: CoreData, build_dir: str) -> str: filename = os.path.join(build_dir, 'meson-private', 'coredata.dat') prev_filename = filename + '.prev' diff --git a/mesonbuild/mesonlib/universal.py b/mesonbuild/mesonlib/universal.py index d708671c8..71f206af6 100644 --- a/mesonbuild/mesonlib/universal.py +++ b/mesonbuild/mesonlib/universal.py @@ -31,6 +31,7 @@ import typing as T import uuid import textwrap import copy +import pickle from mesonbuild import mlog @@ -123,6 +124,7 @@ __all__ = [ 'listify', 'partition', 'path_is_in_root', + 'pickle_load', 'Popen_safe', 'quiet_git', 'quote_arg', @@ -2232,3 +2234,23 @@ class OptionKey: def is_base(self) -> bool: """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: + load_fail_msg = f'{object_name} file {filename!r} is corrupted. Try with a fresh build tree.' + try: + with open(filename, 'rb') as f: + obj = pickle.load(f) + except (pickle.UnpicklingError, EOFError): + raise MesonException(load_fail_msg) + except (TypeError, ModuleNotFoundError, AttributeError): + raise MesonException( + f"{object_name} file {filename!r} references functions or classes that don't " + "exist. This probably means that it was generated with an old " + "version of meson.") + if not isinstance(obj, object_type): + raise MesonException(load_fail_msg) + from ..coredata import version as coredata_version + from ..coredata import major_versions_differ, MesonVersionMismatchException + if major_versions_differ(obj.version, coredata_version): + raise MesonVersionMismatchException(obj.version, coredata_version) + return obj diff --git a/mesonbuild/minstall.py b/mesonbuild/minstall.py index 0c691267e..551f909c8 100644 --- a/mesonbuild/minstall.py +++ b/mesonbuild/minstall.py @@ -18,7 +18,6 @@ from pathlib import Path import argparse import errno import os -import pickle import shlex import shutil import subprocess @@ -28,9 +27,7 @@ import typing as T from . import build from . import environment from .backend.backends import InstallData -from .coredata import major_versions_differ, MesonVersionMismatchException -from .coredata import version as coredata_version -from .mesonlib import MesonException, Popen_safe, RealPathAction, is_windows, setup_vsenv +from .mesonlib import MesonException, Popen_safe, RealPathAction, is_windows, setup_vsenv, pickle_load from .scripts import depfixer, destdir_join from .scripts.meson_exe import run_exe try: @@ -133,13 +130,9 @@ class DirMaker: def load_install_data(fname: str) -> InstallData: - with open(fname, 'rb') as ifile: - obj = pickle.load(ifile) - if not isinstance(obj, InstallData) or not hasattr(obj, 'version'): - raise MesonVersionMismatchException('<unknown>', coredata_version) - if major_versions_differ(obj.version, coredata_version): - raise MesonVersionMismatchException(obj.version, coredata_version) - return obj + obj = pickle_load(fname, 'InstallData', InstallData) + assert isinstance(obj, InstallData), 'fo mypy' + return obj def is_executable(path: str, follow_symlinks: bool = False) -> bool: '''Checks whether any of the "x" bits are set in the source file mode.''' |
