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

Behaviour of not annotated __init__ on inheritance when child class has no parameters #8289

Closed
kprzybyla opened this issue Jan 16, 2020 · 2 comments

Comments

@kprzybyla
Copy link
Contributor

After introduction of #604 you are not longer obligated to specify that __init__ returns None type. However, if you dealing with inheritance and the child class has no parameters, thus it is not annotated if you don't specify the __init__ return type, you unknowingly disable mypy inspection in that class. To make those inspections work you have to explicitly pass --check-untyped-defs argument or simply add return type annotation to __init__.

Now, I'm not saying that it is a bug but this behavior is not so obvious. Especially that after introduction of #604 most people probably removed those explicit annotations from their code or stopped writing them after that point.

Because of that, you can unknowingly make mypy validation pass even thought it shouldn't:

class Base:
    def __init__(self, value: str):
        self.value = value
        reveal_type(self.value)

class Bad(Base):
    def __init__(self):
        super().__init__(value=None)
        reveal_type(self.value)
example_1.py:4: note: Revealed type is 'builtins.str'
example_1.py:10: note: Revealed type is 'Any'
example_1.py:10: note: 'reveal_type' always outputs 'Any' in unchecked functions

However, after adding the annotation (-> None), everything will work as expected:

class Base:
    def __init__(self, value: str):
        self.value = value
        reveal_type(self.value)

class Bad(Base):
    def __init__(self) -> None:
        super().__init__(value=None)
        reveal_type(self.value)
example_2.py:4: note: Revealed type is 'builtins.str'
example_2.py:9: error: Argument "value" to "__init__" of "Base" has incompatible type "None"; expected "str"
example_2.py:10: note: Revealed type is 'builtins.str'
Found 1 error in 1 file (checked 1 source file)

You can also get the same result with the code from example_1.py if you pass --check-untyped-defs parameter to mypy.

Maybe it is worth adding this special case in mypy documentation? Maybe inside the No errors reported for obviously wrong code section in Common issues and solutions chapter?

Versions

mypy 0.761
Python 3.7.4
@JukkaL
Copy link
Collaborator

JukkaL commented Jan 16, 2020

Yeah, this is a known gotcha and it would be useful to document it clearly.

Another idea (though a bit ad hoc) would be to generate a warning if class is otherwise annotated but a no-argument __init__ is missing an annotation.

@ilevkivskyi
Copy link
Member

Fixed by #8303

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants