Skip to content

Member is not assignable error when accessing a module member #5439

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

Closed
gilbsgilbs opened this issue Aug 9, 2018 · 3 comments · Fixed by #13513
Closed

Member is not assignable error when accessing a module member #5439

gilbsgilbs opened this issue Aug 9, 2018 · 3 comments · Fixed by #13513
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code needs discussion priority-1-normal

Comments

@gilbsgilbs
Copy link

Hi,

This issue seems close to the one that was fixed in this PR.

  • Are you reporting a bug, or opening a feature request?

I'm reporting a bug.

  • Please insert below the code you are checking with mypy,
    or a mock-up repro if the source is private. We would appreciate
    if you try to simplify your case to a minimal repro.
import functools

class Foo:
    bar = functools

foo = Foo()
foo.bar  # error: Member "bar" is not assignable
  • What is the actual behavior/output?
test.py:7: error: Member "bar" is not assignable
  • What is the behavior/output you expect?

No Error. I'm just accessing, not mutating.

  • What are the versions of mypy and Python you are using?
    Do you see the same issue after installing mypy from Git master?
$ mypy --version
mypy 0.620

Same error on master.

  • What are the mypy flags you are using? (For example --strict-optional)

No flags. Just raw mypy test.py

If you need any further information, please let me know.
Thank you in advance.

@ilevkivskyi
Copy link
Member

Thanks for reporting!

This particular error is probably easy to fix, but then the best type we can give to foo.bar is types.ModuleType. Supporting things like foo.bar.reduce may be much harder.

@ilevkivskyi ilevkivskyi added bug mypy got something wrong needs discussion priority-1-normal false-positive mypy gave an error on correct code labels Aug 9, 2018
@gilbsgilbs
Copy link
Author

gilbsgilbs commented Aug 9, 2018

Many thanks @ilevkivskyi for your insanely quick reply and tagging.

This particular error is probably easy to fix, but then the best type we can give to foo.bar is types.ModuleType. Supporting things like foo.bar.reduce may be much harder.

You know the implications way better than me, but just to be sure I understand, do you mean that:

import functools

class Foo:
    bar = functools.reduce

foo = Foo()
foo.bar
  • foo.bar will loose type safety?
  • foo.bar line will raise an error, just as reproduced in this issue?

Also, does this mean that, if in my first post example I write r = foo.bar.reduce, I will loose type safety on r?

Anyways, this would probably be preferable than raising an error since the use-case sounds 100% legitimate to me, wouldn't it?

@ilevkivskyi
Copy link
Member

do you mean that...

No, I meant exactly your code in the original post.

ilevkivskyi added a commit that referenced this issue Aug 27, 2022
Fixes #5018 
Fixes #5439
Fixes #10850 

The implementation is simple but not the most beautiful one. I simply add a new slot to the `Instance` class that represents content of the module. This new attribute is short lived (it is not serialized, and not even stored on variables etc., because we erase it in `copy_modified()`). We don't need to store it, because all the information we need is already available in `MypyFile` node. We just need the new attribute to communicate between the checker and `subtypes.py`.

Other possible alternatives like introducing new dedicated `ModuleType`, or passing the symbol tables to `subtypes.py` both look way to complicated. Another argument in favor of this new slot is it could be useful for other things, like `hasattr()` support and ad hoc callable attributes (btw I am already working on the former).

Note there is one important limitation: since we don't store the module information, we can't support module objects stored in nested positions, like `self.mods = (foo, bar)` and then `accepts_protocol(self.mods[0])`. We only support variables (name expressions) and direct instance, class, or module attributes (see tests). I think this will cover 99% of possible use-cases.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code needs discussion priority-1-normal
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants