python / python/mypy

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

Abierto
#5,964 1 comentario 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

feature topic-reachability
Lenguaje dominante
Python
Estrellas
20.6k
Forks
3.3k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

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?

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Empieza rastreando el análisis existente de plataforma, versión y constantes de mypy, incluido el comportamiento descrito para las importaciones condicionales y los cuerpos de las funciones. Resuelve si se desea alguno de los dos comportamientos de cortocircuito propuestos y, a continuación, define la cobertura para los ejemplos de if/return y del assert inicial antes de implementar las pruebas y los cambios.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
python
Área
compilers
Tipo de issue
Nueva funcionalidad
Dificultad
5/5
Tiempo estimado
Más de una semana
Estado de actividad
Estancado
Claridad
Necesita aclaración
Aptitud para principiantes
25/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.