简体   繁体   中英

Type hinting Callable with no parameters

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 Callabale[[None], int] and Callabale[[...], 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 types t1 etc., and return type tr . 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:

"Callable" , PEP 484

 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:

"Using None" , PEP 484

When used in a type hint, the expression None is considered equivalent to type(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:

"Callable" , PEP 484

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).

"The Any type" , PEP 484

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...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM