Browse Source

Update tests

pull/14099/head
Sebastián Ramírez 3 days ago
parent
commit
50fb38d20e
  1. 41
      fastapi/routing.py
  2. 2
      tests/test_tutorial/test_dependencies/test_tutorial008c.py

41
fastapi/routing.py

@ -1,5 +1,6 @@
import dataclasses import dataclasses
import email.message import email.message
import functools
import inspect import inspect
import json import json
import sys import sys
@ -8,6 +9,7 @@ from enum import Enum, IntEnum
from typing import ( from typing import (
Any, Any,
AsyncIterator, AsyncIterator,
Awaitable,
Callable, Callable,
Collection, Collection,
Coroutine, Coroutine,
@ -59,6 +61,8 @@ from fastapi.utils import (
) )
from pydantic import BaseModel from pydantic import BaseModel
from starlette import routing from starlette import routing
from starlette._exception_handler import wrap_app_handling_exceptions
from starlette._utils import is_async_callable
from starlette.concurrency import run_in_threadpool from starlette.concurrency import run_in_threadpool
from starlette.exceptions import HTTPException from starlette.exceptions import HTTPException
from starlette.requests import Request from starlette.requests import Request
@ -68,11 +72,9 @@ from starlette.routing import (
Match, Match,
compile_path, compile_path,
get_name, get_name,
request_response,
websocket_session,
) )
from starlette.routing import Mount as Mount # noqa from starlette.routing import Mount as Mount # noqa
from starlette.types import AppType, ASGIApp, Lifespan, Scope from starlette.types import AppType, ASGIApp, Lifespan, Receive, Scope, Send
from starlette.websockets import WebSocket from starlette.websockets import WebSocket
from typing_extensions import Annotated, Doc, deprecated from typing_extensions import Annotated, Doc, deprecated
@ -246,7 +248,12 @@ def get_request_handler(
async def app(request: Request) -> Response: async def app(request: Request) -> Response:
response: Union[Response, None] = None response: Union[Response, None] = None
async with AsyncExitStack() as file_stack: file_stack = request.scope.get("fastapi_middleware_astack")
assert isinstance(
file_stack, AsyncExitStack
), "fastapi_astack not found in request scope"
# Read body and auto-close files
try: try:
body: Any = None body: Any = None
if body_field: if body_field:
@ -293,8 +300,13 @@ def get_request_handler(
status_code=400, detail="There was an error parsing the body" status_code=400, detail="There was an error parsing the body"
) )
raise http_error from e raise http_error from e
# Solve dependencies and run path operation function, auto-closing dependencies
errors: List[Any] = [] errors: List[Any] = []
async with AsyncExitStack() as async_exit_stack: async_exit_stack = request.scope.get("fastapi_inner_astack")
assert isinstance(
async_exit_stack, AsyncExitStack
), "fastapi_inner_astack not found in request scope"
solved_result = await solve_dependencies( solved_result = await solve_dependencies(
request=request, request=request,
dependant=dependant, dependant=dependant,
@ -321,16 +333,12 @@ def get_request_handler(
# If status_code was set, use it, otherwise use the default from the # If status_code was set, use it, otherwise use the default from the
# response class, in the case of redirect it's 307 # response class, in the case of redirect it's 307
current_status_code = ( current_status_code = (
status_code status_code if status_code else solved_result.response.status_code
if status_code
else solved_result.response.status_code
) )
if current_status_code is not None: if current_status_code is not None:
response_args["status_code"] = current_status_code response_args["status_code"] = current_status_code
if solved_result.response.status_code: if solved_result.response.status_code:
response_args["status_code"] = ( response_args["status_code"] = solved_result.response.status_code
solved_result.response.status_code
)
content = await serialize_response( content = await serialize_response(
field=response_field, field=response_field,
response_content=raw_response, response_content=raw_response,
@ -351,6 +359,8 @@ def get_request_handler(
_normalize_errors(errors), body=body _normalize_errors(errors), body=body
) )
raise validation_error raise validation_error
# Return response
if response is None: if response is None:
raise FastAPIError( raise FastAPIError(
"No response object was returned. There's a high chance that the " "No response object was returned. There's a high chance that the "
@ -370,11 +380,10 @@ def get_websocket_app(
embed_body_fields: bool = False, embed_body_fields: bool = False,
) -> Callable[[WebSocket], Coroutine[Any, Any, Any]]: ) -> Callable[[WebSocket], Coroutine[Any, Any, Any]]:
async def app(websocket: WebSocket) -> None: async def app(websocket: WebSocket) -> None:
async with AsyncExitStack() as async_exit_stack: async_exit_stack = websocket.scope.get("fastapi_inner_astack")
# TODO: remove this scope later, after a few releases assert isinstance(
# This scope fastapi_astack is no longer used by FastAPI, kept for async_exit_stack, AsyncExitStack
# compatibility, just in case ), "fastapi_inner_astack not found in request scope"
websocket.scope["fastapi_astack"] = async_exit_stack
solved_result = await solve_dependencies( solved_result = await solve_dependencies(
request=websocket, request=websocket,
dependant=dependant, dependant=dependant,

2
tests/test_tutorial/test_dependencies/test_tutorial008c.py

@ -40,7 +40,7 @@ def test_fastapi_error(mod: ModuleType):
client = TestClient(mod.app) client = TestClient(mod.app)
with pytest.raises(FastAPIError) as exc_info: with pytest.raises(FastAPIError) as exc_info:
client.get("/items/portal-gun") client.get("/items/portal-gun")
assert "No response object was returned" in exc_info.value.args[0] assert "raising an exception and a dependency with yield" in exc_info.value.args[0]
def test_internal_server_error(mod: ModuleType): def test_internal_server_error(mod: ModuleType):

Loading…
Cancel
Save