mirror of https://github.com/tiangolo/fastapi.git
Merge branch 'master' into master
This commit is contained in:
commit
7c46fe0363
|
|
@ -14,11 +14,13 @@ hide:
|
|||
|
||||
### Fixes
|
||||
|
||||
* 🐛 Fix TYPE_CHECKING annotations for Python 3.14 (PEP 649). PR [#14789](https://github.com/fastapi/fastapi/pull/14789) by [@mgu](https://github.com/mgu).
|
||||
* 🐛 Strip whitespaces from `Authorization` header credentials. PR [#14786](https://github.com/fastapi/fastapi/pull/14786) by [@WaveTheory1](https://github.com/WaveTheory1).
|
||||
* 🐛 Fix OpenAPI duplication of `anyOf` refs for app-level responses with specified `content` and `model` as `Union`. PR [#14463](https://github.com/fastapi/fastapi/pull/14463) by [@DJMcoder](https://github.com/DJMcoder).
|
||||
|
||||
### Refactors
|
||||
|
||||
* 🎨 Tweak types for mypy. PR [#14816](https://github.com/fastapi/fastapi/pull/14816) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 🏷️ Re-export `IncEx` type from Pydantic instead of duplicating it. PR [#14641](https://github.com/fastapi/fastapi/pull/14641) by [@mvanderlee](https://github.com/mvanderlee).
|
||||
* 💡 Update comment for Pydantic internals. PR [#14814](https://github.com/fastapi/fastapi/pull/14814) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -219,9 +219,9 @@ def jsonable_encoder(
|
|||
if isinstance(obj, encoder_type):
|
||||
return encoder_instance(obj)
|
||||
if include is not None and not isinstance(include, (set, dict)):
|
||||
include = set(include)
|
||||
include = set(include) # type: ignore[assignment]
|
||||
if exclude is not None and not isinstance(exclude, (set, dict)):
|
||||
exclude = set(exclude)
|
||||
exclude = set(exclude) # type: ignore[assignment]
|
||||
if isinstance(obj, BaseModel):
|
||||
obj_dict = obj.model_dump(
|
||||
mode="json",
|
||||
|
|
|
|||
|
|
@ -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