python / typing

Python static typing home. Hosts the documentation and a user help forum.
https://typing.readthedocs.io/
Other
1.59k stars 233 forks source link

Typing decorators which enrich a class #1321

Open lijok opened 1 year ago

lijok commented 1 year ago

Hi

I would like to type a decorator which takes as input a class and returns the same class with added attributes, i.e., a subclass. Example:

import typing

_T = typing.TypeVar("_T")

def config(*, /, prefix: str) -> typing.Callable[[typing.Type[_T], ???]:
    def wrap(cls: typing.Type[_T]) -> ???:
        class Subclass(cls):  # or could do cls.prefix = prefix instead of subclassing
            prefix: str = prefix

        return Subclass

    return wrap

@config(prefix="test")
class A:
    ...

print(A.prefix)

Been searching for an answer and experimenting for a few days now and can't find anything concrete. Any help would be much appreciated

Thank you

not-my-profile commented 1 year ago

I think that's currently impossible because of two reasons:

  1. Type intersections aren't implemented yet (#213), which you would need to express Callable[[type[_T]], type[_T] & MyType].
  2. Types can be final, in which case you cannot subclass them, e.g. types.NoneType is marked as final. There does not appear to be a type for final types (typing.Final is something different), which you would need to exclude the type with something like Not[Final] in the TypeVar bound. Note that Not[T] also isn't implemented yet (#801).