@@ -0,0 +1,2901 @@
+# -*- coding: utf-8 -*-%0A%0A%22%22%22%0AMultimethods%0A%0AAn implementation of multimethods for Python, heavily influenced by%0Athe Clojure programming language.%0A%0ACopyright (C) 2010-2011 by Daniel Werner.%0A%0ASee the README file for information on usage and redistribution.%0A%22%22%22%0A%0Aimport functools%0A%0A%0Aclass DefaultMethod(object):%0A    %22%22%22%0A        Class of singleton object allowing default MultiMethod.%0A    %22%22%22%0A    def __repr__(self):%0A        return '%3CDefaultMethod%3E'%0A%0ADefault = DefaultMethod()%0A%0A%0Adef get_multimethod_key(*args, **kwargs):%0A    %22%22%22%0A        Creates immutable key out of args and kwargs.%0A    %22%22%22%0A    return tuple(map(repr, args) + map(repr, kwargs.itervalues()))%0A%0Aclass MultiMethod(object):%0A    __instances__ = %7B%7D%0A%0A    def __init__(self, name, dispatch_func=None):%0A        if name in self.__class__.__instances__:%0A            raise Exception(%22A multimethod '%25s' already exists, %22%0A                            %22redeclaring it would wreak havoc%22 %25 name)%0A        self.dispatch_func = dispatch_func or get_multimethod_key%0A        self.methods = %7B%7D%0A        self.default_method = None%0A        self.__name__ = name%0A        self.__class__.__instances__%5Bname%5D = self%0A%0A    def __call__(self, *args, **kwargs):%0A        dispatch_key = self.dispatch_func(*args, **kwargs)%0A        if dispatch_key in self.methods:%0A            return self.methods%5Bdispatch_key%5D(*args, **kwargs)%0A        if self.default_method is not None:%0A            return self.default_method(*args, **kwargs)%0A        raise Exception(%22No matching method on multimethod '%25s' and %22%0A                        %22no default method defined%22 %25 self.__name__)%0A%0A    def add_method(self, func, *args):%0A        if args == (Default,):%0A            self.default_method = func%0A        else:%0A            dispatch_key = get_multimethod_key(*args)%0A            self.methods%5Bdispatch_key%5D = func%0A%0A    def remove_method(self, dispatch_val):%0A        del self.methods%5Bdispatch_val%5D.multimethod%0A        del self.methods%5Bdispatch_val%5D%0A%0A    def methods(self):%0A        return self.methods%0A%0A    def __repr__(self):%0A        return %22%3CMultiMethod '%25s'%3E%22 %25 self.__name__%0A%0A%0Adef method(*args):%0A    def method_decorator(func):%0A        %22%22%22%0A           Decorator which registers a function as a new method of a like-named%0A           multimethod, keyed by dispatch_val.  The multimethod is determined by%0A           taking the method's name up to the last occurence of '__',%0A           e.g. function foo_bar__zig will become a method on the foo_bar%0A           multimethod.%0A        %22%22%22%0A        try:%0A            multimethod = MultiMethod.__instances__%5Bfunc.__name__%5D%0A        except KeyError:%0A            # create multimethod (don't require registration)%0A            multimethod = MultiMethod(func.__name__)%0A        functools.update_wrapper(multimethod, func)%0A        multimethod.add_method(func, *args)%0A        return multimethod%0A    return method_decorator%0A%0A__all__ = %5B'MultiMethod', 'method', 'Default'%5D

Add multimethods.