Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mypy gives valid-type errors with some import methods, seemingly inconsistently #10822

Closed
Deimos opened this issue Jul 14, 2021 · 3 comments · Fixed by #11708
Closed

mypy gives valid-type errors with some import methods, seemingly inconsistently #10822

Deimos opened this issue Jul 14, 2021 · 3 comments · Fixed by #11708
Labels
bug mypy got something wrong

Comments

@Deimos
Copy link
Contributor

Deimos commented Jul 14, 2021

Bug Report

Sorry in advance, this is going to be an non-ideal bug report. I've spent over an hour now trying to figure out how to create a simpler project that reproduces the issue, but I haven't been able to cause it to happen, so I'm going to have to use my real project as the example.

I recently updated mypy from 0.790 to 0.910, and it started giving a number of [valid-type] errors related to some of my classes, saying that I couldn't use them as type annotations. Here's one example:

tildes/models/group/group_subscription.py: note: In class "GroupSubscription":
tildes/models/group/group_subscription.py:43: error: Module
"tildes.models.user.User" is not valid as a type  [valid-type]
        user: User = relationship("User", innerjoin=True, backref="subscri...
              ^

I had to make some different modifications to how I was importing the classes to get rid of these errors:

  1. If the class was from inside the same package, it had to be imported like from .group import Group. Using the full path like from tildes.models.group import Group would result in an error.
  2. In one specific package, I had to specify the import even more exactly. These ones required me to do from tildes.models.user.user import User, where every other "sibling" package can do from tildes.models.user import User without mypy complaining (the class is imported in the __init__.py to allow that).

All of the changes I needed to make are in this commit if you want to look (there are also some fixes for legitimate typing issues in there too).

The second type of change above is the more interesting one, because I have some modules that are very close to identical, but require different import styles to make mypy happy.

If you compare these two files:

They're almost identical - the first one is a link between User+Group, and the other is a link between User+Topic. However, mypy needs me to do the from tildes.models.user.user import User import in group_subscription.py, but is fine with from tildes.models.user import User in topic_vote.py.

To Reproduce

(Sorry again for having to use my actual project here)

  1. Clone https://gitlab.com/tildes/tildes
  2. Open terminal inside the repo directory
  3. git checkout 9720040cb9a7c75fd590322479e821a0e8f13497 -- tildes/tildes/models/group/group_subscription.py (reverts the fix I made to that single file)
  4. Change into the tildes/ subdirectory, and run mypy .
  5. Get 4 errors, two of which are from files other than the one that was reverted:
tildes/models/user/user_permissions.py: note: In class "UserPermissions":
tildes/models/user/user_permissions.py:31: error: Module "tildes.models.group.Group" is not valid as a
type  [valid-type]
        group: Group = relationship("Group", innerjoin=True)
               ^
tildes/models/user/user_group_settings.py: note: In class "UserGroupSettings":
tildes/models/user/user_group_settings.py:34: error: Module "tildes.models.group.Group" is not valid as
a type  [valid-type]
        group: Group = relationship("Group", innerjoin=True)
               ^
tildes/models/group/group_subscription.py: note: In class "GroupSubscription":
tildes/models/group/group_subscription.py:43: error: Module "tildes.models.user.User" is not valid as a
type  [valid-type]
        user: User = relationship("User", innerjoin=True, backref="subscriptions")
              ^
tildes/models/group/group_subscription.py: note: In member "__init__" of class "GroupSubscription":
tildes/models/group/group_subscription.py:46: error: Module "tildes.models.user.User" is not valid as a
type  [valid-type]
        def __init__(self, user: User, group: Group):
                                 ^
Found 4 errors in 3 files (checked 145 source files)

Expected Behavior

mypy should support classes imported in any of the ways Python supports.

Actual Behavior

mypy seems to require specific import methods in certain cases.

Your Environment

@Deimos Deimos added the bug mypy got something wrong label Jul 14, 2021
@JelleZijlstra
Copy link
Member

This sounds similar to #10661.

@Deimos
Copy link
Contributor Author

Deimos commented Jul 15, 2021

Yes, definitely looks like it could be the same issue (I like that we both have similar apologies for not being able to simplify it too).

The problems I was seeing were inside a Vagrant VM (Virtualbox) running on a Windows host, with the code in a synced folder from the host, so it seems very similar to what @paulcwatts showed there with Docker. My repo includes the Vagrantfile, so you should be able to get an equivalent setup easily with Vagrant and Virtualbox if you have a Windows/Mac machine available (for a case-insensitive host).

Looking inside the .mypy_cache directory, I see some things that look like they could be wrong:

  • Inside the tildes/models/group directory, there are Group.data.json and Group.meta.json (both capitalized), but inside the user directory there are User.data.json and user.meta.json (only one capitalized).
  • In Group.meta.json:
    • "id": "tildes.models.group.Group" (a class)
    • "path": "/opt/tildes/tildes/models/group/Group.py" (worth noting: this capitalized filename does not exist, the filename is all lowercase)
  • In user.meta.json:
    • "id": "tildes.models.user.user" (a module)
    • "path": "./tildes/models/user/user.py"

So it does seem like there might be conflicts in the cache due to case insensitivity, where the class and module are getting mixed up.

@Deimos
Copy link
Contributor Author

Deimos commented Jul 15, 2021

It's probably not surprising, but since I tested it: disabling incremental mode or using an sqlite cache both don't help.

hauntsaninja pushed a commit to hauntsaninja/mypy that referenced this issue Dec 10, 2021
JukkaL pushed a commit that referenced this issue Dec 13, 2021
Originally added in #10093

Fixes #11690, fixes #10661, fixes #10822

Co-authored-by: hauntsaninja <>
tushar-deepsource pushed a commit to DeepSourceCorp/mypy that referenced this issue Jan 20, 2022
Originally added in python#10093

Fixes python#11690, fixes python#10661, fixes python#10822

Co-authored-by: hauntsaninja <>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants