python / python/mypy

Idea: short-circuit analysis with `if <platform-check>: return`

Aperta
#5,964 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

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

Descrizione

Hey all,

I'm adding OS-specific typechecking to a large Python app, and we have a fair number of files and functions that mix OS versions. Currently, mypy only does limited analysis with platform/version/constants to figure out which lines it shouldn't check. With that limited analysis, it's possible to add OS-specific typechecking to the app, but it'll make the code a bit messier.

I'd like to get your feedback on two ideas that would make adding OS-specific typechecking easier.

  1. For if statements where the expression is a mypy-constant, short-circuit if there's a return statement one-level deep in the body of the if. (Currently, the inner bodies of the if are conditionally checked, and return doesn't short-circuit checking.)

E.g.

# flags: --always-false=IS_WINDOWS
if IS_WINDOWS:
    import win_specific_import

def some_fun_broken() -> int:
    if not IS_WINDOWS:
        return 1 # checked
    # The rest of this function is analyzed even though we returned above. 

    # Blows up since `win_specific_import` isn't defined
    return win_specific_import.something()

def some_fun_fixed() -> int:
    if not IS_WINDOWS:
        return 1  # checked
    else:
        # Not analyzed because this is in the `else` part of the `if` statement
        return win_specific_import.something()  # Works

We use the if not IS_WINDOWS: return pattern a fair amount in our codebase, and it would be nice if mypy supported that.

I'm not sure how we'd implement that in mypy, though. Maybe we can scan for a return one-level deep in if statement bodies which have a mypy-constant expression and mark the rest of the function as unreachable.

  1. Make mypy-constant asserts also ignore function bodies. This would be an extension of #5308. E.g.
# flags: --always-false=IS_WINDOWS

if IS_WINDOWS:
    import win_specific_import

def invalid_win_specific_function() -> bool:
    assert IS_WINDOWS
    return win_specific_import.some_func()  # This blows up

if IS_WINDOWS:
    def valid_win_specific_function() -> bool:
        return win_specific_import.some_func()

It would be convenient if we ignored the rest of the function body if the first statement in it is a mypy-constant assert. I don't think we'd want to look for asserts elsewhere in the function block, though, even though that would make it a magical special-case.

Any thoughts on the above ideas?

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 tracciando l’analisi esistente di piattaforma, versione e costanti di mypy, compreso il comportamento descritto per gli import condizionali e i corpi delle funzioni. Determina se è desiderato uno dei due comportamenti proposti di cortocircuito, quindi definisci la copertura per gli esempi if/return e dell’assert iniziale prima di implementare test e modifiche.

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

Valutazione

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

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.