Author: Ronan Lamy <[email protected]>
Branch: var-in-Some
Changeset: r71570:9a6b10d71995
Date: 2014-05-18 21:33 +0100
http://bitbucket.org/pypy/pypy/changeset/9a6b10d71995/
Log: create DoubleDispatchRegistry
diff --git a/rpython/tool/pairtype.py b/rpython/tool/pairtype.py
--- a/rpython/tool/pairtype.py
+++ b/rpython/tool/pairtype.py
@@ -71,3 +71,26 @@
for base2 in cls2.__mro__:
for base1 in cls1.__mro__:
yield (base1, base2)
+
+class DoubleDispatchRegistry(object):
+ """
+ A mapping of pairs of types to arbitrary objects respecting inheritance
+ """
+ def __init__(self):
+ self._registry = {}
+ self._cache = {}
+
+ def __getitem__(self, clspair):
+ try:
+ return self._cache[clspair]
+ except KeyError:
+ cls1, cls2 = clspair
+ for c1, c2 in pairmro(cls1, cls2):
+ if (c1, c2) in self._cache:
+ return self._cache[(c1, c2)]
+ else:
+ raise
+
+ def __setitem__(self, clspair, value):
+ self._registry[clspair] = value
+ self._cache = self._registry.copy()
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,4 +1,5 @@
-from rpython.tool.pairtype import pairtype, pair, extendabletype, pairmro
+from rpython.tool.pairtype import (
+ pairtype, pair, extendabletype, pairmro, DoubleDispatchRegistry)
def test_binop():
### Binary operation example
@@ -113,3 +114,18 @@
class B2(B): pass
parent_pairtypes = pairtype(A3, B2).__mro__[:-2]
assert (tuple(pairtype(a, b) for a, b in pairmro(A3, B2)) ==
parent_pairtypes)
+
+def test_doubledispatch():
+ class A(object): pass
+ class A2(A): pass
+ class A3(A2): pass
+ class B(object): pass
+ class B2(B): pass
+ reg = DoubleDispatchRegistry()
+ reg[object, object] = "default"
+ assert reg[A3, B2] == "default"
+ reg[A2, B2] = "A2-B2"
+ assert reg[A, B2] == "default"
+ 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
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit