typing icon indicating copy to clipboard operation
typing copied to clipboard

Type interference: `ProtocolOf`?

Open kai3341 opened this issue 10 months ago • 2 comments

I'm looking the way to interfere existing types explicitly, like typeof / keyof in Typescript

I have 2 use cases:

  • existing function definition -> Callable[...]
  • dataclass __init__ signature / protocol

I think it should look like:

from typing import ProtocolOf

def foo(a: int, b: float) -> float:
    return a * b

FooProtocol = ProtocolOf[foo]

Should be equal to:

class FooProtocol(Protocol):
    def __call__(a: int, b: float) -> float: ...

Or dataclasses:

from dataclasses import dataclass
from typing import ProtocolOf

@dataclass()
class Foo:
    a: int
    b: float

Here I'm not sure which way is better

# way 1:
FooProtocol = ProtocolOf[Foo]

Should be equal to:

class FooProtocol(Protocol):
    def __call__(a: int, b: float) -> Foo: ...
# way 2:
FooInitProtocol = ProtocolOf["Foo.__init__"]

Should be equal to:

class FooInitProtocol(Protocol):
    def __call__(a: int, b: float) -> None: ...

Callable / Protocol to ParamSpec / Returning to use in typing

I see typing.get_args but it doesn't looks suitable for typing. Also

from collections.abc import Callable
from typing import get_args

FooSignature = Callable[[int, float], float]
get_args(FooSignature)  # == [[int, float], float]

Instead of that it should be way to define FooParamSpec / FooReturning

Bonus

there are no way to convert TypedDict to ParamSpec.kwargs UPD: is't bound to typing.Unpack

kai3341 avatar Mar 07 '25 00:03 kai3341

Idea of ProtocolOf is quite raw. Maybe it have to require 2nd parameter keys as (keyof Target)[]. For example:

from dataclasses import dataclass
from typing import ProtocolOf

def foo(a: int, b: float) -> float:
    return a * b


@dataclass()
class Bar:
    a: int
    b: float


FooProtocol = ProtocolOf[foo, ["__call__"]]

# (a: int, b: float) => Bar
BarNewProtocol = ProtocolOf[Bar, ["__new__"]]

kai3341 avatar Mar 07 '25 01:03 kai3341

(I am not a member here, so this is only my personal opinion)

This is lovely idea, I've written a similar idea recently, but as expected I was not the first to come up with an idea on this, for example you will find discussions and further links here for example:

  • https://github.com/python/cpython/issues/107001
  • https://discuss.python.org/t/extract-kwargs-types-from-a-function-signature
  • Possibly there exists a topic on https://github.com/python/typing 🤔

However, typing_extensions is not the right place to discuss or introduce new ideas that still need consensus from the community. You fill find your idea better suited at the two places noted in the https://github.com/python/typing readme:

Improvements to the type system should be discussed on Python's Discourse, and are tracked in the issues in this repository.

Decide if you want to start a new discussion, or bring new input/support to the existing ones. And, hopefully we will get a concrete draft of a PEP on this to add this to the typing-specs. When more points are fledged out we can think of runtime implementations and how type-checkers have to support this.

Daraan avatar Mar 12 '25 11:03 Daraan