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