Author: Ronan Lamy <ronan.l...@gmail.com> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit