Skip to content

Extensible dispatchers #97

Open
Open

Description

I'm working on a library that will provide some default dispatchers, using the @dispatcher.register(type) syntax.

In [8]: default_dispatcher = multipledispatch.Dispatcher("default")                                                         

In [9]: import json                                                                                                          

In [10]: @default_dispatcher.register(dict) 
    ...: def _(obj): 
    ...:     return json.dumps(obj) 
    ...:                                                                                                                     

I'd like users to be able to extend my dispatcher into their own.

In [11]: user_dispatcher = multipledispatch.Dispatcher('user')                                                               

In [12]: user_dispatcher.funcs = default_dispatcher.funcs.copy()                                                             

In [13]: @user_dispatcher.register(list) 
    ...: def _(obj): 
    ...:     return json.dumps(list) 
    ...:                           

Syntactically, this is a bit awkward. I know there's the @dispatch(namespace=d) API, but this requires the user to remember to add the namespace argument on every decoration, which seems potentially more error-prone than d.register().

How would you feel about providing some extensibility options? For example, using a ChainMap or dict it might be

# multipledispatch code

class ExtensibleDispatcher:
    def __init__(self, funcs=None, doc=None):
        self.funcs = collections.ChainMap(funcs)
        self.doc = doc

    def evolve(self, registry=None):
        return type(self)(self.funcs.new_child(registry or {}), self.doc)

# client library code

d = ExtensibleDispatcher()

@d.register(dict)
def _(obj):
    return json.dumps(obj)


# user code

d2 = d.evolve()

@d2.register(list)
def _(obj):
    return json.dumps(obj)

But it could even be as simple as adding a funcs argument to the Dispatcher constructor to allow

user_dispatcher = Dispatcher(name='new', funcs=default_dispatcher.copy())

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions