Python generic types that implement protocols
Objects A, B...have attributesnamespace
, I have a function that passes a specific set of namespace
propertiesvalue to filter the list of such objects:
T=TypeVar('T')
def filter(seq: list[T], namespace_values: set[str])-> list[T]:
# Returns a smaller list containing only the items from
# `seq` whose `namespace` are in `namespace_values`
...
This works, but it allows passingwithout any checking errorsX
Properties of typed objectsnamespace
.
I then created a protocol and changed the function to use it:
class Namespaced(Protocol):
namespace: str
def filter(seq: list[Namespaced], namespace_values: set[str])-> list[Namespaced]:
# Returns a smaller list containing only the items from
# `seq` whose `namespace` are in `namespace_values`
...
Now if I pass a stringX
(this is what I want), I get a check error, but I lose the generic:
list_of_a: list[A]=[a1, a2, a3]
output=filter(list_of_a, ['ns1', 'ns2'])
# output is list[Namespaced] instead of list[A]
How to combine generics and protocols so that my function returns a list of type T, And check whether the project of seq
is implemented Namespaced
protocol?
I tried the following but T code> is missing.
def filter(seq: list[Namespaced[T]], namespace_values: set[str])-> list[T]:
# Returns a smaller list containing only the items from
# `seq` whose `namespace` are in `namespace_values`
...
Cheers!
uj5u.com enthusiastic netizens replied:
Use binding type variables and protocols as bindings.Consider the following modules:
(py39) Juans-MacBook-Pro:~ juan$ cat test.py
There are:
from typing import TypeVar, Protocol
from dataclasses import dataclass
class Namespaced(Protocol):
namespace: str
T=TypeVar("T", bound="Namespaced")
@dataclass
class Foo:
namespace: str
@dataclass
class Bar:
namespace: str
id: int
def frobnicate(namespaced: list[T])-> list[ T]:
for x in namespaced:
print(x.namespace)
return namespaced
result1=frobnicate([Foo('foo')])
result2=frobnicate([Bar('bar', 1)])
reveal_type(result1)
reveal_type(result2)
Then mypy gives:
(py39) Juans-MacBook-Pro:~ juan$ mypy--strict test.py
test.py:27: note: Revealed type is "builtins.list[test.Foo*]"
test.py:28: note: Revealed type is "builtins.list[test.Bar*]"
0 Comments