python / python/mypy

Assigning wrapped class members to a member defined by a base class fails with incompatible types in assignment

Offen
#14,408 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

bug topic-inference topic-type-context
Vorherrschende Sprache
Python
Sterne
20.6k
Forks
3.3k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

Bug Report

Consider the following code, where wrap is some decorator that preserves the function signature:

class Base:
    def f(self, a: int) -> int:
        return a + 1

    def g(self, a: int) -> int:
        return a + 1

class Derived(Base):
    @wrap
    def f(self, a: int) -> int:
        return a + 2

    def _g(self, a: int) -> int:
        return a + 2 

    g = wrap(_g)

The assignment g = wrap(_g) fails with Argument 1 to "wrap" has incompatible type "Callable[[Dervied, int], int]"; expected "Callable[[Base, int], int]". I would have expected both ways of wrapping a function to be the same (ans as far as I can tell they do so at runtime) and therefore both should be allowed.

This is also not a general issue with assignments as the following code type checks:

class Base:
    def f(self, a: int) -> int:
        return a + 1

class Derived(Base):
    def _f(self, a: int) -> int:
        return a + 2

    f = _f

To Reproduce

https://mypy-play.net/?mypy=master&python=3.11&gist=2455e6265bf5ec9cc5ffac2d95accf98

Note that mypy-play seems to use c660354846688ff8158d0f0178eb298171b74f5b rather than the latest commit from master for some reason. The output on current master is slightly different (the type of C.abc is no longer consider def (self: __main__.A, a: builtins.int) -> builtins.int):

test_assign_function_subclass.py:32: error: Incompatible types in assignment (expression has type "Callable[[C, int], int]", base class "A" defined the type as "Callable[[A, int], int]")  [assignment]
test_assign_function_subclass.py:50: error: Cannot determine type of "abc"  [has-type]
test_assign_function_subclass.py:55: note: Revealed type is "def (self: test_assign_function_subclass.A, a: builtins.int) -> builtins.int"
test_assign_function_subclass.py:56: note: Revealed type is "def (self: test_assign_function_subclass.B, a: builtins.int) -> builtins.int"
test_assign_function_subclass.py:57: error: Cannot determine type of "abc"  [has-type]
test_assign_function_subclass.py:57: note: Revealed type is "Any"
test_assign_function_subclass.py:58: note: Revealed type is "def (self: test_assign_function_subclass.D, a: builtins.int) -> builtins.int"
test_assign_function_subclass.py:59: note: Revealed type is "def (self: test_assign_function_subclass.E, a: builtins.int) -> builtins.int"
Found 3 errors in 1 file (checked 1 source file)

Expected Behavior

No error, code type checks

Actual Behavior

main.py:32: error: Argument 1 to "wrap" has incompatible type "Callable[[C, int], int]"; expected "Callable[[A, int], int]"  [arg-type]

Your Environment

  • Mypy version used: 98cc165a657a316accb93f1ed57fdc128b086d9f
  • Mypy command-line flags: None
  • Mypy configuration options from mypy.ini (and other config files): None
  • Python version used: 3.10 & 3.11

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

Führe zunächst den verknüpften mypy-play-Reproducer mit der aktuellen mypy-Version aus und vergleiche die Decorator-Form mit der direkten Zuweisungsform. Untersuche, wie mypy umschlossene Klassenmitglieder gegen geerbte Mitglieder prüft; die Aufgabe ist erledigt, wenn beide äquivalenten Beispiele ohne die Fehler incompatible-argument oder assignment typgeprüft werden.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

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