Search code examples
pythonmypy

Appeasing MyPy trying to use an instance variable


If I have the file mypytest/models.py that looks like this:

from typing import Type


class FakeBaseModel:
    pass


class FakeDatabase:
    Base: Type[FakeBaseModel]

    def __init__(self) -> None:
        self.Base = FakeBaseModel


db = FakeDatabase()


class FakeModel(db.Base):
    pass

And I run mypy ., I get the following output:

[mypytest {mypytest}]$ mypy .
mypytest/models.py:18: error: Name "db.Base" is not defined
Found 1 error in 1 file (checked 2 source files)

Clearly, though, db.Base is defined. How do I get mypy to recognize it?


Solution

  • I believe the problem here is that db.Base is a variable, not a type alias.

    It's unclear from your example exactly why you need a dynamic base class. Inlining FakeBaseModel would obviously work; you could also just use a type alias while running the type checking:

    from typing import Type, TYPE_CHECKING
    
    # *snip*
    
    db = FakeDatabase()
    
    if TYPE_CHECKING:
        FakeBase = FakeBaseModel
    else:
        FakeBase = db.Base
    
    class FakeModel(FakeBase):
        pass
    

    This will produce valid type checking based on what you've provided (basically, as long as FakeModel only uses what's in FakeBaseModel so it's safe to treat it as one).