You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
singledispatchmethod should expose registry of all known overloads #87109
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=Nonecreated_at=<Date2021-01-16.21:46:19.079>labels= ['type-feature', 'library', '3.11']
title='singledispatchmethod should expose registry of all known overloads'updated_at=<Date2021-12-09.15:14:16.576>user='https://github.com/Kentzo'
defreceive_message_on_thread(message):
if ...: # only signal to asyncio if message can be handledmessages.append(message)
loop.call_soon_threadsafe(condition.notify_all)
else:
...
asyncdefprocess_messages_on_asyncio():
whileTrue:
awaitcondition.wait_for(lambda: len(messages) >0)
whilelen(messages):
m=messages.pop(0)
...
Here messages are delivered outside of asyncio in a separate thread and thus they need to be forwarded into asyncio for further processing in the app. If the flow of messages is high it is desirable to filter inside the thread handler before signaling asyncio.
There are multiple approaches to describe which messages can be handled by the asyncio processor, but singledispatchmethod is the most elegant as it allows to keep everything in one place without if/else or code duplication.
Having a registry (trivially) exposed would allow to write the condition as isinstance(message, tuple(on_message.registry.keys())).
I do not think that isinstance(message, tuple(on_message.registry.keys())) is the most elegant way. Dispatching logic is more complex.
You need to separate method dispatching step from method execution step. Since you process messages in asynchronous code, I think that most simple way is to make all message handlers asynchronous functions. Except the default handler.
@singledispatchmethoddefon_message(self, message):
raiseNotImplementedError# or return None, or whatever@on_message.registerasyncdef_(self, message: MessageA): ...
@on_message.registerasyncdef_(self, message: MessageB): ...
Activity
Kentzo commentedon Jan 16, 2021
The wrapper created by singledispatchmethod does not (trivially) expose registry of all known overloads.
Consider the following example:
Here messages are delivered outside of asyncio in a separate thread and thus they need to be forwarded into asyncio for further processing in the app. If the flow of messages is high it is desirable to filter inside the thread handler before signaling asyncio.
There are multiple approaches to describe which messages can be handled by the asyncio processor, but singledispatchmethod is the most elegant as it allows to keep everything in one place without if/else or code duplication.
Having a registry (trivially) exposed would allow to write the condition as
isinstance(message, tuple(on_message.registry.keys())).serhiy-storchaka commentedon Feb 24, 2024
I do not think that
isinstance(message, tuple(on_message.registry.keys()))is the most elegant way. Dispatching logic is more complex.You need to separate method dispatching step from method execution step. Since you process messages in asynchronous code, I think that most simple way is to make all message handlers asynchronous functions. Except the default handler.