mirror of https://github.com/tiangolo/fastapi.git
Merge c940ab7197 into da4135ce1e
This commit is contained in:
commit
dcb8eb8877
|
|
@ -329,6 +329,7 @@ def get_dependant(
|
|||
def add_non_field_param_to_dependency(
|
||||
*, param_name: str, type_annotation: Any, dependant: Dependant
|
||||
) -> bool | None:
|
||||
type_annotation = get_origin(type_annotation) or type_annotation
|
||||
if lenient_issubclass(type_annotation, Request):
|
||||
dependant.request_param_name = param_name
|
||||
return True
|
||||
|
|
@ -453,7 +454,7 @@ def analyze_param(
|
|||
# Only apply special handling when there's no explicit Depends - if there's a Depends,
|
||||
# the dependency will be called and its return value used instead of the special injection
|
||||
if depends is None and lenient_issubclass(
|
||||
type_annotation,
|
||||
get_origin(type_annotation) or type_annotation,
|
||||
(
|
||||
Request,
|
||||
WebSocket,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
from collections.abc import AsyncGenerator
|
||||
from contextlib import asynccontextmanager
|
||||
from typing import TypedDict
|
||||
|
||||
import pytest
|
||||
from fastapi import APIRouter, FastAPI, Request
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel
|
||||
from starlette import __version__ as STARLETTE_VERSION
|
||||
from typing_extensions import Self
|
||||
|
||||
STARLETTE_MINOR_VERSION_TUPLE = tuple(int(x) for x in STARLETTE_VERSION.split(".")[:2])
|
||||
|
||||
|
||||
class State(BaseModel):
|
||||
|
|
@ -171,6 +176,39 @@ def test_router_nested_lifespan_state(state: State) -> None:
|
|||
assert state.sub_router_shutdown is True
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
STARLETTE_MINOR_VERSION_TUPLE < (0, 52),
|
||||
reason="Starlette Request with generic type is not supported in Starlette < 0.52.0",
|
||||
)
|
||||
def test_router_generic_request_typed_dict_lifespan_state() -> None:
|
||||
class MyClass:
|
||||
async def __aenter__(self) -> Self:
|
||||
return self
|
||||
|
||||
async def __aexit__(self, exc_type, exc_value, traceback) -> None:
|
||||
pass
|
||||
|
||||
class MyState(TypedDict):
|
||||
my_class: MyClass
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI) -> AsyncGenerator[MyState]:
|
||||
async with MyClass() as my_class:
|
||||
yield {"my_class": my_class}
|
||||
|
||||
app = FastAPI(lifespan=lifespan)
|
||||
|
||||
@app.get("/")
|
||||
def main(request: Request[MyState]) -> dict[str, str]:
|
||||
assert isinstance(request.state["my_class"], MyClass)
|
||||
return {"message": "Hello World"}
|
||||
|
||||
with TestClient(app) as client:
|
||||
response = client.get("/")
|
||||
assert response.status_code == 200, response.text
|
||||
assert response.json() == {"message": "Hello World"}
|
||||
|
||||
|
||||
def test_router_nested_lifespan_state_overriding_by_parent() -> None:
|
||||
@asynccontextmanager
|
||||
async def lifespan(
|
||||
|
|
|
|||
Loading…
Reference in New Issue