python / python/mypy

Unable to make generic subclass using type variable with value restriction

Ouverte
#10,130 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

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

Description

Bug Report

Mypy reports some strange false positive errors when I try to define a generic subclass of a generic class where the type variable has a value restriction.

To Reproduce

I made this minimal example to reproduce the bug:

from typing import Generic, TypeVar

T = TypeVar("T", str, int)


class GenericSuperClass(Generic[T]):
    def __init__(self, value: T) -> None:
        # mypy complains if self.value is not annotated, for some reason
        self.value: T = value


class GenericSubClass(GenericSuperClass[T]):
    def __init__(self, value: T, flag: bool) -> None:
        super().__init__(value)
        self.flag = flag


instance = GenericSubClass("string", True)
reveal_type(instance.value)

This example is a bit simple, of course, and does not make use of the value restriction. But you could imagine that there is some logic here that assumes T is either a str or an int.

Expected Behavior

I would expect the above example to not report any errors with Mypy, and I would expect Mypy to infer that self.value is of type T.

I expect the revealed type to be builtins.str.

Actual Behavior

Mypy reports the following errors:

testing_inheriting_generics.py:14: error: Argument 1 to "__init__" of "GenericSuperClass" has incompatible type "str"; expected "T"
testing_inheriting_generics.py:14: error: Argument 1 to "__init__" of "GenericSuperClass" has incompatible type "int"; expected "T"
testing_inheriting_generics.py:19: note: Revealed type is 'builtins.str*'
Found 2 errors in 1 file (checked 1 source file)

Additionally, if self.value is not annotated, Mypy reports the error testing_inheriting_generics.py:9: error: Need type annotation for 'value'

The revealed type is correct, but I believe the errors are false positives?

If I replace T = TypeVar("T", str, int) with T = TypeVar("T"), everything works as expected, but then I would not be able to assume that T is either a str or an int.

Your Environment

  • Mypy version used: mypy 0.812
  • Mypy command-line flags: none
  • Mypy configuration options from mypy.ini (and other config files):
    [mypy]
    disallow_untyped_calls = True
    warn_redundant_casts = True
    warn_return_any = True
    warn_unused_configs = True
    warn_unused_ignores = True
    
    [mypy-responses.*]
    ignore_missing_imports = True
    
  • Python version used: Python 3.9.1
  • Operating system and version: macOS Catalina 10.15.7

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 reproducteur minimal dans testing_inheriting_generics.py et exécutez mypy avec la configuration Python 3.9 indiquée. Suivez la vérification du TypeVar à valeurs restreintes à travers GenericSubClass et GenericSuperClass. Le travail est terminé lorsque les erreurs de constructeur faussement positives et l’erreur d’annotation d’attribut inutile ont disparu, tandis que reveal_type indique builtins.str.

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é
3/5
Temps estimé
1-2 jours
Activité
À l'abandon
Clarté
Clairement spécifiée
Accessibilité débutants
48/100

Recevez les nouvelles issues par e-mail

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