dmontagu / fastapi-utils

Reusable utilities for FastAPI
MIT License
1.9k stars 165 forks source link

Typing issue when using class based views [BUG] #63

Open yeralin opened 4 years ago

yeralin commented 4 years ago

Describe the bug When I tried to use @cbv(router) and added a class attribute with Depends, my pylint started complaining with E1101: Instance of 'Depends' has no '...' member (no-member).

To Reproduce

from fastapi import APIRouter, Path, Depends, Query
from fastapi_utils.cbv import cbv

router = APIRouter()

class ControllerClass:

    def get_sample() -> str:
        return "sample"

def get_controller() -> ControllerClass:
     return ControllerClass()

@cbv(router)
class MyRouter:

    controller: ControllerClass = Depends(get_controller)

    @router.get("/sample")
    async def sample(self) -> str:
        return self.controller.get_sample() # <- this line recognizes self.controller as `Depends` instance, not `ControllerClass`

# > E1101: Instance of 'Depends' has no 'get_sample' member (no-member)

Although, functionally everything works just fine.

Expected behavior The typing of the class var should be inferred as ControllerClass, not Depends.

Environment:

>>> print(fastapi_utils.__version__)
0.2.1
>>> print(fastapi.__version__)
0.55.1
>>> print(pydantic.utils.version_info())
             pydantic version: 1.5.1
            pydantic compiled: True
               python version: 3.7.7 (default, May  6 2020, 04:59:01)  [Clang 4.0.1 (tags/RELEASE_401/final)]
                     platform: Darwin-19.5.0-x86_64-i386-64bit
     optional deps. installed: ['typing-extensions']
torugok commented 4 years ago

Same bug here

Python 3.8.2

HymanZHAN commented 4 years ago

Isn't it more of a problem on the linter's side though? IIRC, pylint comes with its own inference engine and can lead to false positives when it comes to checks like no-member. I don't find it work that well with type annotations.

As a side note, I personally use a combination of flake8, mypy(with some stricter options), and/or Pylance(pyright), which I think should be more than enough to set the baseline of code quality for a fully typed project.

Reference: https://github.com/PyCQA/pylint/issues/647#issuecomment-529359236 https://github.com/PyCQA/pylint/issues/2842#issuecomment-477906941

falkben commented 3 years ago

Have there been any solutions for this? I realize it may be an issue with pylint but it would be nice to solve without having to put # pylint: disable=no-memeber everywhere

I tried putting it in my generated-members .pylintrc file, but that doesn't seem to fix things