From 8323001b01dacae3cef18a08dd606a2aea3a6a4e Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Thu, 6 Jul 2023 23:13:44 -0400 Subject: [PATCH] chore: use get_origin/get_args Signed-off-by: Henry Schreiner --- pyproject.toml | 2 +- src/scikit_build_core/_compat/typing.py | 11 +++++-- src/scikit_build_core/file_api/reply.py | 12 ++++--- src/scikit_build_core/settings/sources.py | 38 +++++++---------------- 4 files changed, 27 insertions(+), 36 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 97db23c06..7eb3dac73 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -235,7 +235,7 @@ exclude = [] "typing.Protocol".msg = "Use scikit_build_core._compat.typing.Protocol instead." "typing.Self".msg = "Use scikit_build_core._compat.typing.Self instead." "typing_extensions.Self".msg = "Use scikit_build_core._compat.typing.Self instead." -"typing.runtime_checkable".msg = "Use scikit_build_core._compat.typing.runtime_checkable instead." +"typing.runtime_checkable".msg = "Add and use scikit_build_core._compat.typing.runtime_checkable instead." "typing.Final".msg = "Add scikit_build_core._compat.typing.Final instead." "typing.NotRequired".msg = "Add scikit_build_core._compat.typing.NotRequired instead." "typing.OrderedDict".msg = "Add scikit_build_core._compat.typing.OrderedDict instead." diff --git a/src/scikit_build_core/_compat/typing.py b/src/scikit_build_core/_compat/typing.py index 3d4730e95..09d31a11f 100644 --- a/src/scikit_build_core/_compat/typing.py +++ b/src/scikit_build_core/_compat/typing.py @@ -4,9 +4,14 @@ import typing if sys.version_info < (3, 8): - from typing_extensions import Literal, Protocol, runtime_checkable + from typing_extensions import ( + Literal, + Protocol, + get_args, + get_origin, + ) else: - from typing import Literal, Protocol, runtime_checkable + from typing import Literal, Protocol, get_args, get_origin if sys.version_info < (3, 11): if typing.TYPE_CHECKING: @@ -16,7 +21,7 @@ else: from typing import Self -__all__ = ["Protocol", "runtime_checkable", "Literal", "Self"] +__all__ = ["Protocol", "Literal", "Self", "get_origin", "get_args"] def __dir__() -> list[str]: diff --git a/src/scikit_build_core/file_api/reply.py b/src/scikit_build_core/file_api/reply.py index 53eff80af..153bf9baf 100644 --- a/src/scikit_build_core/file_api/reply.py +++ b/src/scikit_build_core/file_api/reply.py @@ -6,6 +6,7 @@ from typing import Any, Callable, Dict, List, Type, TypeVar, Union # noqa: TID251 from .._compat.builtins import ExceptionGroup +from .._compat.typing import get_args, get_origin from .model.cache import Cache from .model.cmakefiles import CMakeFiles from .model.codemodel import CodeModel, Target @@ -88,11 +89,12 @@ def _convert_any(self, item: Any, target: Type[T]) -> T: if dataclasses.is_dataclass(target): # We don't have DataclassInstance exposed in typing yet return self.make_class(item, target) # type: ignore[return-value] - if hasattr(target, "__origin__"): - if target.__origin__ == list: # type: ignore[attr-defined] - return [self._convert_any(i, target.__args__[0]) for i in item] # type: ignore[return-value,attr-defined] - if target.__origin__ == Union: # type: ignore[attr-defined] - return self._convert_any(item, target.__args__[0]) # type: ignore[no-any-return,attr-defined] + origin = get_origin(target) + if origin is not None: + if origin == list: + return [self._convert_any(i, get_args(target)[0]) for i in item] # type: ignore[return-value] + if origin == Union: + return self._convert_any(item, get_args(target)[0]) # type: ignore[no-any-return] return target(item) # type: ignore[call-arg] diff --git a/src/scikit_build_core/settings/sources.py b/src/scikit_build_core/settings/sources.py index bd393e1ea..7019614b2 100644 --- a/src/scikit_build_core/settings/sources.py +++ b/src/scikit_build_core/settings/sources.py @@ -38,7 +38,7 @@ from typing import Any, TypeVar, Union from .._compat.builtins import ExceptionGroup -from .._compat.typing import Protocol, runtime_checkable +from .._compat.typing import Protocol, get_args, get_origin T = TypeVar("T") @@ -72,32 +72,20 @@ def _dig_fields(__opt: Any, *names: str) -> Any: return __opt -@runtime_checkable -class TypeLike(Protocol): - @property - def __origin__(self) -> Any: - ... - - @property - def __args__(self) -> list[Any]: - ... - - def _process_union(target: type[Any]) -> Any: """ Selects the non-None item in an Optional or Optional-like Union. Passes through non-Unions. """ - if ( - not isinstance(target, TypeLike) - or not hasattr(target, "__origin__") - or target.__origin__ is not Union - ): + origin = get_origin(target) + + if origin is None or origin is not Union: return target - if len(target.__args__) == 2: - items = list(target.__args__) + args = get_args(target) + if len(args) == 2: + items = list(args) if type(None) not in items: msg = f"None must be in union, got {items}" raise AssertionError(msg) @@ -115,10 +103,8 @@ def _get_target_raw_type(target: type[Any]) -> type[Any]: """ target = _process_union(target) - # The hasattr is required for Python 3.7, though not quite sure why - if isinstance(target, TypeLike) and hasattr(target, "__origin__"): - return target.__origin__ - return target + origin = get_origin(target) + return origin or target def _get_inner_type(__target: type[Any]) -> type[Any]: @@ -130,11 +116,9 @@ def _get_inner_type(__target: type[Any]) -> type[Any]: raw_target = _get_target_raw_type(__target) target = _process_union(__target) if raw_target == list: - assert isinstance(__target, TypeLike) - return target.__args__[0] + return get_args(target)[0] # type: ignore[no-any-return] if raw_target == dict: - assert isinstance(__target, TypeLike) - return target.__args__[1] + return get_args(target)[1] # type: ignore[no-any-return] msg = f"Expected a list or dict, got {target!r}" raise AssertionError(msg)