Open glyph opened 1 year ago
This probably requires some implementation support from the zope.interface side, but I find myself wanting to be able to write this:
from dataclasses import dataclass from typing import Generic, TypeVar from zope.interface import Interface, implementer T = TypeVar("T") class IA(Generic[T], Interface): def m() -> T: ... @implementer(IA) @dataclass class A(Generic[T]): _v: T def m(self) -> T: return self._v a: IA[int] = A(3)
This actually appears to do what I want at type-check time! But then it (somewhat obviously) crashes at runtime.
This horrible hack almost works though, which suggests that this could work properly with some very small changes:
# from __future__ import annotations from dataclasses import dataclass from typing import Generic, TypeVar, TYPE_CHECKING from zope.interface import Interface, implementer T = TypeVar("T") if TYPE_CHECKING: from typing import Generic as GenericInterface else: from zope.interface.interface import InterfaceClass class SpecialInterfaceClass(InterfaceClass): def __getitem__(self, key): return self EmptyInterface = SpecialInterfaceClass("<Empty>", __module__=__name__) class GenericInterfaceClass: def __getitem__(self, typevars): return EmptyInterface GenericInterface = GenericInterfaceClass() class IA(Interface, GenericInterface[T]): def m() -> T: ... @implementer(IA) @dataclass class A(Generic[T]): _v: T def m(self) -> T: return self._v @dataclass class B: ... a: IA[int] = A(3) # works, hooray a = B() # error, hooray a = A("oops") # no error, boo
This probably requires some implementation support from the zope.interface side, but I find myself wanting to be able to write this:
This actually appears to do what I want at type-check time! But then it (somewhat obviously) crashes at runtime.
This horrible hack almost works though, which suggests that this could work properly with some very small changes: