python / python/mypy

Type checking for *args and **kwargs when passing them to another function

Abierto
#19,302 14 comentarios 9 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

feature topic-calls
Lenguaje dominante
Python
Estrellas
20.6k
Forks
3.3k
Merge medio
1 d 18 h
PR fusionados (30 d)
54

Descripción

Feature

Add type checking for passing *args and **kwargs to another function.

It may be enabled by default when mypy detects *args and **kwargs are passed to the same function or it may be enabled only by decorator (for example, @mypy_extensions.pass_args. This will overwrite *args and **kwargs in the function signature with signature of the function to which they are passed. Also it should be possible to explicitly mark the function to which arguments are passed and specify whether to pass *args, **kwargs or both.

Pitch

I'll give an example with usual functions but it will be useful for decorators too.

For example, function wrapper passes its arguments to function inner and adds its own arguments:

def inner(a: int, b: int) -> None:
    ...


def wrapper(arg1: str, *args, **kwargs) -> None:
    inner(*args, **kwargs)  # It will automatically detect passing arguments to another function

This will automatically detect passing *args and **kwargs to another function and change the function signature to:

def wrapper(arg1: str, a: int, b: int):
    ...

It should successfully process and type-check the following calls:

wrapper("foo", 1, 2)  # All positional arguments
wrapper(arg1="foo", b=1, a=2)  # All keyword arguments
wrapper("foo", 1, a=2)  # Mix positional and keyword

wrapper([], 1, 2)
#       ^^ Type error in wrapper's argument (list passed instead of str)

wrapper("foo", [], 2)
#              ^^ Type error in inner's argument (list passed instead of int)

Also multiple passes to the same function should be successfully processed:

def wrapper(arg1: str, *args, **kwargs) -> None:
    if some_condition:
        inner(1, *args, **kwargs)  # Multiple same function calls with passed arguments
    elif condition2:
        inner(2, *args, **kwargs)
    else:
        inner(*args, **kwargs)

Also these cases should be processed:

def wrapper(arg1: str, *args, **kwargs) -> None:
    inner(*args)  # Only args are passed
def wrapper(arg1: str, *args, **kwargs) -> None:
    inner(**kwargs)  # Only kwargs are passed

There should be an option to overwrite this behavior using decorator (or this feature may be disabled by default and be enabled by the decorator). The decorator factory signature concept:

def pass_args(func: collections.abc.Callable | None, pass_args: bool = False, pass_kwargs: bool = False):
    ...

func – The function to copy arguments from. Use None value to force disable this feature.
pass_args – whether to copy arguments that may be passed as positional (passing *args)
pass_kwargs – whether to copy arguments that may be passed as keyword (passing **kwargs)

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

El issue no menciona archivos, pruebas ni puntos de entrada. Empieza por localizar cómo mypy gestiona las firmas y las llamadas de funciones, y después determina cómo encaja el comportamiento propuesto en la comprobación de argumentos existente. Se considerará terminado cuando haya un diseño decidido, una implementación y pruebas que cubran argumentos posicionales, argumentos con palabras clave, llamadas mixtas, reenvío parcial y sobrescrituras.

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

Evaluación

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

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.