]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
✨ Add support for PEP695 `TypeAliasType` (#13920)
authorAlbin Skott <cstruct@users.noreply.github.com>
Thu, 5 Feb 2026 18:34:34 +0000 (19:34 +0100)
committerGitHub <noreply@github.com>
Thu, 5 Feb 2026 18:34:34 +0000 (18:34 +0000)
Co-authored-by: lokidev <torsten.zielke@protonmail.com>
Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Yurii Motov <yurii.motov.monte@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
fastapi/dependencies/utils.py
pyproject.toml
tests/test_dependency_pep695.py [new file with mode: 0644]
uv.lock

index 3037b233b9ca1af031cf7e3d6f3acf28ac3961fe..e5ac51d53c8ecfe41b5c3724e91c72087829cd03 100644 (file)
@@ -66,6 +66,7 @@ from starlette.requests import HTTPConnection, Request
 from starlette.responses import Response
 from starlette.websockets import WebSocket
 from typing_extensions import Literal, get_args, get_origin
+from typing_inspection.typing_objects import is_typealiastype
 
 multipart_not_installed_error = (
     'Form data requires "python-multipart" to be installed. \n'
@@ -370,6 +371,9 @@ def analyze_param(
     depends = None
     type_annotation: Any = Any
     use_annotation: Any = Any
+    if is_typealiastype(annotation):
+        # unpack in case PEP 695 type syntax is used
+        annotation = annotation.__value__
     if annotation is not inspect.Signature.empty:
         use_annotation = annotation
         type_annotation = annotation
index 0f6bf1e4ac1b4f81dca16352115641bd4ace0ddd..e62baa5f8514014cfc60cb151894cd6d1b1b4efc 100644 (file)
@@ -46,6 +46,7 @@ dependencies = [
     "starlette>=0.40.0,<0.51.0",
     "pydantic>=2.7.0",
     "typing-extensions>=4.8.0",
+    "typing-inspection>=0.4.2",
     "annotated-doc>=0.0.2",
 ]
 
diff --git a/tests/test_dependency_pep695.py b/tests/test_dependency_pep695.py
new file mode 100644 (file)
index 0000000..ef56366
--- /dev/null
@@ -0,0 +1,27 @@
+from typing import Annotated
+
+from fastapi import Depends, FastAPI
+from fastapi.testclient import TestClient
+from typing_extensions import TypeAliasType
+
+
+async def some_value() -> int:
+    return 123
+
+
+DependedValue = TypeAliasType(
+    "DependedValue", Annotated[int, Depends(some_value)], type_params=()
+)
+
+
+def test_pep695_type_dependencies():
+    app = FastAPI()
+
+    @app.get("/")
+    async def get_with_dep(value: DependedValue) -> str:  # noqa
+        return f"value: {value}"
+
+    client = TestClient(app)
+    response = client.get("/")
+    assert response.status_code == 200
+    assert response.text == '"value: 123"'
diff --git a/uv.lock b/uv.lock
index 931a27021baba858013ac992f185716097f46a99..db5d2e9b1a86ea51be5fa73f9bf110fde4b2cf38 100644 (file)
--- a/uv.lock
+++ b/uv.lock
@@ -1021,6 +1021,7 @@ dependencies = [
     { name = "starlette", version = "0.49.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
     { name = "starlette", version = "0.50.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
     { name = "typing-extensions" },
+    { name = "typing-inspection" },
 ]
 
 [package.optional-dependencies]
@@ -1202,6 +1203,7 @@ requires-dist = [
     { name = "pyyaml", marker = "extra == 'all'", specifier = ">=5.3.1" },
     { name = "starlette", specifier = ">=0.40.0,<0.51.0" },
     { name = "typing-extensions", specifier = ">=4.8.0" },
+    { name = "typing-inspection", specifier = ">=0.4.2" },
     { name = "ujson", marker = "extra == 'all'", specifier = ">=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0" },
     { name = "uvicorn", extras = ["standard"], marker = "extra == 'all'", specifier = ">=0.12.0" },
     { name = "uvicorn", extras = ["standard"], marker = "extra == 'standard'", specifier = ">=0.12.0" },