Given following example:
from typing import Protocol, Callable
class Domain(Protocol):
def foo(self, arg: str) -> str:
...
def bar(self, arg: int) -> int:
...
# how to infer this type hint from Domain?
FooFn = Callable[[str], str]
- What is the recommended way - if possible - to extract method signatures of
foo
andbar
into a separateCallable
type, while leaving out theself
-referential context? - Is it possible to inverse this operation, i.e. incorporate a function
Callable
into aProtocol
?
Background
I am using Protocol
s for objects which are to be constructed via dependency injection. All methods need the same set of dependencies, so it makes sense to set them up this way. Now sometimes I’d like to limit methods of Domain
depending on the client and make only one of them available (interface segregation).
It is possible to separate all methods:
class Foo(Protocol):
def foo(self, arg: str) -> str: ...
class Bar(Protocol):
def bar(self, arg: int) -> int: ...
class Domain(Foo, Bar, Protocol): ...
, but I would like to just pass a function with help of closures instead of an object with one method type:
def client(foofn: FooFn):
foofn()
# instead of
def client(myfoo: Foo):
myfoo.foo()
TypeScript for example can leverage lookup types, Parameters
or ReturnType
for call signatures:
type Foo = {
foo: (arg: string) => string
}
type T1 = Foo["foo"] // (arg: string) => string
type T2 = Parameters<T1> // [arg: string]
type T3 = ReturnType<T1> // string
I discovered Concatenate
for Python, and tried to use it for this case, but this seems to rather suited for HOCs.