Author: Ronan Lamy <[email protected]>
Branch: anntype2
Changeset: r80840:d8221802192d
Date: 2015-11-23 02:13 +0000
http://bitbucket.org/pypy/pypy/changeset/d8221802192d/

Log:    Implement @doubledispatch decorator

diff --git a/rpython/tool/pairtype.py b/rpython/tool/pairtype.py
--- a/rpython/tool/pairtype.py
+++ b/rpython/tool/pairtype.py
@@ -94,3 +94,40 @@
     def __setitem__(self, clspair, value):
         self._registry[clspair] = value
         self._cache = self._registry.copy()
+
+def doubledispatch(func):
+    """
+    Decorator returning a double-dispatch function
+
+    Usage
+    -----
+        >>> @doubledispatch
+        ... def func(x, y):
+        ...     return 0
+        >>> @func.register(basestring, basestring)
+        ... def func_string_string(x, y):
+        ...     return 42
+        >>> func(1, 2)
+        0
+        >>> func('x', u'y')
+        42
+    """
+    return DoubleDispatchFunction(func)
+
+class DoubleDispatchFunction(object):
+    def __init__(self, func):
+        self._registry = DoubleDispatchRegistry()
+        self._default = func
+
+    def __call__(self, arg1, arg2, *args, **kwargs):
+        try:
+            func = self._registry[type(arg1), type(arg2)]
+        except KeyError:
+            func = self._default
+        return func(arg1, arg2, *args, **kwargs)
+
+    def register(self, cls1, cls2):
+        def decorator(func):
+            self._registry[cls1, cls2] = func
+            return func
+        return decorator
diff --git a/rpython/tool/test/test_pairtype.py 
b/rpython/tool/test/test_pairtype.py
--- a/rpython/tool/test/test_pairtype.py
+++ b/rpython/tool/test/test_pairtype.py
@@ -1,5 +1,6 @@
 from rpython.tool.pairtype import (
-    pairtype, pair, extendabletype, pairmro, DoubleDispatchRegistry)
+    pairtype, pair, extendabletype, pairmro, DoubleDispatchRegistry,
+    doubledispatch)
 
 def test_binop():
     ### Binary operation example
@@ -115,7 +116,7 @@
     parent_pairtypes = pairtype(A3, B2).__mro__[:-2]
     assert (tuple(pairtype(a, b) for a, b in pairmro(A3, B2)) == 
parent_pairtypes)
 
-def test_doubledispatch():
+def test_doubledispatch_registry():
     class A(object): pass
     class A2(A): pass
     class A3(A2): pass
@@ -129,3 +130,15 @@
     assert reg[A3, B2] == "A2-B2"
     reg[A3, B] = "A3-B"
     assert reg[A3, B2] == "A2-B2"  # note that A2,B2 wins over A3,B
+
+def test_doubledispatch_function():
+    @doubledispatch
+    def f(x, y, z):
+        return z
+
+    @f.register(int, int)
+    def f_int(x, y, z):
+        return 42
+
+    assert f(1., 1., 0) == 0
+    assert f(1, 1, 0) == 42
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to