Reputation: 1442
from typing import Callable
def f() -> Callable:
return f
How to explicitly define f
's type? like Callable[[], Callable]
I think it is slightly like a linked list, but I can't implement it.
from typing import Union
class Node:
def __init__(self, val):
self.val = val
self.next: Union[Node, None] = None
Upvotes: 4
Views: 1684
Reputation: 23674
I think @chepner's answer is great. If you really do want to express this as a recursive Callable type, then you could restructure the function as a callable class and do something like this:
from __future__ import annotations
class F:
def __call__(self) -> F:
return self
f = F()
You can test this with mypy to see that it maintains its type on future calls:
g = f()
h = g(1) # Too many arguments for "__call__" of "F"
i = h()
j = i(2) # Too many arguments for "__call__" of "F"
k = j()
Upvotes: 5
Reputation: 532238
Ideally, you could use typing.Literal
to specify the exact function being returned, but that doesn't work for a number of reasons:
There's no way to refer to f
using typing.Literal
. typing.Literal['f']
is the string literal 'f'
, not a forward reference to the function about to be defined.
f
doesn't necessarily refer to the function being defined. It's a free variable that could refer to something else entirely by the time the function is actually called.
OK, let's loosen our restriction. Let's try to define a type of function that returns a function of its own type. We can at least write a valid type hint:
T = typing.Callable[[],'T']
def f() -> T:
return f
but this is only useful as documentation; mypy
doesn't yet know how to handle recursively defined types like this.
So let's try
T1 = Callable[[], 'T2']
T2 = Callable[[], T1]
def f() -> T2:
return f
Oops, mypy
doesn't like cyclic definitions, either.
So we're left with your original idea, of using the overlay broad type of functions that take no arguments and returns some callable.
def f() -> Callable[[], Callable]:
return f
The problem with the comparison to Node
is that there's no type-level recursion involved; next
simply refers to some value of type Node
.
Upvotes: 4