A way for plugins to mark a metaclass as safely passing keyword arguments to __init_subclass__.
Pitch
The current situation
Currently, if a class is inherited from that both has a custom metaclass and __init_subclass__ defined then there is no type checking done for the keyword arguments in __init_subclass__. For example the following is an error:
class Base:
def __init_subclass__(cls, keyword: int = 0): ...
class Derived(Base, keyword='fail'): ...
error: Argument "keyword" to "__init_subclass__" of "Base" has incompatible type "str"; expected "int"
But this is not:
class Meta(type): ...
class Base(metaclass=Meta):
def __init_subclass__(cls, keyword: int = 0): ...
class Derived(Base, keyword='fail'): ...
The specifics around this are in #7723.
My issue
I have a base class that operates similar to dataclass object. I have a plugin that provides the semantics to mypy already. However, this class uses a metaclass and __init_subclass__ and I would like type checking on the __init_subclass__ keyword arguments. The metaclass __new__ does not do anything with the keyword arguments but pass them along, so I know it's safe to do the type checking. I would like for my plugin to be able to tell mypy that this metaclass is safe.
Unfortunately I can't just get rid of the metaclass as it provides a class level __await__.
My current solution is just to hack the TypeInfo._fullname for the metaclass to be builtins.type.
The solutions that come to mind would be either:
A boolean on TypeInfo that says that the metaclass is __init_subclass__ safe (plugins just need to flip this in one of the existing hooks)
A way for plugins to manipulate the set of safe metaclasses that Checker uses (hook to customize Checker prior to run?)
I'm happy to do the work if a solution can be found.
Feature
A way for plugins to mark a metaclass as safely passing keyword arguments to
__init_subclass__
.Pitch
The current situation
Currently, if a class is inherited from that both has a custom metaclass and
__init_subclass__
defined then there is no type checking done for the keyword arguments in__init_subclass__
. For example the following is an error:error: Argument "keyword" to "__init_subclass__" of "Base" has incompatible type "str"; expected "int"
But this is not:
The specifics around this are in #7723.
My issue
I have a base class that operates similar to
dataclass
object. I have a plugin that provides the semantics to mypy already. However, this class uses a metaclass and__init_subclass__
and I would like type checking on the__init_subclass__
keyword arguments. The metaclass__new__
does not do anything with the keyword arguments but pass them along, so I know it's safe to do the type checking. I would like for my plugin to be able to tell mypy that this metaclass is safe.Unfortunately I can't just get rid of the metaclass as it provides a class level
__await__
.My current solution is just to hack the
TypeInfo._fullname
for the metaclass to bebuiltins.type
.The solutions that come to mind would be either:
TypeInfo
that says that the metaclass is__init_subclass__
safe (plugins just need to flip this in one of the existing hooks)Checker
uses (hook to customizeChecker
prior to run?)I'm happy to do the work if a solution can be found.