diff --git a/githubkit/compat.py b/githubkit/compat.py index 67b4ed47e..591c2f247 100644 --- a/githubkit/compat.py +++ b/githubkit/compat.py @@ -1,5 +1,6 @@ from collections.abc import Generator -from typing import TYPE_CHECKING, Any, Callable, Protocol, TypeVar, overload +from typing import TYPE_CHECKING, Any, Callable, Protocol, TypeVar +from typing_extensions import TypeForm from pydantic import VERSION @@ -36,24 +37,10 @@ class GitHubModel(BaseModel): class ExtraGitHubModel(GitHubModel): model_config = ConfigDict(extra="allow") - # Remove the overload once [PEP747](https://peps.python.org/pep-0747/) is accepted - # We should use TypeForm here - @overload - def type_validate_python(type_: type[T], data: Any) -> T: ... - - @overload - def type_validate_python(type_: Any, data: Any) -> Any: ... - - def type_validate_python(type_: type[T], data: Any) -> T: + def type_validate_python(type_: TypeForm[T], data: Any) -> T: return TypeAdapter(type_).validate_python(data) - @overload - def type_validate_json(type_: type[T], data: Any) -> T: ... - - @overload - def type_validate_json(type_: Any, data: Any) -> Any: ... - - def type_validate_json(type_: type[T], data: Any) -> T: + def type_validate_json(type_: TypeForm[T], data: Any) -> T: return TypeAdapter(type_).validate_json(data) def model_dump(model: BaseModel, by_alias: bool = True) -> dict[str, Any]: @@ -97,22 +84,10 @@ class ExtraGitHubModel(BaseModel): class Config: extra = Extra.allow - @overload - def type_validate_python(type_: type[T], data: Any) -> T: ... - - @overload - def type_validate_python(type_: Any, data: Any) -> Any: ... - - def type_validate_python(type_: type[T], data: Any) -> T: + def type_validate_python(type_: TypeForm[T], data: Any) -> T: return parse_obj_as(type_, data) - @overload - def type_validate_json(type_: type[T], data: Any) -> T: ... - - @overload - def type_validate_json(type_: Any, data: Any) -> Any: ... - - def type_validate_json(type_: type[T], data: Any) -> T: + def type_validate_json(type_: TypeForm[T], data: Any) -> T: return parse_raw_as(type_, data) def to_jsonable_python(obj: Any) -> Any: diff --git a/githubkit/core.py b/githubkit/core.py index 9da5cf316..954917487 100644 --- a/githubkit/core.py +++ b/githubkit/core.py @@ -387,12 +387,16 @@ async def _arequest( raise RequestError(e) from e # check and parse response + def _check_is_error(self, response: httpx.Response) -> bool: + """Check if the response is an error.""" + return response.is_error + @overload def _check( self, response: httpx.Response, response_model: type[T], - error_models: Optional[Mapping[str, type]] = None, + error_models: Optional[Mapping[str, Any]] = None, ) -> Response[T]: ... @overload @@ -400,13 +404,9 @@ def _check( self, response: httpx.Response, response_model: UnsetType = UNSET, - error_models: Optional[Mapping[str, type]] = None, + error_models: Optional[Mapping[str, Any]] = None, ) -> Response[Any]: ... - def _check_is_error(self, response: httpx.Response) -> bool: - """Check if the response is an error.""" - return response.is_error - def _check( self, response: httpx.Response, diff --git a/githubkit/utils.py b/githubkit/utils.py index 84ce5e0a2..c9c7f9c8b 100644 --- a/githubkit/utils.py +++ b/githubkit/utils.py @@ -1,7 +1,8 @@ from enum import Enum from functools import partial import inspect -from typing import Any, Generic, Literal, Optional, TypeVar, final, overload +from typing import Any, Generic, Literal, Optional, TypeVar, final +from typing_extensions import TypeForm from hishel._utils import generate_key import httpcore @@ -98,13 +99,7 @@ def parse_query_params(params: dict[str, Any]) -> dict[str, Any]: class TaggedUnion(Generic[T]): __slots__ = ("discriminator", "tag", "type_") - @overload - def __init__(self, type_: type[T], discriminator: str, tag: str) -> None: ... - - @overload - def __init__(self, type_: Any, discriminator: str, tag: str) -> None: ... - - def __init__(self, type_: type[T], discriminator: str, tag: str) -> None: + def __init__(self, type_: TypeForm[T], discriminator: str, tag: str) -> None: self.type_ = type_ self.discriminator = discriminator self.tag = tag diff --git a/pyproject.toml b/pyproject.toml index fa2b7c487..a497d1698 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ dependencies = [ "anyio >=3.6.1, <5.0.0", "httpx >=0.23.0, <1.0.0", "hishel >=0.0.21, <=0.2.0", - "typing-extensions >=4.11.0, <5.0.0", + "typing-extensions >=4.13.0, <5.0.0", "pydantic >=1.9.1, <3.0.0, !=2.5.0, !=2.5.1", ] @@ -150,6 +150,8 @@ typeCheckingMode = "standard" reportPrivateImportUsage = false reportShadowedImports = false disableBytesTypePromotions = true +# enable PEP 747 `TypeForm` check +enableExperimentalFeatures = true pythonPlatform = "All" defineConstant = { PYDANTIC_V2 = true } diff --git a/uv.lock b/uv.lock index fa35852d1..22c6ba2f2 100644 --- a/uv.lock +++ b/uv.lock @@ -875,7 +875,7 @@ requires-dist = [ { name = "pyjwt", extras = ["crypto"], marker = "extra == 'auth'", specifier = ">=2.4.0,<3.0.0" }, { name = "pyjwt", extras = ["crypto"], marker = "extra == 'auth-app'", specifier = ">=2.4.0,<3.0.0" }, { name = "pyjwt", extras = ["crypto"], marker = "extra == 'jwt'", specifier = ">=2.4.0,<3.0.0" }, - { name = "typing-extensions", specifier = ">=4.11.0,<5.0.0" }, + { name = "typing-extensions", specifier = ">=4.13.0,<5.0.0" }, ] provides-extras = ["jwt", "auth-app", "auth-oauth-device", "auth", "all"]