Skip to content

Feature: use PEP 747 TypeForm for internal converters #234

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 6 additions & 31 deletions githubkit/compat.py
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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]:
Expand Down Expand Up @@ -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:
Expand Down
12 changes: 6 additions & 6 deletions githubkit/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,26 +354,26 @@ 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
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,
Expand Down
11 changes: 3 additions & 8 deletions githubkit/utils.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -85,13 +86,7 @@ def is_async(obj: Any) -> bool:
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
Expand Down
4 changes: 3 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
]

Expand Down Expand Up @@ -147,6 +147,8 @@ typeCheckingMode = "standard"
reportPrivateImportUsage = false
reportShadowedImports = false
disableBytesTypePromotions = true
# enable PEP 747 `TypeForm` check
enableExperimentalFeatures = true

pythonPlatform = "All"
defineConstant = { PYDANTIC_V2 = true }
Expand Down
Loading
Loading