False positive for Union[type, ...] and inspect.isclass()
Personne n'a encore pris cette issue.
- Langage dominant
- Python
- Étoiles
- 20.6k
- Forks
- 3.3k
- Métriques de merge des PR
- Métriques de PR en attente
Description
Bug Report
When a variable's type is declared as a union that includes type (or typing.Type[...]), mypy does not take into account whether usage of that variable occurs inside of an if inspect.isclass(...) conditional block, leading to false positives.
To Reproduce
Python code
from inspect import isclass
registry: dict[str, type] = {}
def decorator_factory(arg: str | type):
if isclass(arg):
registry[arg.__name__.lower()] = arg
return arg
else:
def decorator(cls: type):
registry[arg] = cls
return cls
return decorator
@decorator_factory
class Foo:
pass
@decorator_factory("alt")
class Bar:
pass
Expected Behavior**
mypy reports no errors
Actual Behavior
main.py:11: error: Invalid index type "str | type" for "dict[str, type]"; expected type "str" [index]
Found 1 error in 1 file (checked 1 source file)
Workaround
Using typing.cast to narrow the union explicitly.
Python code
from inspect import isclass
from typing import cast, TYPE_CHECKING
registry: dict[str, type] = {}
def decorator_factory(arg: str | type):
if isclass(arg):
registry[arg.__name__.lower()] = arg
return arg
else:
if TYPE_CHECKING:
arg = cast(str, arg)
def decorator(cls: type):
registry[arg] = cls
return cls
return decorator
@decorator_factory
class Foo:
pass
@decorator_factory("alt")
class Bar:
pass
Your Environment
- Mypy version used: 1.7.1
- Mypy command-line flags: (mypy-play defaults)
- Mypy configuration options from
mypy.ini(and other config files): (mypy-play defaults) - Python version used: 3.12
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez par exécuter le reproducer lié avec mypy et comparez l’erreur signalée avec le comportement attendu autour de inspect.isclass() et de Union[type, ...]. Suivez ensuite le chemin de réduction de type pour inspect.isclass, puis ajoutez une couverture de régression pour le reproducer. Vérifiez que mypy ne signale aucune erreur sans le contournement avec cast.
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
- 38/100