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

Don't emit an "x has no attribute y" error if "y" was defined in __slots__ #5941

Open
exhuma opened this issue Nov 23, 2018 · 6 comments
Open
Labels
false-positive mypy gave an error on correct code feature priority-1-normal

Comments

@exhuma
Copy link

exhuma commented Nov 23, 2018

Python version: 3.5.2
mypy version: 0.630
Bug of Feature request: Feature Request


When defining a class with __slots__ mypy complains that the instance has no attribute, even if it was defined in __slots__.

Consider the following code:

class Foo:
    __slots__ = ['a']


instance = Foo()
instance.a = 10  # <-- False positive ("Foo" has no attribute "a")
instance.b = 20  # <-- True positive

In this case I would expect mypy to accept assigning something to a (using type Any), but still complain about assigning to b.

The docs about __slots__ state that any iterable can be assigned, and contains the following section:

Any non-string iterable may be assigned to slots. Mappings may also be used; however, in the future, special meaning may be assigned to the values corresponding to each key.

So it may also be interesting to allow typing of the entries in __slots__, for example:

class Bar:
    __slots__ = {'a': int}

instance2 = Bar()
instance2.a = 10
instance2.a = 'foo'  # <-- I would expect an error here

The docs about __slots__ don't say anything about ordering of the items. So this should be safe even in older version of Python where dicts did not keep ordering yet.

I also came across #1211 and #1325 which both mention __slots__ but are different enough that this should be a separate issue I think.

@ilevkivskyi ilevkivskyi added feature priority-1-normal false-positive mypy gave an error on correct code labels Nov 23, 2018
@rhocairn
Copy link

Any movement on this? I have some classes using __slots__ and it'd be nice to not get these false positives anymore. What workarounds have folks used in the meantime?

@ilevkivskyi
Copy link
Member

A possible workaround is:

from typing import TYPE_CHECKING

class Data:
    __slots__ = ('x', 'y', 'z')
    if TYPE_CHECKING:
        x: int
        y: int
        z: int

@rhocairn
Copy link

Thanks @ilevkivskyi . I thought about doing that, but unfortunately I'm stuck on python 3.4 for this particular project, and 3.4 doesn't support class annotations. I'm currently setting them in __init__ as a workaround, but interested in alternatives.

@ilevkivskyi
Copy link
Member

Another option on 3.4 is to use type comments:

class Data:
    __slots__ = ('x', 'y', 'z')
    if TYPE_CHECKING:
        x = None  # type: int
        y = None  # type: int
        z = None  # type: int

but I am not sure it is better.

@yashvardhannanavati
Copy link

Hi, can I please ask if there's been any development on this?

@JelleZijlstra
Copy link
Member

@ilevkivskyi's workaround seems pretty good to me. Note you don't even need the if TYPE_CHECKING.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
false-positive mypy gave an error on correct code feature priority-1-normal
Projects
None yet
Development

No branches or pull requests

5 participants