I assume not for very long, because get_original_bases was only added in 3.12 in the first place.
To be clear, for those of us in the back who have been happily ignoring all the typing features: the goal seems to be, to be able to do something like
class IntHandler(Generic[int], Handler):
def handle(self, msg: Msg[int]):
...
and have it type-check in your IDE, and also be able to assert IntHandler.processable is int at runtime?
But - what does the latter piece of information gain you at runtime?
If you don’t already know which Handler subtype you’re using at that point in the process, then presumably you want to use some kind of dispatching system. But that would have to have been set up earlier in the code. If you want that to happen automatically - say, at the time that IntHandler is created - then decorators are perfectly capable of, ahem, handling that.
Well spotted! Yes I was doing cls.__orig_bases__ before that. A little gross, but it worked and I’d seen get_original_bases was coming; it’s actually only switching to that which got me looking at the code and saw the deprecation warning
Yeah I’ve got a messaging queue, and handlers which look like this:
Processable = Foo | Bar
class FooBarHandler(Handler[Processable]):
def handle(self, msg: Msg[Processable]):
match (payload := msg.data):
case Foo():
...
Then as messages come off the queue I can check processable to see if a handler handles it, and be safe in the knowledge that the match would fail with reportMatchNotExhaustive if the implementation was missing.
I’d probably just accept making processable a class method before I refactored to use decorators, but if you have an example of a dispatching with decorators somewhere I’d love to take a look.
Now at runtime when you discover the type being handled you can use it as a key in handler_map to get the class, and instantiate and use that.
That isn’t going to work with type checking, of course; information that you only get at runtime is inherently information that can’t be used before then. If you know ahead of time that you want to handle an int then it doesn’t make any sense to expect the runtime to discover IntHandler for you dynamically while also expecting the type checker to know that the runtime will do so. Just specify IntHandler directly.
Have you tried defining your own descriptor class? What’s been deprecated is specifically classmethod + property, but you could define your own class with a __get__() method. That could itself be generic.