Correct Type annotation for __init__
Question:
What is the correct type annotation for a __init__
function in python?
class MyClass:
...
Which of the following would make more sense?
def __init__(self):
# type: (None) -> None
def __init__(self):
# type: (MyClass) -> MyClass
def __init__(self):
# type: (None) -> MyClass
Since we would normally instantiate as myclass = MyClass()
, but the __init__
function itself has no return value.
Answers:
self
should be omitted from the annotation when it is given as a comment, and __init__()
should be marked as -> None
. This is all specified explicitly in PEP-0484.
If you’re using Python 3 (I hope you do), no need to annotate __init__
method at all since mypy 0.641 release if there’s at least one annotated argument, it must always be None
, because it returns nothing. In other cases, mypy will raise an error. This behavior annoyed people for years but eventually it was fixed.
This is what Guido says:
New Feature: Allow Omitting Return Type for __init__
It is now
possible to omit the return type of an annotated __init__
method
without getting an error message. For example:
class Circuit:
def __init__(self, voltage: float):
self.voltage = voltage
In previous mypy versions this would elicit an error message:
error: The return type of "__init__" must be None
This error was just annoying as the only legal return declaration for
__init__
is -> None, so we’ve removed it. Note that this only works if there’s at least one annotated argument! For __init__
methods without
arguments you must still add -> None, otherwise the method will be
treated as untyped, and its body will not be type checked at all.
Examples:
class UntypedExample:
# This method is not type-checked at all!
def __init__(self):
self.voltage = 0.0
class TypedExample:
# This is how to ensure that a 0-argument __init__ is type-checked:
def __init__(self) -> None:
self.voltage = 0.0
Related discussions:
What is the correct type annotation for a __init__
function in python?
class MyClass:
...
Which of the following would make more sense?
def __init__(self):
# type: (None) -> None
def __init__(self):
# type: (MyClass) -> MyClass
def __init__(self):
# type: (None) -> MyClass
Since we would normally instantiate as myclass = MyClass()
, but the __init__
function itself has no return value.
self
should be omitted from the annotation when it is given as a comment, and __init__()
should be marked as -> None
. This is all specified explicitly in PEP-0484.
If you’re using Python 3 (I hope you do), no need to annotate __init__
method at all since mypy 0.641 release if there’s at least one annotated argument, it must always be None
, because it returns nothing. In other cases, mypy will raise an error. This behavior annoyed people for years but eventually it was fixed.
This is what Guido says:
New Feature: Allow Omitting Return Type for
__init__
It is now
possible to omit the return type of an annotated__init__
method
without getting an error message. For example:class Circuit: def __init__(self, voltage: float): self.voltage = voltage
In previous mypy versions this would elicit an error message:
error: The return type of "__init__" must be None
This error was just annoying as the only legal return declaration for
__init__
is -> None, so we’ve removed it. Note that this only works if there’s at least one annotated argument! For__init__
methods without
arguments you must still add -> None, otherwise the method will be
treated as untyped, and its body will not be type checked at all.
Examples:class UntypedExample: # This method is not type-checked at all! def __init__(self): self.voltage = 0.0 class TypedExample: # This is how to ensure that a 0-argument __init__ is type-checked: def __init__(self) -> None: self.voltage = 0.0
Related discussions: