Skip to content

Commit

Permalink
Define strict return value typing for Depends and Security
Browse files Browse the repository at this point in the history
Depends can be used with a direct form, which although not recommended, is
still supported. The following code is problematic wrt. type checking.

    def dependency() -> str:
        return "dependency"

    @router.get("/")
    def endpoint(value: int = Depends(dependency)):
      pass

Currently, `Depends(dependency)` returns Any, which then happily gets assigned
to the int. This patch changes it to return a type matching what the dependency
returns, making the above code fail type checking with mypy as it should.
  • Loading branch information
JaniM committed Mar 7, 2024
1 parent eef1b7d commit 4082cdb
Showing 1 changed file with 16 additions and 7 deletions.
23 changes: 16 additions & 7 deletions fastapi/param_functions.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Callable, Dict, List, Optional, Sequence, Union
from typing import Any, Callable, Dict, List, Optional, Sequence, TypeVar, Union

from fastapi import params
from fastapi._compat import Undefined
Expand Down Expand Up @@ -2217,9 +2217,12 @@ def File( # noqa: N802
)


DependencyResult = TypeVar("DependencyResult")


def Depends( # noqa: N802
dependency: Annotated[
Optional[Callable[..., Any]],
Optional[Callable[..., DependencyResult]],
Doc(
"""
A "dependable" callable (like a function).
Expand All @@ -2244,7 +2247,7 @@ def Depends( # noqa: N802
"""
),
] = True,
) -> Any:
) -> DependencyResult:
"""
Declare a FastAPI dependency.
Expand Down Expand Up @@ -2274,12 +2277,14 @@ async def read_items(commons: Annotated[dict, Depends(common_parameters)]):
return commons
```
"""
return params.Depends(dependency=dependency, use_cache=use_cache)
depends_any: Any = params.Depends(dependency=dependency, use_cache=use_cache)
depends: DependencyResult = depends_any
return depends


def Security( # noqa: N802
dependency: Annotated[
Optional[Callable[..., Any]],
Optional[Callable[..., DependencyResult]],
Doc(
"""
A "dependable" callable (like a function).
Expand Down Expand Up @@ -2321,7 +2326,7 @@ def Security( # noqa: N802
"""
),
] = True,
) -> Any:
) -> DependencyResult:
"""
Declare a FastAPI Security dependency.
Expand Down Expand Up @@ -2357,4 +2362,8 @@ async def read_own_items(
return [{"item_id": "Foo", "owner": current_user.username}]
```
"""
return params.Security(dependency=dependency, scopes=scopes, use_cache=use_cache)
security_any: Any = params.Security(
dependency=dependency, scopes=scopes, use_cache=use_cache
)
security: DependencyResult = security_any
return security

0 comments on commit 4082cdb

Please sign in to comment.