Home > OS >  PyCharm says unfilled parameters even though all parameters are optional
PyCharm says unfilled parameters even though all parameters are optional

Time:10-02

I have a function which should receive another function as an argument, I defined that parameter annotation as:

input_function: Callable[
    [
        Optional[InputType],
        Optional[Sequence[str]],
        Optional[bool]
    ],
    Awaitable[str]
] = func

And also, my func function:


async def func(input_type: InputType = None, formats: Sequence[str] = (), *, hide: bool = False) -> str: ...

The function signature and parameter annotation should be the same. However, when I call that function with only one parameter (as all of the parameters are optional) PyCharm says that there are unfilled parameters:

enter image description here

CodePudding user response:

TLDR: Define the signature as a Protocol with __call__, not a Callable.

from typing import Protocol


class InputFunction(Protocol):
    async def __call__(self, input_type: InputType = None, formats: Sequence[str] = (), *, hide: bool = False) -> str: ...

input_function: InputFunction = func

The Callable type can only express a limited kind of signatures: Explicit positional parameters such as Callable[[A, B], R] or arbitrary parameters such as Callable[..., R]. Typing one of its parameter as Optional[T] means it must be "a T or None", not that it can be omitted.

In contrast, a Protocol's __call__ method allows to define the signature using regular definition syntax, including all of its features such as default values.

Callback Protocols

Protocols can be used to define flexible callback types that are hard (or even impossible) to express using the Callable[...] syntax, such as variadic, overloaded, and complex generic callbacks. They are defined with a special __call__ member:

While a Protocol is a class, it matches structurally: defining it with just a __call__ method merely encodes "callable object of same signature", and functions of same signature satisfy this as well.

Note that the self parameter is required on the __call__ definition, but not used to check whether signatures match.

CodePudding user response:

The documentation for typing.Optional states:

Note that this is not the same concept as an optional argument, which is one that has a default.

And the documentation for typing.Callable states:

There is no syntax to indicate optional or keyword arguments

As such, it is not possible to accurately define the type of the function the way you want it.

  • Related