Skip to content

metaclass/__init_subclass__ keyword checking #11057

Open
@esoma

Description

@esoma

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:

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.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions