sorted() loses information about namedtuple elements
Nessuno ha ancora preso questa issue.
- Lingua principale
- Python
- Stelle
- 20.6k
- Fork
- 3.3k
- Metriche di merge delle PR
- Metriche PR in attesa
Descrizione
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
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia con la riproduzione collegata su mypy playground usando Python 3.12 e mypy 1.10.1, quindi confronta i tipi rivelati prima e dopo sorted() in main.py. La correzione è completa quando il risultato di sorted() preserva le alternative di NamedTuple, in modo che i rami isinstance accettino sorted_nt.field_a e sorted_nt.field_b senza un errore attr-defined.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- python
- Ambito
- devtools
- Tipo di issue
- Bug
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Stato di attività
- Ferma
- Chiarezza
- Specificata chiaramente
- Idoneità per principianti
- 48/100