python / python/mypy

`mypy` doesn't understand that `*args: P.args` implies that `args` is a `tuple`

Ouverte
#19,663 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

bug topic-calls topic-paramspec
Langage dominant
Python
Étoiles
20.6k
Forks
3.3k
Merge moyen
1 j 18 h
PR mergées (30 j)
54

Description

from typing import Callable

def as_tuple[*Ts](*args: *Ts) -> tuple[*Ts]: return args
def tuple_identity[*Ts](t: tuple[*Ts]) -> tuple[*Ts]: return t
def tuple_identity2[T: tuple](t: T) -> T: return t


def test_paramspec[**P](
    dummy: Callable[P, None],  # ensure P is bound
    /,
    *args: P.args,
    **kwargs: P.kwargs,
) -> None:
    reveal_type(args)                   # N: "P.args`-1" 
    reveal_type( (*args,) )             # N: "builtins.tuple[P.args`-1, ...]"
    reveal_type( tuple(args) )          # N: "builtins.tuple[builtins.object, ...]"
    reveal_type(as_tuple(*args))        # N: "builtins.tuple[P.args`-1, ...]"
    reveal_type(tuple_identity(args))   # N: "builtins.tuple[Never, ...]"
                                        # E: [arg-type]
    reveal_type(tuple_identity2(args))  # N: "P.args`-1" ✅

    if isinstance(args, tuple):
        pass
    else:
        reveal_type(args)  # false negative [warn-unreachable]

https://mypy-play.net/?mypy=latest&python=3.12&flags=warn-unreachable&gist=3eabd8f4ee599e272934c94080f02bd8

Ideally, all the reveal_types should show the same result (or raise errors if considered misuse of ParamSpec[^1]), and the else-branch should trigger an unreachable warning.

[^1]: For instance, pyright says as_tuple(*args) is illegal. Code sample in pyright playground

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 le reproducer test_params fourni et exécutez-le avec warn-unreachable activé, en comparant les résultats de reveal_type de mypy au comportement attendu et aux playgrounds liés. Suivez le traitement des arguments de ParamSpec et le narrowing des tuples dans mypy ; c’est terminé lorsque les types révélés sont cohérents ou correctement rejetés et que la branche else impossible signale qu’elle est inaccessible.

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

Évaluation

Stack technique
python
Domaine
devtools
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
42/100

Recevez les nouvelles issues par e-mail

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