How to alias a type used in a class before it is declared?
Question:
I have code similar to this example
import typing
class C():
def __init__(self, callback: typing.Callable[[C], int]):
self._callback = callback
def getCallback() -> typing.Callable[[C], int]:
return self._callback
class C2():
def __init__(self, cInstance: C):
self._cInstance = cInstance
def f() -> typing.NoReturn:
self._cInstance.getCallback()(self.cInstance)
and I want to add a type alias for typing.Callable[[C], int]
However when I try to do this
import typing
CallbackType = typing.Callable[[C], int] # ERROR: C not defined
class C():
def __init__(self, callback: CallbackType):
self._callback = callback
def getCallback() -> CallbackType:
return self._callback
class C2():
def __init__(self, cInstance: C):
self._cInstance = cInstance
def f() -> typing.NoReturn:
self._cInstance.getCallback()(self.cInstance)
I get the error that C
was not defined at the time. If I define the CallbackType after class C
, then CallbackType is not defined in C
‘s __init__
. In the example the typing is short enough, but in my actual code it’s quite complex, which is why I want to add the alias.
Answers:
You can use forward references:
CallbackType = typing.Callable[['C'], int]
Add the future statement
from __future__ import annotations
to the top of your module (available in Python 3.7 and onwards). This enables the postponed evaluation of type hints. With postponed evaluation, forward references to work out of the box. No explicit quoting is required, since all type hints become implicitly "quoted". Your code will then work as-is:
from __future__ import annotations
CallbackType = typing.Callable[[C], int] # forward reference OK
class C:
...
See also the question from __future__
import annotations and PEP 563 for more details.
I have code similar to this example
import typing
class C():
def __init__(self, callback: typing.Callable[[C], int]):
self._callback = callback
def getCallback() -> typing.Callable[[C], int]:
return self._callback
class C2():
def __init__(self, cInstance: C):
self._cInstance = cInstance
def f() -> typing.NoReturn:
self._cInstance.getCallback()(self.cInstance)
and I want to add a type alias for typing.Callable[[C], int]
However when I try to do this
import typing
CallbackType = typing.Callable[[C], int] # ERROR: C not defined
class C():
def __init__(self, callback: CallbackType):
self._callback = callback
def getCallback() -> CallbackType:
return self._callback
class C2():
def __init__(self, cInstance: C):
self._cInstance = cInstance
def f() -> typing.NoReturn:
self._cInstance.getCallback()(self.cInstance)
I get the error that C
was not defined at the time. If I define the CallbackType after class C
, then CallbackType is not defined in C
‘s __init__
. In the example the typing is short enough, but in my actual code it’s quite complex, which is why I want to add the alias.
You can use forward references:
CallbackType = typing.Callable[['C'], int]
Add the future statement
from __future__ import annotations
to the top of your module (available in Python 3.7 and onwards). This enables the postponed evaluation of type hints. With postponed evaluation, forward references to work out of the box. No explicit quoting is required, since all type hints become implicitly "quoted". Your code will then work as-is:
from __future__ import annotations
CallbackType = typing.Callable[[C], int] # forward reference OK
class C:
...
See also the question from __future__
import annotations and PEP 563 for more details.