python / python/mypy

metaclass/__init_subclass__ keyword checking

Offen
#11,057 1 Kommentar 2 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

feature topic-metaclasses topic-plugins
Vorherrschende Sprache
Python
Sterne
20.6k
Forks
3.3k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

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.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne damit, die Checker-Logik zu lesen, die bestimmt, welche Metaklassen sicher sind, und untersuche dann TypeInfo und die im Issue erwähnten bestehenden Plugin-Hooks. Vergleiche das vorgeschlagene TypeInfo-Flag mit einem Hook zur Anpassung der Menge sicherer Metaklassen. Als abgeschlossen gilt die Änderung, wenn ein Plugin eine Metaklasse als sicher weiterleitend für init_subclass-Schlüsselwörter markieren kann und das Beispiel eine Typprüfung erhält.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
compilers, devtools
Issue-Typ
Feature
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
30/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.