python / python/mypy

Infer correct metaclass for protocols

Offen
#13,979 1 Kommentar 1 Reaktion 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

bug topic-protocols
Vorherrschende Sprache
Python
Sterne
20.6k
Forks
3.3k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

A subclass of Protocol is also an ABC:

import abc
from typing import Protocol

class P(Protocol):
    @abc.abstractmethod
    def f(self) -> None: pass

class C(P):
    pass

C()  # TypeError: Can't instantiate abstract class C with abstract method f

However, mypy doesn't detect a metaclass conflict here:

from typing import Protocol

class Meta(type): pass

# Metaclass conflict at runtime, but no mypy error
class P(Protocol, metaclass=Meta): pass

At runtime this will generate a metaclass conflict:

Traceback (most recent call last):
  File "/Users/jukka/src/mypy/t/t5.py", line 6, in <module>
    class P(Protocol, metaclass=Meta): pass
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

The actual metaclass is typing._ProtocolMeta:

>>> type(typing.Protocol)
<class 'typing._ProtocolMeta'>

Mypy should infer typing._ProtocolMeta as the metaclass of protocol classes. Maybe a custom metaclass should also be rejected, at least if it isn't a subclass of typing._ProtocolMeta.

More discussion here: https://github.com/python/typeshed/pull/9058

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, mypy's Metaklasseninferenz für von Protocol abgeleitete Klassen nachzuverfolgen und sie mit dem in den Beispielen gezeigten Verhalten von Python's typing._ProtocolMeta zu vergleichen. Die Arbeit ist abgeschlossen, wenn Protokollklassen die korrekte Metaklasse zugewiesen bekommen und eine inkompatible benutzerdefinierte Metaklasse eine Diagnose zu einem Metaklassenkonflikt erzeugt.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
devtools
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

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