I would like mypy to verify that a variable is subclassed from a certain base class and that it also has a specific mixin. Union only verifies that the value is of one type or another. I need to check that the value is both types.
In the example, I'm making up a keyword "All" to demonstrate the behavior I'm looking for:
from typing import All
class Base ( object ):
pass
class Mixin ( object ):
pass
def assert_all ( x ):
# type: ( All[Base,Mixin] ) -> None
assert isinstance ( x, Base ) and isinstance ( x, Mixin )
class Child ( Mixin, Base ):
pass
assert_all ( Child() )
try:
assert_all ( Base() ) # !!! mypy should complain here
except AssertionError:
pass
else:
raise AssertionError ( 'assert inside of assert_all() should have fired' )
try:
assert_all ( Mixin() ) # !!! mypy should complain here, too
except AssertionError:
pass
else:
raise AssertionError ( 'assert inside of assert_all() should have fired' )
In case it's helpful, the reason I need this is I have my own win32 wrapper implemented in Python. My Base class is the basic Window class. My required Mixin is ControlHost which adds specific window styles and functions to the Window class to manage owning children, things that a basic window doesn't need. When creating child controls, like a ComboBox for example, I want mypy to call me out if the parent window I feed it doesn't have both super classes.
Also, I'm having an issue calling Window.init() from Control.init() because of a change of the parent's type. Here's abbreviated pseudo-code that illustrates the problem:
class Window:
def __init__ ( self, parent, .... ):
# type: ( Optional[Window], .... )
class Control ( Window ):
def __init__ ( self, parent, .... ):
# type: ( Optional[ControlHost], .... )
My work-around looks like this, but it doesn't allow mypy to catch type infractions:
class Control ( Control_mixin, Window ):
....
def __init__ ( self, parent=None ):
# type: ( Optional[ControlHost] ) -> None
self.initStyle |= winapi.WS_CHILD|winapi.WS_CLIPSIBLINGS
assert isinstance ( parent, Window )
super ( Control, self ).__init__ ( cast ( Window, parent ) )
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…