Hi all,
I’m struggling to define a protocol with an internal enum class that can be understood by mypy.
python: 3.10
mypy : 1.11.2
Here’s my attempt:
from __future__ import annotations
import enum
from typing import Protocol
class PListItem(Protocol):
class Role(enum.Enum):
...
def get_data(self, role: Role) -> str:
...
The goal is to define a generic container of items. I use the protocol as a bound
:
import enum
from collections.abc import Iterable
from typing import TypeVar, Generic
T = TypeVar('T', bound=PListItem)
class ListOfItems(Generic[T]):
_collections: list[T]
_roles: dict[int, T.Role]
def __init__(self,collections: Iterable[T], type_data: type[T]):
self._collections = list(collections)
roles = type_data.Role
self._roles = dict(enumerate(roles))
class Item:
def __init__(self, name: str):
self.name = name
class Role(enum.Enum):
NAME: str = "name"
def get_data(self, role: Role) -> str:
if role == self.Role.NAME:
return self.name
return ""
if __name__ == '__main__':
d1 = Item("data1")
d2 = Item("data2")
lst = ListOfItems([d1, d2], type_data=Item)
mypy gives me to errors :
error: Name "T.Role" is not defined [name-defined]
error: Value of type variable "T" of "ListModel" cannot be "Item" [type-var]
I don’t understand why T.Role
is not recognized, and I couldn’t find examples of protocols with attached classes.
Is there a better way to define the typing in this case?