python / python/mypy

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

Ouverte
#5,964 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

feature topic-reachability
Langage dominant
Python
Étoiles
20.6k
Forks
3.3k
Métriques de merge des PR
Métriques de PR en attente

Description

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?

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par suivre l’analyse existante de la plateforme, de la version et des constantes de mypy, y compris le comportement décrit pour les imports conditionnels et les corps de fonction. Déterminez si l’un ou l’autre des deux comportements proposés de court-circuitage est souhaité, puis définissez la couverture pour les exemples if/return et de assert en tête avant d’implémenter les tests et les modifications.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
python
Domaine
compilers
Type d'issue
Fonctionnalité
Difficulté
5/5
Temps estimé
Plus d'une semaine
Activité
À l'abandon
Clarté
À clarifier
Accessibilité débutants
25/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.