python / python/mypy

ENH: Support slack variables (lower bound emulation)

Offen
#20,648 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

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

Beschreibung

Describe the Bug

Context: https://github.com/python/typing/issues/674

Slack variables would allow us to emulate lower bounds on type variables, which is relevant for methods like dict.__or__ or list concatenation, when an outer context is present.

from typing import Never, assert_type, reveal_type

class Vec[T]:  # invariant in T
    def _items(self) -> list[T]: ...
    def _append(self, item: T) -> None: ...

def concat_vecs[T1, T2, _T_slack=Never](
    left: Vec[T1],
    right: Vec[T2],
) -> Vec[T1 | T2 | _T_slack]:  # <-- Slack variable makes return a supertype of T1 | T2
    return Vec()

class A: ...
class B: ...
class C: ...

def test_vec_concat(left: Vec[A], right: Vec[B]) -> None:
    # without outer context, the type is precise
    assert_type(concat_vecs(left, right), Vec[A | B])  # ✅️
    # outer context allows widening due to slack variables
    _0: Vec[A | B]     = concat_vecs(left, right) # ❌️
    _1: Vec[A | B | C] = concat_vecs(left, right) # ❌️
    _2: Vec[object]    = concat_vecs(left, right) # ❌️

mypy fails to find existing solutions on some of these function calls:

  • _0: (T1=A, T2=B, _T_slack=Never)
  • _1: (T1=A, T2=B, _T_slack=C)
  • _2: (T1=A, T2=B, _T_slack=object)
21:38: error: Argument 1 to "concat_vecs" has incompatible type "Vec[A]"; expected "Vec[A | B]"  [arg-type]
21:44: error: Argument 2 to "concat_vecs" has incompatible type "Vec[B]"; expected "Vec[A | B]"  [arg-type]
22:38: error: Argument 1 to "concat_vecs" has incompatible type "Vec[A]"; expected "Vec[A | B | C]"  [arg-type]
22:44: error: Argument 2 to "concat_vecs" has incompatible type "Vec[B]"; expected "Vec[A | B | C]"  [arg-type]
23:38: error: Argument 1 to "concat_vecs" has incompatible type "Vec[A]"; expected "Vec[object]"  [arg-type]
23:44: error: Argument 2 to "concat_vecs" has incompatible type "Vec[B]"; expected "Vec[object]"  [arg-type]

no playground link as typevar defaults are still not supported.

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 mit der Vec- und concat_vecs-Reproduktion im Issue und lies dann das verlinkte python/typing-Issue 674 zum Kontext der Slack-Variablen. Es werden keine Repository-Dateien oder Tests genannt; abgeschlossen bedeutet, dass die Aufrufe _0, _1 und _2 mit den angegebenen erweiterten Ergebnistypen die Typprüfung bestehen.

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
Muss geklärt werden
Anfängerfreundlichkeit
25/100

Neue Issues direkt in Ihr Postfach

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