diff options
author | Eli Schwartz <eschwartz@archlinux.org> | 2022-11-16 19:20:33 -0500 |
---|---|---|
committer | Dylan Baker <dylan@pnwbakers.com> | 2022-11-17 12:56:04 -0800 |
commit | 0d3be23377c82f844aa7f9e9cb6074a8813400a4 (patch) | |
tree | d3a1968dc78e080616e4986c57a271c1e2d498a0 | |
parent | 3a4aa109b4932d13c1a620575510c41eae6cb048 (diff) | |
download | meson-0d3be23377c82f844aa7f9e9cb6074a8813400a4.zip meson-0d3be23377c82f844aa7f9e9cb6074a8813400a4.tar.gz meson-0d3be23377c82f844aa7f9e9cb6074a8813400a4.tar.bz2 |
build: use the unified pickle loader to handle more edge cases
We have divergent implementations of loading a pickled *.dat file. The
Build class loader has a better error message. But the generic loader
handles TypeError and ModuleNotFoundError. Merge the implementations,
and use it for Build as well.
Fixes #11051
-rw-r--r-- | mesonbuild/build.py | 21 | ||||
-rw-r--r-- | mesonbuild/utils/universal.py | 11 |
2 files changed, 12 insertions, 20 deletions
diff --git a/mesonbuild/build.py b/mesonbuild/build.py index b779237..3f35c31 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -36,7 +36,7 @@ from .mesonlib import ( extract_as_list, typeslistify, stringlistify, classify_unity_sources, get_filenames_templates_dict, substitute_values, has_path_sep, OptionKey, PerMachineDefaultable, OptionOverrideProxy, - MesonBugException, EnvironmentVariables + MesonBugException, EnvironmentVariables, pickle_load, ) from .compilers import ( is_object, clink_langs, sort_clink, all_languages, @@ -2900,24 +2900,11 @@ def get_sources_string_names(sources, backend): def load(build_dir: str) -> Build: filename = os.path.join(build_dir, 'meson-private', 'build.dat') - load_fail_msg = f'Build data file {filename!r} is corrupted. Try with a fresh build tree.' - nonexisting_fail_msg = f'No such build data file as "{filename!r}".' try: - with open(filename, 'rb') as f: - obj = pickle.load(f) + return pickle_load(filename, 'Build data', Build) except FileNotFoundError: - raise MesonException(nonexisting_fail_msg) - except (pickle.UnpicklingError, EOFError): - raise MesonException(load_fail_msg) - except AttributeError: - raise MesonException( - f"Build data file {filename!r} references functions or classes that don't " - "exist. This probably means that it was generated with an old " - "version of meson. Try running from the source directory " - f"meson setup {build_dir} --wipe") - if not isinstance(obj, Build): - raise MesonException(load_fail_msg) - return obj + raise MesonException(f'No such build data file as {filename!r}.') + def save(obj: Build, filename: str) -> None: with open(filename, 'wb') as f: diff --git a/mesonbuild/utils/universal.py b/mesonbuild/utils/universal.py index 570edd6..b1a301a 100644 --- a/mesonbuild/utils/universal.py +++ b/mesonbuild/utils/universal.py @@ -2289,16 +2289,21 @@ def pickle_load(filename: str, object_name: str, object_type: T.Type) -> T.Any: except (pickle.UnpicklingError, EOFError): raise MesonException(load_fail_msg) except (TypeError, ModuleNotFoundError, AttributeError): + build_dir = os.path.dirname(os.path.dirname(filename)) 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.") + "version of meson. Try running from the source directory " + f'meson setup {build_dir} --wipe') 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) + 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 |