python / python/mypy

Plugin hook to selectively silence error messages

Offen
#7,468 7 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

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

Beschreibung

For developing an Either-like monad that types correctly and also behaves nicely at runtime I currently use the following pattern to independently declare the types for mypy and the runtime implementation

from typing import Generic, TypeVar, TYPE_CHECKING

L = TypeVar('L')
R = TypeVar('R')

if TYPE_CHECKING:  # type declarations

    class Either(Generic[L, R]): pass
    Left = Either[L, None]
    Right = Either[None, R]

else:  # runtime implementation

    class Either(): pass
    class Left(Either): pass
    class Right(Either): pass


# type checking features
a: Left[int] 
b: Either[int, None]

a = b  # typechecks
b = a  # typechecks 

# runtime features
isinstance(Left(), Left)  #works at runtime 
isinstance(Left(), Either)  #works at runtime

During static analysis it is important that Left and Right get treated as aliases for Either so that assignments get typechecked correctly (even though at runtime they are subclasses (and thus subtypes) of Either). Additionally I'd like to be able and use isinstance checks at runtime to determine whether a result is an instance of Left or Right (or more general if something is an instance of Either). This mostly works (assignments typecheck and runtime behavior is as excepted), however mypy (rightfully) complains about the isinstance checks that

Parameterized generics cannot be used with class or instance checks mypy(error)

In cases like these it would be useful if one could tell mypy that a generic class can be used with instance checks. This would also be somewhat similar to how one can declare protocol classes to support runtime instance checks with the @runtime_checkable decorator.


This would also allow user defined generics to behave similar to types from typing like List where

isinstance([1,2,3], List)  # typechecks
isinstance([1,2,3], List[int])  # Parameterized generics cannot be ...

vs

isinstance(Left(1), Left)  # should typecheck, currently doesn't
isinstance(Left(1), Left[int])  # Parameterized generics cannot be ...

I'd propose that @runtime_checkable marks an Generic accordingly so that in the example it would be

#...
if TYPE_CHECKING:  # type declarations

    @runtime_checkable
    class Either(Generic[L, R]): pass

#...
Addendum

The issue is actually not with Either per se but rather with the type aliases Left and Right. For mypy

isinstance(Left(1), Left)  #looks similar to 'isinstance([1,2,3], List)'

actually is

isinstance(Left(1), Either[L, None])  # looks similar to 'isinstance([1,2,3], List[int])'

I still think this would be a useful feature to be able and better support the dynamic nature of Python with the if TYPE_CHECKING pattern.

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

Es werden keine Implementierungsdateien oder Tests genannt. Beginne damit, mypys Behandlung von isinstance-Prüfungen mit generischen Aliasen nachzuverfolgen, und vergleiche sie mit dem im Issue beschriebenen bestehenden List-Verhalten. Als abgeschlossen gilt die Entscheidung über die beabsichtigte Behandlung von nicht parametrisierten und parametrisierten generischen Prüfungen sowie deren Implementierung, mit Testabdeckung für die Beispiele Either, Left und Right.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
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.