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

Initializer not checked against declared type when annotating using self.x #7398

Closed
sotte opened this issue Aug 27, 2019 · 7 comments
Closed
Labels
bug mypy got something wrong priority-0-high

Comments

@sotte
Copy link

sotte commented Aug 27, 2019

mypy accepts instance variables that are instantiated as None even though the type indicates int. This is not the case for equivalent dataclasses. I'm not sure if this is a bug or intended behavior.

Here is a minimal example:

from dataclasses import dataclass, field


class Foo:
    def __init__(self):
        self.bar: int = None


@dataclass
class Foo2:
    bar: int = None
    bar2: int = field(default=None)

This is how I check the fiel: mypy mypy_demo.py.

Here the resulting error msgs:

mypy_demo.py:11: error: Incompatible types in assignment (expression has type "None", variable has type "int")
mypy_demo.py:12: error: Incompatible types in assignment (expression has type "None", variable has type "int")

I did not find anything helpful in the dataclass section: https://mypy.readthedocs.io/en/latest/additional_features.html#dataclasses

I'm testing with Mypy version 0.701.

@JukkaL
Copy link
Collaborator

JukkaL commented Aug 27, 2019

Thanks for reporting this! The initialization in Foo should be rejected by mypy. This is quite serious, as even a totally bogus initializer is accepted:

class Foo:
    def __init__(self):
        self.bar: int = 'x'  # No error even though this is clearly wrong!

@JukkaL JukkaL added bug mypy got something wrong priority-0-high labels Aug 27, 2019
@JukkaL JukkaL changed the title dataclass and class differ when assigning instance variable None to a different type Initializer not checked against declared type when annotating using self.x Aug 27, 2019
@ilevkivskyi
Copy link
Member

Adding -> None helps. Note however --check-untyped-defs is broken for __init__(), see #7309 (there are also couple issues mentioned that we may potentially close as duplicates).

@ilevkivskyi
Copy link
Member

#7291 is also related (I think it was discussed whether we should just assume the -> None by default in other issues. IIRC there is no consensus because either option has drawbacks, so status quo wins)

@JukkaL
Copy link
Collaborator

JukkaL commented Aug 27, 2019

Oops, #3948 bites again.

@sotte
Copy link
Author

sotte commented Aug 28, 2019

Thanks for the quick response!

Just for completeness sake: my assumption was, that I can do self.bar: int = None because it's also ok to do def bob(a: int = None): print(a). That is that an implicit Optional would be used.

from dataclasses import dataclass, field


class Foo:
    def __init__(self):
        self.bar: int = None

    def bob(self, a: int = None):
        print(a)


@dataclass
class Foo2:
    bar: int = None
    bar2: int = field(default=None)

@JelleZijlstra
Copy link
Member

Implicit optional may be allowed in some cases but it's deprecated. It's preferable to explicitly add Optional.

@sotte
Copy link
Author

sotte commented Aug 29, 2019

Thanks for clarification!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong priority-0-high
Projects
None yet
Development

No branches or pull requests

4 participants