From 9d323020321893093492bc7d538c311c61398a1e Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Mon, 6 Mar 2023 11:24:10 -0800 Subject: [PATCH] interpreter: use typed_kwargs for shared_library(darwin_versions) --- mesonbuild/build.py | 47 +++---------------------- mesonbuild/interpreter/kwargs.py | 1 + mesonbuild/interpreter/type_checking.py | 44 +++++++++++++++++++++++ 3 files changed, 49 insertions(+), 43 deletions(-) diff --git a/mesonbuild/build.py b/mesonbuild/build.py index c1427be21..5b9d1525c 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -2141,7 +2141,7 @@ class SharedLibrary(BuildTarget): self.soversion: T.Optional[str] = None self.ltversion: T.Optional[str] = None # Max length 2, first element is compatibility_version, second is current_version - self.darwin_versions = [] + self.darwin_versions: T.Optional[T.Tuple[str, str]] = None self.vs_module_defs = None # The import library this target will generate self.import_filename = None @@ -2307,44 +2307,6 @@ class SharedLibrary(BuildTarget): if create_debug_file: self.debug_filename = os.path.splitext(self.filename)[0] + '.pdb' - @staticmethod - def _validate_darwin_versions(darwin_versions): - try: - if isinstance(darwin_versions, int): - darwin_versions = str(darwin_versions) - if isinstance(darwin_versions, str): - darwin_versions = 2 * [darwin_versions] - if not isinstance(darwin_versions, list): - raise InvalidArguments('Shared library darwin_versions: must be a string, integer,' - f'or a list, not {darwin_versions!r}') - if len(darwin_versions) > 2: - raise InvalidArguments('Shared library darwin_versions: list must contain 2 or fewer elements') - if len(darwin_versions) == 1: - darwin_versions = 2 * darwin_versions - for i, v in enumerate(darwin_versions[:]): - if isinstance(v, int): - v = str(v) - if not isinstance(v, str): - raise InvalidArguments('Shared library darwin_versions: list elements ' - f'must be strings or integers, not {v!r}') - if not re.fullmatch(r'[0-9]+(\.[0-9]+){0,2}', v): - raise InvalidArguments('Shared library darwin_versions: must be X.Y.Z where ' - 'X, Y, Z are numbers, and Y and Z are optional') - parts = v.split('.') - if len(parts) in {1, 2, 3} and int(parts[0]) > 65535: - raise InvalidArguments('Shared library darwin_versions: must be X.Y.Z ' - 'where X is [0, 65535] and Y, Z are optional') - if len(parts) in {2, 3} and int(parts[1]) > 255: - raise InvalidArguments('Shared library darwin_versions: must be X.Y.Z ' - 'where Y is [0, 255] and Y, Z are optional') - if len(parts) == 3 and int(parts[2]) > 255: - raise InvalidArguments('Shared library darwin_versions: must be X.Y.Z ' - 'where Z is [0, 255] and Y, Z are optional') - darwin_versions[i] = v - except ValueError: - raise InvalidArguments('Shared library darwin_versions: value is invalid') - return darwin_versions - def process_kwargs(self, kwargs): super().process_kwargs(kwargs) @@ -2358,11 +2320,10 @@ class SharedLibrary(BuildTarget): # number of the version by default. self.soversion = self.ltversion.split('.')[0] # macOS, iOS and tvOS dylib compatibility_version and current_version - if 'darwin_versions' in kwargs: - self.darwin_versions = self._validate_darwin_versions(kwargs['darwin_versions']) - elif self.soversion: + self.darwin_versions = T.cast('T.Optional[T.Tuple[str, str]]', kwargs.get('darwin_versions')) + if self.darwin_versions is None and self.soversion is not None: # If unspecified, pick the soversion - self.darwin_versions = 2 * [self.soversion] + self.darwin_versions = (self.soversion, self.soversion) # Visual Studio module-definitions file if 'vs_module_defs' in kwargs: diff --git a/mesonbuild/interpreter/kwargs.py b/mesonbuild/interpreter/kwargs.py index c46328837..af5733f4e 100644 --- a/mesonbuild/interpreter/kwargs.py +++ b/mesonbuild/interpreter/kwargs.py @@ -340,6 +340,7 @@ class StaticLibrary(_BuildTarget): class _SharedLibMixin(TypedDict): + darwin_versions: T.Optional[T.Tuple[str, str]] soversion: T.Optional[str] version: T.Optional[str] diff --git a/mesonbuild/interpreter/type_checking.py b/mesonbuild/interpreter/type_checking.py index 87a4d439e..28c915295 100644 --- a/mesonbuild/interpreter/type_checking.py +++ b/mesonbuild/interpreter/type_checking.py @@ -504,6 +504,49 @@ def _validate_win_subsystem(value: T.Optional[str]) -> T.Optional[str]: return f'Invalid value for win_subsystem: {value}.' return None + +def _validate_darwin_versions(darwin_versions: T.List[T.Union[str, int]]) -> T.Optional[str]: + if len(darwin_versions) > 2: + return f"Must contain between 0 and 2 elements, not {len(darwin_versions)}" + if len(darwin_versions) == 1: + darwin_versions = 2 * darwin_versions + for v in darwin_versions: + if isinstance(v, int): + v = str(v) + if not re.fullmatch(r'[0-9]+(\.[0-9]+){0,2}', v): + return 'must be X.Y.Z where X, Y, Z are numbers, and Y and Z are optional' + try: + parts = v.split('.') + except ValueError: + return f'badly formed value: "{v}, not in X.Y.Z form' + if len(parts) in {1, 2, 3} and int(parts[0]) > 65535: + return 'must be X.Y.Z where X is [0, 65535] and Y, Z are optional' + if len(parts) in {2, 3} and int(parts[1]) > 255: + return 'must be X.Y.Z where Y is [0, 255] and Y, Z are optional' + if len(parts) == 3 and int(parts[2]) > 255: + return 'must be X.Y.Z where Z is [0, 255] and Y, Z are optional' + return None + + +def _convert_darwin_versions(val: T.List[T.Union[str, int]]) -> T.Optional[T.Tuple[str, str]]: + if not val: + return None + elif len(val) == 1: + v = str(val[0]) + return (v, v) + return (str(val[0]), str(val[1])) + + +_DARWIN_VERSIONS_KW: KwargInfo[T.List[T.Union[str, int]]] = KwargInfo( + 'darwin_versions', + ContainerTypeInfo(list, (str, int)), + default=[], + listify=True, + validator=_validate_darwin_versions, + convertor=_convert_darwin_versions, + since='0.48.0', +) + # Arguments exclusive to Executable. These are separated to make integrating # them into build_target easier _EXCLUSIVE_EXECUTABLE_KWS: T.List[KwargInfo] = [ @@ -535,6 +578,7 @@ STATIC_LIB_KWS = [ # Arguments exclusive to SharedLibrary. These are separated to make integrating # them into build_target easier _EXCLUSIVE_SHARED_LIB_KWS: T.List[KwargInfo] = [ + _DARWIN_VERSIONS_KW, KwargInfo('soversion', (str, int, NoneType), convertor=lambda x: str(x) if x is not None else None), KwargInfo('version', (str, NoneType), validator=_validate_shlib_version) ]