python / python/mypy

Type narrowing and PEP 634 pattern matching

Aperta
#17,622 0 commenti 3 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

feature
Lingua principale
Python
Stelle
20.6k
Fork
3.3k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

Feature

Narrowing a type in a case block that matches the True result of a type-narrowing expression.

Pitch

Hi all- I'd be curious to hear opinions on how realistic the above would be. Here's an example of something that would work if this were implemented:

a: str | None = "hello"

match a is not None:  # or `match isinstance(a, str)`, etc.
    case True:
        print("'a' is a string", a.encode())  # currently: Item "None" of "str | None" has no attribute "encode"
    case False:
        print("'a' is None")

My "pitch" is simply that this feels like it should work (even though it makes sense to me why it doesn't). I think this feeling comes from the fact that, at least on the surface:

if thing:
    blah()
else:
    whatev()

seems morally equivalent to

match thing:
    case True:
        blah()
    case False:
        whatev()

Since I don't have any background with mypy's internals, I'm hoping to hear from the team here how feasible this all sounds.


For context, I ran into this issue when I had a type-narrowing expression embedded in a larger scrutinee (in practice, I can't imagine using match over if if the only thing I were testing was the result of a single type-narrowing expression). Specifically, I was creating a decision table of sorts, and match seemed like a nice way to do that without having to repeat tests:

content: str | bytes
is_text_format: bool

match isinstance(content, str), is_text_format:
    case True, True:
        prepped = content
    case True, False:
        prepped = content.encode("utf-8")  # type narrowing useful here
    case False, True:
        prepped = content.decode("utf-8")  # and here
    case False, False:
        prepped = content

...

I'm sure there are better ways to tackle this bool-centric example, but I think the general question stands on its own outside my original context.


Thank you for your consideration!

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia con i due esempi di match nell’issue e confronta il comportamento di narrowing richiesto con le diagnosi correnti di mypy. L’issue non identifica alcun file sorgente, test o punto di ingresso, quindi individuare l’implementazione del pattern matching e del type narrowing farebbe parte del lavoro. Il lavoro è completato quando i rami True e False restringono l’espressione analizzata in modo coerente, inclusi i tuple scrutinee.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
devtools
Tipo di issue
Funzionalità
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
25/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.