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,
|
extract_as_list, typeslistify, stringlistify, classify_unity_sources,
|
||||||
get_filenames_templates_dict, substitute_values, has_path_sep,
|
get_filenames_templates_dict, substitute_values, has_path_sep,
|
||||||
OptionKey, PerMachineDefaultable, OptionOverrideProxy,
|
OptionKey, PerMachineDefaultable, OptionOverrideProxy,
|
||||||
MesonBugException, EnvironmentVariables
|
MesonBugException, EnvironmentVariables, pickle_load,
|
||||||
)
|
)
|
||||||
from .compilers import (
|
from .compilers import (
|
||||||
is_object, clink_langs, sort_clink, all_languages,
|
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:
|
def load(build_dir: str) -> Build:
|
||||||
filename = os.path.join(build_dir, 'meson-private', 'build.dat')
|
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:
|
try:
|
||||||
with open(filename, 'rb') as f:
|
return pickle_load(filename, 'Build data', Build)
|
||||||
obj = pickle.load(f)
|
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
raise MesonException(nonexisting_fail_msg)
|
raise MesonException(f'No such build data file as {filename!r}.')
|
||||||
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
|
|
||||||
|
|
||||||
def save(obj: Build, filename: str) -> None:
|
def save(obj: Build, filename: str) -> None:
|
||||||
with open(filename, 'wb') as f:
|
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):
|
except (pickle.UnpicklingError, EOFError):
|
||||||
raise MesonException(load_fail_msg)
|
raise MesonException(load_fail_msg)
|
||||||
except (TypeError, ModuleNotFoundError, AttributeError):
|
except (TypeError, ModuleNotFoundError, AttributeError):
|
||||||
|
build_dir = os.path.dirname(os.path.dirname(filename))
|
||||||
raise MesonException(
|
raise MesonException(
|
||||||
f"{object_name} file {filename!r} references functions or classes that don't "
|
f"{object_name} file {filename!r} references functions or classes that don't "
|
||||||
"exist. This probably means that it was generated with an old "
|
"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):
|
if not isinstance(obj, object_type):
|
||||||
raise MesonException(load_fail_msg)
|
raise MesonException(load_fail_msg)
|
||||||
from ..coredata import version as coredata_version
|
from ..coredata import version as coredata_version
|
||||||
from ..coredata import major_versions_differ, MesonVersionMismatchException
|
from ..coredata import major_versions_differ, MesonVersionMismatchException
|
||||||
if major_versions_differ(obj.version, coredata_version):
|
version = getattr(obj, 'version', None)
|
||||||
raise MesonVersionMismatchException(obj.version, coredata_version)
|
if version is None:
|
||||||
|
version = obj.environment.coredata.version
|
||||||
|
if major_versions_differ(version, coredata_version):
|
||||||
|
raise MesonVersionMismatchException(version, coredata_version)
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue