[Python] How to define a Python Protocol that is Callable with any number of keyword arguments...

Discussão em 'Python' iniciado por Stack, Janeiro 19, 2025.

  1. Stack

    Stack Membro Participativo

    How do I define a Python protocol for a type that is:

    • Callable
    • with any number of keyword arguments of any type
    • that returns a value of a specified type

    This is my attempt:

    from typing import Any, Protocol, TypeVar

    T = TypeVar("T", covariant=True)


    class Operation(Protocol[T]):
    def __call__(self, **kwargs: Any) -> T:
    pass


    # some example functions that should be a structural sub-type of "Operation[str]"
    def sumint(*, x: Any, y: Any) -> str:
    return f"{x} + {y} = {x + y}"


    def greet(*, name: Any = "World") -> str:
    return f"Hello {name}"


    # an example function that takes an "Operation[str]" as an argument
    def apply_operation(operation: Operation[str], **kwargs: Any) -> str:
    return operation(**kwargs)


    if __name__ == "__main__":
    print(apply_operation(sumint, x=2, y=2))
    # prints: 2 + 2 = 4
    print(apply_operation(greet, name="Stack"))
    # prints: Hello Stack


    However, mypy produces the error:

    example.py:26: error: Argument 1 to "apply_operation" has incompatible type "Callable[[NamedArg(Any, 'x'), NamedArg(Any, 'y')], str]"; expected "Operation[str]"
    example.py:28: error: Argument 1 to "apply_operation" has incompatible type "Callable[[DefaultNamedArg(Any, 'name')], str]"; expected "Operation[str]"
    Found 2 errors in 1 file (checked 1 source file)


    What am I doing wrong? How do I make mypy happy?

    Continue reading...

Compartilhe esta Página