sorted() loses information about namedtuple elements
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Python
- Sterne
- 20.6k
- Forks
- 3.3k
- PR-Merge-Kennzahlen
- PR-Kennzahlen ausstehend
Beschreibung
Bug Report
it seems that running sorted() on an union of iterables of named tuple, create some missing information
To Reproduce
from typing import NamedTuple
from typing import reveal_type
class NamedTupleA(NamedTuple):
field_a: str
class NamedTupleB(NamedTuple):
field_b: str
def my_fun(my_list: list[NamedTupleA] | list[NamedTupleB]) -> None:
reveal_type(my_list)
# Revealed type is "Union[builtins.list[tuple[builtins.str, fallback=__main__.NamedTupleA]], builtins.list[tuple[builtins.str, fallback=__main__.NamedTupleB]]]"
for nt in my_list:
if isinstance(nt, NamedTupleA):
print(nt.field_a)
else:
# here nt is recognized of `NamedTupleB` type, I can access field_b
print(nt.field_b)
reveal_type(sorted(my_list))
# Revealed type is "builtins.list[tuple[builtins.str]]"
for sorted_nt in sorted(my_list):
if isinstance(sorted_nt, NamedTupleA):
print(sorted_nt.field_a)
else:
# here I expected nt to be recognized of `NamedTupleB` type
print(sorted_nt.field_b)
if __name__ == '__main__':
my_fun([NamedTupleA('value_1')])
my_fun([NamedTupleB('value_2')])
# this error is expected: I cannot mix NamedTupleA and NamedTupleB
my_fun([NamedTupleA('value_1'), NamedTupleB('value_2')])
basically I have 2 list of NamedTuples.
my_fun must accept either one.
Ideally I could write a User-Defined Type Guards, but let's say that I'm just checking (with isinstance) each element type.
If I loop directly over the list, the check works for both the if and the else branch (there shouldn't be any other case, the union is between two types)
If I loop directly over the sorted list, the type of the element is different, so in the else branch mypy gives me an error
Expected Behavior
I expect no errors on print(sorted_nt.field_b)
Actual Behavior
main.py:32: error: "tuple[str]" has no attribute "field_b" [attr-defined]
Your Environment
linux, python3.12, mypy 1.10.1
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
Beginnen Sie mit der verknüpften mypy-playground-Reproduktion unter Python 3.12 und mypy 1.10.1 und vergleichen Sie anschließend die angezeigten Typen vor und nach sorted() in main.py. Die Korrektur ist vollständig, wenn das Ergebnis von sorted() die NamedTuple-Alternativen beibehält, sodass die isinstance-Zweige sorted_nt.field_a und sorted_nt.field_b ohne einen attr-defined-Fehler akzeptieren.
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
- 48/100