Union type narrowing behaves differently depending on argument position
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Python
- Sterne
- 20.6k
- Forks
- 3.3k
- PR-Merge-Kennzahlen
- PR-Kennzahlen ausstehend
Beschreibung
Bug Report
In the following example the type narrowing of the union types works as expected if it appears in the first or second argument position, but breaks if it appears in position three (or later).
This issue probably falls into the topic-join-v-union.
To Reproduce
Example on mypy playground
from typing import Callable, TypeVar
T = TypeVar("T")
def func(
a: Callable[[], T],
b: Callable[[], T],
c: Callable[[], T],
) -> T:
raise NotImplementedError()
class Foo:
...
class Bar:
...
def make_foo() -> Foo:
raise NotImplementedError()
def make_bar() -> Bar:
raise NotImplementedError()
def make_foo_or_bar() -> Foo | Bar:
raise NotImplementedError()
x1: Foo | Bar = func(a=make_foo_or_bar, b=make_foo, c=make_bar)
x2: Foo | Bar = func(a=make_foo, b=make_foo_or_bar, c=make_bar)
x3: Foo | Bar = func(a=make_foo, b=make_bar, c=make_foo_or_bar)
Expected Behavior
The example should type check properly.
Actual Behavior
Inferring the return type works properly for x1 and x2, but it fails for x3 with:
Incompatible types in assignment (expression has type "object", variable has type "Foo | Bar") [assignment]
Considering that the code is fully valid and symmetric, there should not be a difference in the behavior.
Side note: The issue cannot be work-around at call site by just swapping the order of a and c in the func(...) call. Apparently it has to do with the order in which they appear in the function signature.
Your Environment
- Mypy version used: 1.6.1
- Mypy command-line flags: none
- Mypy configuration options from
mypy.ini(and other config files): none - Python version used: 3.10, 3.11
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne mit dem Reproducer im Issue und führe ihn mit mypy 1.6.1 oder der aktuellen Version aus, um den Positionsunterschied zu bestätigen. Verfolge die Typinferenz der Callable-Argumente für func und untersuche, warum der dritte Parameter object erzeugt; abgeschlossen, wenn x1, x2 und x3 alle konsistent typgeprüft werden.
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
- Klar beschrieben
- Anfängerfreundlichkeit
- 35/100