Reputation: 8888
Seeing kind of contradictory results:
class A:
def __init__(self, a: int):
pass
The snippet above passes a mypy
test, but the one below doesn't.
class A:
def __init__(self):
pass
Any idea why?
Upvotes: 7
Views: 3009
Reputation: 18598
This is documented here.
When you have at least one (annotated) argument for a function, it is considered (at least partially) typed. When neither arguments nor return values are annotated, the function is considered untyped.
This distinction is important because by default, mypy
does not check the bodies of untyped functions at all. This behavior is configurable via check_untyped_defs
.
Note that the complaint about the missing return type only arises, if you set disallow_untyped_defs
(or strict
). Otherwise neither of your examples will trigger an error.
The __init__
method receives special treatment because people complained that always returns None
and they did not want to explicitly write out the return type accordingly. This is why that behavior is so inconsistent.
class A:
def __init__(self, x: int): # this is fine with `mypy`
pass
def foo(self, x: int):
print("hi")
class B:
def __init__(self):
pass
def foo(self):
print("hi")
Out of all these methods, only A.__init__
is considered fully typed (because of the implicit None
return by __init__
). All the other methods will trigger errors with disallow_untyped_defs
set:
error: Function is missing a return type annotation [no-untyped-def]
I don't particularly like this approach, but that is the way they decided to handle it.
Upvotes: 9