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.

Asked By: FalcoGer

||

Answers:

You can use forward references:

CallbackType = typing.Callable[['C'], int]
Answered By: InSync

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.

Answered By: Brian61354270
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.