Search code examples
pythontypesfastapimypy

FastAPI's Depends() causes "Incompatible default for argument" error in mypy


I have this example code.

def get_test(q: str) -> str:
    return 'str str str' + q


@router_user.put(
    "/", response_model=schemas.UpdateUserRequest, tags=["User and Authentication"]
)
async def update_user(
        data: schemas.UpdateUserRequest,
        q: str = Depends(logic.get_test),
        db: AsyncSession = Depends(get_db),
        user: models.User = Depends(logic.get_curr_user_by_token),
):
    print(q)

when checking it with mypy, I always get an error


app/api/user/router.py:74: error: Incompatible default for argument "q" (default has type "Depends", argument has type "str")  [assignment]


Solution

  • It looks like you've used an incorrect import.

    I've cleaned up your code sample and added imports, and the following does pass mypy:

    from fastapi import APIRouter, Depends
    
    
    def get_test(q: str) -> str:
        return "str str str" + q
    
    
    router_user = APIRouter()
    
    
    @router_user.put("/")
    async def update_user(
        q: str = Depends(get_test)
    ) -> None:
        print(q)
    

    However, if I replace the imports with

    from fastapi import APIRouter
    from fastapi.params import Depends
    

    Then I get the same error you got from mypy.

    I'm guessing your IDE incorrectly completed the import from fastapi.params instead of directly from fastapi. If you check the official docs, you'll see that Depends should be imported directly from fastapi.

    Why this happens

    params.Depends is a class defined here. However, if you use that directly, it will be a type error whenever you write something like x: str = Depends(...), because the params.Depends class is not compatible with str. What we really want is for mypy to ignore the type of Depends() and assume it's compatible with any type.

    That's why the Depends in fastapi is actually a wrapper function around params.Depends defined as returning Any.