mirror of https://github.com/tiangolo/fastapi.git
🐛 Fix TYPE_CHECKING annotations for Python 3.14 (PEP 649) (#14789)
This commit is contained in:
parent
c944add5a9
commit
09f5941f0e
|
|
@ -204,7 +204,12 @@ def _get_signature(call: Callable[..., Any]) -> inspect.Signature:
|
|||
except NameError:
|
||||
# Handle type annotations with if TYPE_CHECKING, not used by FastAPI
|
||||
# e.g. dependency return types
|
||||
signature = inspect.signature(call)
|
||||
if sys.version_info >= (3, 14):
|
||||
from annotationlib import Format
|
||||
|
||||
signature = inspect.signature(call, annotation_format=Format.FORWARDREF)
|
||||
else:
|
||||
signature = inspect.signature(call)
|
||||
else:
|
||||
signature = inspect.signature(call)
|
||||
return signature
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
from typing import TYPE_CHECKING, Annotated
|
||||
|
||||
from fastapi import Depends, FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from .utils import needs_py314
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
|
||||
class DummyUser: ...
|
||||
|
||||
|
||||
@needs_py314
|
||||
def test_stringified_annotation():
|
||||
# python3.14: Use forward reference without "from __future__ import annotations"
|
||||
async def get_current_user() -> DummyUser | None:
|
||||
return None
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
client = TestClient(app)
|
||||
|
||||
@app.get("/")
|
||||
async def get(
|
||||
current_user: Annotated[DummyUser | None, Depends(get_current_user)],
|
||||
) -> str:
|
||||
return "hello world"
|
||||
|
||||
response = client.get("/")
|
||||
assert response.status_code == 200
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
import importlib
|
||||
import sys
|
||||
from types import ModuleType
|
||||
from typing import Annotated, Any
|
||||
from unittest.mock import Mock, patch
|
||||
|
|
@ -12,8 +13,13 @@ from fastapi.testclient import TestClient
|
|||
name="module",
|
||||
params=[
|
||||
"tutorial008_py39",
|
||||
# Fails with `NameError: name 'DepA' is not defined`
|
||||
pytest.param("tutorial008_an_py39", marks=pytest.mark.xfail),
|
||||
pytest.param(
|
||||
"tutorial008_an_py39",
|
||||
marks=pytest.mark.xfail(
|
||||
sys.version_info < (3, 14),
|
||||
reason="Fails with `NameError: name 'DepA' is not defined`",
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
def get_module(request: pytest.FixtureRequest):
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ needs_py39 = pytest.mark.skipif(sys.version_info < (3, 9), reason="requires pyth
|
|||
needs_py310 = pytest.mark.skipif(
|
||||
sys.version_info < (3, 10), reason="requires python3.10+"
|
||||
)
|
||||
needs_py_lt_314 = pytest.mark.skipif(
|
||||
sys.version_info >= (3, 14), reason="requires python3.13-"
|
||||
needs_py314 = pytest.mark.skipif(
|
||||
sys.version_info < (3, 14), reason="requires python3.14+"
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue