mypy icon indicating copy to clipboard operation
mypy copied to clipboard

(🎁) Allow if expression / conditional base in class def

Open KotlinIsland opened this issue 3 years ago • 5 comments

I have some proxy objects and it's difficult to type them, I want to lie to mypy what the bases are

from typing import TYPE_CHECKING

class A: ...
class B: ...
class C(A if TYPE_CHECKING else B): ...  # error: Invalid base class  [misc]

KotlinIsland avatar Mar 25 '22 06:03 KotlinIsland

Note that this works if you don't use ternary, e.g. I often do something like:

if TYPE_CHECKING:
    AnyBaseClass = Any
else:
    AnyBaseClass = object

class A(AnyBaseClass): ...

hauntsaninja avatar Mar 25 '22 08:03 hauntsaninja

I want to make a type argument conditional on TYPE_CHECKING, because the upstream library used does not support a __class_getitem__ for this particular class -- only type stubs do.

@hauntsaninja's work-around doesn't work for this case. Is there another work-around for this pattern?

class NestedHyperlinkedRelatedField(HyperlinkedRelatedField[T_Model] if TYPE_CHECKING else HyperlinkedRelatedField):
    def get_foo(self) -> T_Model:
        ...

intgr avatar Apr 23 '24 15:04 intgr

It's not pretty but you can duplicate the whole class in the two branches of an if TYPE_CHECKING block.

JelleZijlstra avatar Apr 23 '24 15:04 JelleZijlstra

If someone is interested in fixing this, I imagine it's probably not too hard; it would likely require finding the code in or near semanal.py that handles ternaries and adding support for TYPE_CHECKING there.

JelleZijlstra avatar Apr 23 '24 15:04 JelleZijlstra

The last example in https://mypy.readthedocs.io/en/stable/runtime_troubles.html#using-classes-that-are-generic-in-stubs-but-not-at-runtime could be useful. But a patch would be very welcome, feel free to tag me if you open a PR.

hauntsaninja avatar Apr 23 '24 21:04 hauntsaninja