python / python/mypy

Issue inferring type with circular imports/future annotations

Ouverte
#12,874 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

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

Description

Hey! I ran into something which I think is a bug, although its a very small use case and can be fixed pretty easily. This is my first time reporting an issue so let me know if I need to supply anything more info, or if this isn't actually a bug

Bug Report

using future annotations with this circular import seems to cause issues with recognizing types

To reproduce:

create the following structure:

src
 ├──my_directory
     ├── __init__.py
     ├──a.py
 ├──__init__.py
 ├──b.py

with the following code in the files:

src/my_directory/init.py:

from .a import OBJECT_FACTORY, Object

src/my_directory/a.py

from .. import b

class Object():
    pass

class ObjectFactory:
    def make_object(self) -> Object:
        pass

OBJECT_FACTORY = ObjectFactory()

src/init.py

# empty file

src/b.py

from __future__ import annotations
from . import my_directory

def func(bar: Bar):
    print(bar.object)

class Bar:
    def __init__( 
        self,
        _: str, # if you delete this type annotation there will no longer be an error
    ):
        self.object = my_directory.OBJECT_FACTORY.make_object()

then run:
mypy src

Expected Behavior:

Should be able to infer that the type of bar.object is Object from the type annotation of the make_object method.

Actual Behavior

src/b.py:5: error: Cannot determine type of "object"
Found 1 error in 1 file (checked 4 source files)

Some interesting behaviors:

  • if you delete the str type annotation in the Bar class, mypy passes with no issues
  • defining func after Bar class passes with no issues
  • deleting the 'from .. import b' in a.py passes with no issues
  • using a static function make_object with the same annotation instead of in OBJECT_FACTORY will pass with no issues
  • running mypy src/b.py instead of mypy src will pass with no issues
    • subsequently, now running mypy src will actually pass without issues (likely due to .mypy_cache, deleting the cache will re-instate the bug)
  • you can fix this issue if you add the type annotation my_directory.Object to self.object in class Bar
My Environment:

mypy --version

mypy 0.960 (compiled: yes)

python --version

Python 3.8.6

  • Mypy command-line flags: no flags
  • OS: Windows 10

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

Reproduisez le rapport à l’aide des fichiers sous src/my_directory/a.py, src/b.py et des fichiers init.py du package, puis exécutez mypy src après avoir supprimé le cache. Comparez le comportement lorsque l’annotation du constructeur, l’importation circulaire ou future annotations sont modifiées. C’est terminé lorsque l’exemple signalé infère bar.object comme Object sans ajouter d’annotation redondante et ne signale toujours aucune erreur.

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

Évaluation

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

Recevez les nouvelles issues par e-mail

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