There are a few ways to deal with that. One is to declare the properties directly in the subclass:
class Inject:
def __init_subclass__(cls):
cls.injected = 42
class Child(Inject):
injected: int
print(Child().injected) # 42
This technique isn't too useful in practice, though it has its place (e.g. when creating ctypes.Structures). But there's a clever way to simplify this. Remember that the subclass is a subclass -- it inherits from Inject:
import typing as t
class Inject:
injected: t.ClassVar[int]
def __init_subclass__(cls):
cls.injected = 42
class Child(Inject):
pass
print(Child().injected) # 42
(ClassVar[int] ensures that type checkers know it's a variable attached to the class, not each instance.)
yes you can do that, but if you want to do say, what dataclasses does, where it collects all the Field objects and creates a typed `__init__` method, typing can't do that without plugins. all the current typecheckers hardcode the specific behavior of "dataclasses" without there being any pep that allows other systems (like ORMs) to take advantage of the same thing without writing mypy plugins or simply not working for other type checkers that don't allow plugins.
im not really sure (highly doubtful, much simpler ideas like being able to make your own Tuple subclass are still not ready for primetime) but this would be a pretty tough pep to allow the general "dataclass" concept to be available to other libraries that want to use the same pattern, but not use dataclasses.