Skip to content

Commit 02a4d8b

Browse files
committed
Vendor a copy of is_typealiastype from typing-inspection
1 parent 1182644 commit 02a4d8b

File tree

5 files changed

+34
-19
lines changed

5 files changed

+34
-19
lines changed

fastapi/dependencies/utils.py

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import inspect
2+
import sys
3+
import typing
24
from contextlib import AsyncExitStack, contextmanager
35
from copy import copy, deepcopy
46
from dataclasses import dataclass
@@ -19,6 +21,7 @@
1921
)
2022

2123
import anyio
24+
import typing_extensions
2225
from fastapi import params
2326
from fastapi._compat import (
2427
PYDANTIC_V2,
@@ -71,13 +74,12 @@
7174
from starlette.requests import HTTPConnection, Request
7275
from starlette.responses import Response
7376
from starlette.websockets import WebSocket
74-
from typing_extensions import Annotated, get_args, get_origin
77+
from typing_extensions import Annotated, TypeAliasType, TypeGuard, get_args, get_origin
7578

7679
try:
77-
from typing_extensions import TypeAliasType
80+
from types import GenericAlias
7881
except ImportError: # pragma: no cover
79-
TypeAliasType = None # type: ignore[misc,assignment]
80-
82+
GenericAlias = None # type: ignore[misc,assignment]
8183

8284
multipart_not_installed_error = (
8385
'Form data requires "python-multipart" to be installed. \n'
@@ -362,7 +364,7 @@ def analyze_param(
362364
depends = None
363365
type_annotation: Any = Any
364366
use_annotation: Any = Any
365-
if TypeAliasType is not None and isinstance(annotation, TypeAliasType):
367+
if _is_typealiastype(annotation):
366368
# unpack in case py3.12 type syntax is used
367369
annotation = annotation.__value__
368370
if annotation is not inspect.Signature.empty:
@@ -1008,3 +1010,26 @@ def get_body_field(
10081010
field_info=BodyFieldInfo(**BodyFieldInfo_kwargs),
10091011
)
10101012
return final_field
1013+
1014+
1015+
def _is_typealiastype(tp: Any, /) -> TypeGuard[TypeAliasType]:
1016+
in_typing = hasattr(typing, "TypeAliasType")
1017+
in_typing_extensions = hasattr(typing_extensions, "TypeAliasType")
1018+
is_typealiastype = False
1019+
if in_typing and in_typing_extensions:
1020+
if getattr(typing, "TypeAliasType", None) is getattr(
1021+
typing_extensions, "TypeAliasType", None
1022+
):
1023+
is_typealiastype = isinstance(tp, typing.TypeAliasType) # type: ignore [attr-defined]
1024+
else:
1025+
is_typealiastype = isinstance(
1026+
tp,
1027+
(typing.TypeAliasType, typing_extensions.TypeAliasType), # type: ignore [attr-defined]
1028+
)
1029+
elif in_typing and not in_typing_extensions:
1030+
is_typealiastype = isinstance(tp, typing.TypeAliasType) # type: ignore [attr-defined]
1031+
elif not in_typing and in_typing_extensions:
1032+
is_typealiastype = isinstance(tp, typing_extensions.TypeAliasType)
1033+
if sys.version_info[:2] == (3, 10):
1034+
return type(tp) is not GenericAlias and is_typealiastype
1035+
return is_typealiastype

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,6 @@ dynamic_context = "test_function"
199199
omit = [
200200
"docs_src/response_model/tutorial003_04.py",
201201
"docs_src/response_model/tutorial003_04_py310.py",
202-
"tests/test_dependency_pep695_py312.py" # syntax error for version < py312
203202
]
204203

205204
[tool.coverage.report]

tests/conftest.py

Lines changed: 0 additions & 4 deletions
This file was deleted.

tests/test_dependency_pep695_py312.py renamed to tests/test_dependency_pep695.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
from __future__ import annotations
22

3-
from typing import Annotated
4-
53
from fastapi import Depends, FastAPI
64
from fastapi.testclient import TestClient
7-
8-
from .utils import needs_py312
5+
from typing_extensions import Annotated, TypeAliasType
96

107

118
async def some_value() -> int:
129
return 123
1310

1411

15-
type DependedValue = Annotated[int, Depends(some_value)]
12+
DependedValue = TypeAliasType(
13+
"DependedValue", Annotated[int, Depends(some_value)], type_params=()
14+
)
1615

1716

18-
@needs_py312
1917
def test_pep695_type_dependencies():
2018
app = FastAPI()
2119

tests/utils.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@
88
needs_py310 = pytest.mark.skipif(
99
sys.version_info < (3, 10), reason="requires python3.10+"
1010
)
11-
needs_py312 = pytest.mark.skipif(
12-
sys.version_info < (3, 12), reason="requires python3.12+"
13-
)
1411
needs_pydanticv2 = pytest.mark.skipif(not PYDANTIC_V2, reason="requires Pydantic v2")
1512
needs_pydanticv1 = pytest.mark.skipif(PYDANTIC_V2, reason="requires Pydantic v1")
1613

0 commit comments

Comments
 (0)