I want to use type hinting for a function with no parameters
from typing import Callable
def no_parameters_returns_int() -> int:
return 7
def get_int_returns_int(a: int) -> int:
return a
def call_function(next_method: Callable[[], int]):
print(next_method())
call_function(no_parameters_returns_int) # no indication of error from IDE expected
call_function(get_int_returns_int) # expected an indication of error from IDE
I expected PyCharm to mark the line when I pass a function that does take parameters.
Also tried Callable[[None], int]
and Callable[[...], int]
. However the first one hinting the passed function to receive a None
type argument, second one hinting the passed function to receive at least one argument.
Is it possible to hint that the passed function receives no arguments?
Is it possible to hint that the passed function receives no arguments?
The correct way to type hint a Callable
without arguments is stated in:
"Fundamental building blocks", PEP 483
Callable[[t1, t2, ..., tn], tr]
. A function with positional argument typest1
etc., and return typetr
. The argument list may be empty n==0.
An explicit example is given in:
"Covariance and Contravariance", PEP 483
- Callable[[], int] is a subtype of Callable[[], float]. - Callable[[], Manager] is a subtype of Callable[[], Employee].
And also in:
from typing import Callable def feeder(get_next_item: Callable[[], str]) -> None: # Body
The built-in name None
should be distinguished from the type None (the first is used to access the second):
3.2. The standard type hierarchy, Data Model
None
- This type has a single value. There is a single object with this value. This object is accessed through the built-in name
None
.
The syntax and meaning of the built-in name None
used as a type hint is a special case:
When used in a type hint, the expression
None
is considered equivalent totype(None)
.
Considering the above, it's less of a surprise the following two ways -of trying to write a Callable
type hint of a function without arguments- are wrong:
Callable[[None], tr]
Callable[[type(None)], tr]
The Ellipsis in a Callable
type hint simply means:
Note that there are no square brackets around the ellipsis. The arguments of the callback are completely unconstrained in this case (and keyword arguments are acceptable).
Since it is "unconstrained" the following is unlikely to cause the static type checker to issue any warnings because of arguments:
Callable[..., tr]
Worth noting, the relation between Callable
, Any
and ...
(Ellipsis).
As well, a bare Callable in an annotation is equivalent to Callable[..., Any]
Finally, if you run your code through MyPy the expected warning is in fact issued:
main.py:13: error: Argument 1 to "call_function" has incompatible type "Callable[[int], int]"; expected "Callable[[], int]" Found 1 error in 1 file (checked 1 source file)
I checked your example in PyCharm 2020.2 Pro and the IDE does not issue the above warning. Notice that PyCharm uses its own implementation of PEP 484, and their static type checker has been know to have bugs.
I think you found a bug...
Final Note: Running type(None)
gives NoneType
. In Python 3 NoneType
isn't exposed for import although in Python 2 it was importable.
EDIT: For some reason Python 3.10 is reintroducing types.NoneType
.