• Re: Any way to "subclass" typing.Annotated?

    From ram@[email protected] (Stefan Ram) to comp.lang.python on Wed Jan 29 13:45:30 2025
    From Newsgroup: comp.lang.python

    [email protected] (Stefan Ram) wrote or quoted:
    # The factory function
    def AbstractClassVariable(type_: T) -> Any:
    return Annotated[type_, abstract]

    Alright, so now I've got something here that actually compiles!

    Python

    from typing import Annotated, TypeVar, Any, Generic

    # This is your "abstract" flag. It's just a unique object.
    abstract = object()

    # A generic type variable to keep things flexible.
    T = TypeVar("T")

    # Define AbstractClassVariable as a class instead of a function
    class AbstractClassVariable(Generic[T]):
    def __class_getitem__(cls, item):
    return Annotated[item, abstract]

    class AbstractType(type):
    def __new__(cls, name, bases, namespace):
    for key, value in namespace.items():
    if isinstance(value, type(Annotated)):
    if abstract in value.__metadata__:
    raise TypeError(f"Abstract class variable '{key}' must be defined")

    return super().__new__(cls, name, bases, namespace)

    class Foo(object, metaclass=AbstractType):
    acv: AbstractClassVariable[int]


    --- Synchronet 3.20c-Linux NewsLink 1.2
  • From ram@[email protected] (Stefan Ram) to comp.lang.python on Wed Jan 29 13:48:00 2025
    From Newsgroup: comp.lang.python

    [email protected] (Stefan Ram) wrote or quoted:
    Option 2: Custom Wrapper Class

    To compile, this should read:

    Python

    from typing import Annotated, TypeVar, Generic, Any

    # Your trusty "abstract" flag, chillin' like it's at Venice Beach
    abstract = object()

    # Type variable, as constant as the NorCal fog
    T = TypeVar("T")

    class AbstractClassVariable(Generic[T]):
    def __class_getitem__(cls, item: T) -> Any:
    return Annotated[item, abstract]


    --- Synchronet 3.20c-Linux NewsLink 1.2
  • From Fabien LUCE@[email protected] to comp.lang.python on Fri Jan 31 11:41:22 2025
    From Newsgroup: comp.lang.python

    Maybe you'd better use descriptors?

    On Tue, 28 Jan 2025 at 23:03, Ian Pilcher via Python-list < [email protected]> wrote:

    (Note: I have mail delivery disabled for this list and read it through GMane. Please copy me on any responses, so that I can respond with
    proper threading.)

    From the things that I probably shouldn't spend my free time on
    department ...

    As background, I'm working on a project that is going to involve a bunch
    of abstract classes and dynamic types, and I've found that Python's
    existing abstract class implementation leaves a lot to be desired, particularly the inability to create abstract class variables and class methods. Having been seduced by the Siren song of Python's flexibility,
    I've been rolling my own implementation.

    Now to my question.

    I'm currently using annotations to create abstract class variables, for example:

    class Foo(object, metaclass=AbstractType):

    acv: Annotated[int, abstract]

    ('abstract' is simply a unique "flag" object.)

    This works just fine, but it's somewhat un-idiomatic. What I'd like to
    be able to do is create my own type, so that I could do something like
    this:

    class Foo(object, metaclass=AbstractType):

    acv: AbstractClassVariable[int]

    Essentially I'd like to create "subclass" of typing.Annotated that
    always sets the metadata to 'abstract'. Thus far, I haven't found a
    way to do this, as typing.Annotated can't be subclassed.

    Anyone have any ideas?

    --
    ========================================================================
    If your user interface is intuitive in retrospect ... it isn't intuitive ========================================================================

    --
    https://mail.python.org/mailman/listinfo/python-list

    --- Synchronet 3.20c-Linux NewsLink 1.2