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
This commit is contained in:
parent
3a4aa109b4
commit
0d3be23377
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue