From 6a3ac50c476620e9aed3ff3c70ba539e7b6d7d1c Mon Sep 17 00:00:00 2001 From: ?ukasz Langa Date: Sun, 26 May 2013 00:02:51 +0200 Subject: make tests pass on Python 2.6 - 3.3 --- setup.py | 8 +++++--- singledispatch.py | 19 +++++++++---------- singledispatch_helpers.py | 12 ++++++++++-- test_singledispatch.py | 26 ++++++++++++++++---------- tox.ini | 1 + 5 files changed, 41 insertions(+), 25 deletions(-) diff --git a/setup.py b/setup.py index 4ca442a..4acfb81 100644 --- a/setup.py +++ b/setup.py @@ -41,6 +41,10 @@ with codecs.open( # We let it die a horrible tracebacking death if reading the file fails. # We couldn't sensibly recover anyway: we need the long description. +install_requires = ['six'] +if sys.version_info[:2] < (2, 7): + install_requires.append('ordereddict') + setup ( name = 'singledispatch', version = '3.4.0.0', @@ -56,9 +60,7 @@ setup ( license = 'MIT', py_modules = ('singledispatch', 'singledispatch_helpers'), zip_safe = True, - install_requires = [ - 'six', - ], + install_requires = install_requires, classifiers = [ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', diff --git a/singledispatch.py b/singledispatch.py index 5093904..e1009b9 100644 --- a/singledispatch.py +++ b/singledispatch.py @@ -47,7 +47,8 @@ def singledispatch(func): """ registry = {} dispatch_cache = WeakKeyDictionary() - cache_token = None + def ns(): pass + ns.cache_token = None def dispatch(cls): """generic_func.dispatch(type) -> @@ -56,7 +57,7 @@ def singledispatch(func): for the given `type` registered on `generic_func`. """ - if cache_token is not None: + if ns.cache_token is not None: mro = _compose_mro(cls, registry.keys()) match = None for t in mro: @@ -68,7 +69,7 @@ def singledispatch(func): and match not in cls.__mro__): # `match` is an ABC but there is another unrelated, equally # matching ABC. Refuse the temptation to guess. - raise RuntimeError("Ambiguous dispatch: {} or {}".format( + raise RuntimeError("Ambiguous dispatch: {0} or {1}".format( match, t)) return registry[match] else: @@ -78,12 +79,11 @@ def singledispatch(func): return func def wrapper(*args, **kw): - nonlocal cache_token - if cache_token is not None: + if ns.cache_token is not None: current_token = get_cache_token() - if cache_token != current_token: + if ns.cache_token != current_token: dispatch_cache.clear() - cache_token = current_token + ns.cache_token = current_token cls = args[0].__class__ try: impl = dispatch_cache[cls] @@ -97,12 +97,11 @@ def singledispatch(func): Registers a new overload for the given `type` on a `generic_func`. """ - nonlocal cache_token if func is None: return lambda f: register(typ, f) registry[typ] = func - if cache_token is None and hasattr(typ, '__abstractmethods__'): - cache_token = get_cache_token() + if ns.cache_token is None and hasattr(typ, '__abstractmethods__'): + ns.cache_token = get_cache_token() dispatch_cache.clear() return func diff --git a/singledispatch_helpers.py b/singledispatch_helpers.py index 5c4aa8b..2141568 100644 --- a/singledispatch_helpers.py +++ b/singledispatch_helpers.py @@ -7,7 +7,15 @@ from __future__ import print_function from __future__ import unicode_literals from abc import ABCMeta -from collections import MutableMapping, UserDict +from collections import MutableMapping +try: + from collections import UserDict +except ImportError: + from UserDict import UserDict +try: + from collections import OrderedDict +except ImportError: + from ordereddict import OrderedDict try: from thread import get_ident except ImportError: @@ -142,7 +150,7 @@ class ChainMap(MutableMapping): class MappingProxyType(UserDict): def __init__(self, data): - super(MappingProxyType, self).__init__() + UserDict.__init__(self) self.data = data diff --git a/test_singledispatch.py b/test_singledispatch.py index 0234de3..484e88e 100644 --- a/test_singledispatch.py +++ b/test_singledispatch.py @@ -10,8 +10,11 @@ import collections import decimal from itertools import permutations import singledispatch as functools -from singledispatch_helpers import ChainMap -import unittest +from singledispatch_helpers import ChainMap, OrderedDict +try: + import unittest2 as unittest +except ImportError: + import unittest class TestSingleDispatch(unittest.TestCase): @@ -30,7 +33,7 @@ class TestSingleDispatch(unittest.TestCase): @functools.singledispatch def g(obj): return "base" - class C: + class C(object): pass class D(C): pass @@ -44,7 +47,7 @@ class TestSingleDispatch(unittest.TestCase): @functools.singledispatch def g(obj): return "base" - class C: + class C(object): pass class D(C): pass @@ -101,7 +104,7 @@ class TestSingleDispatch(unittest.TestCase): for haystack in permutations(bases): m = mro(dict, haystack) self.assertEqual(m, [dict, c.MutableMapping, c.Mapping, object]) - bases = [c.Container, c.Mapping, c.MutableMapping, c.OrderedDict] + bases = [c.Container, c.Mapping, c.MutableMapping, OrderedDict] for haystack in permutations(bases): m = mro(ChainMap, haystack) self.assertEqual(m, [ChainMap, c.MutableMapping, c.Mapping, @@ -116,7 +119,7 @@ class TestSingleDispatch(unittest.TestCase): c = collections d = {"a": "b"} l = [1, 2, 3] - s = {object(), None} + s = set([object(), None]) f = frozenset(s) t = (1, 2, 3) @functools.singledispatch @@ -229,7 +232,7 @@ class TestSingleDispatch(unittest.TestCase): c.Container.register(O) self.assertEqual(g(o), "sized") # see above: Sized is in __mro__ - class P: + class P(object): pass p = P() @@ -259,10 +262,13 @@ class TestSingleDispatch(unittest.TestCase): # __mro__ def test_cache_invalidation(self): - from collections import UserDict + try: + from collections import UserDict + except ImportError: + from UserDict import UserDict class TracingDict(UserDict): def __init__(self, *args, **kwargs): - super(TracingDict, self).__init__(*args, **kwargs) + UserDict.__init__(self, *args, **kwargs) self.set_ops = [] self.get_ops = [] def __getitem__(self, key): @@ -313,7 +319,7 @@ class TestSingleDispatch(unittest.TestCase): self.assertEqual(td.get_ops, [list, dict]) self.assertEqual(td.set_ops, [dict, list, dict, list]) self.assertEqual(td.data[list], g.dispatch(list)) - class X: + class X(object): pass c.MutableMapping.register(X) # Will not invalidate the cache, # not using ABCs yet. diff --git a/tox.ini b/tox.ini index fb6827d..6110b5d 100644 --- a/tox.ini +++ b/tox.ini @@ -8,4 +8,5 @@ commands = [testenv:py26] basepython = python2.6 deps = + ordereddict unittest2 -- cgit v1.2.1