diff options
author | Alex Stewart <alex@foogod.com> | 2010-09-02 19:22:30 -0700 |
---|---|---|
committer | Alex Stewart <alex@foogod.com> | 2010-09-02 19:22:30 -0700 |
commit | c17eb8483f8f5ffa8933634b5ad0ec0f40419d97 (patch) | |
tree | 14142dc1cba01d4a4cdb9bf37667c7b9e0fa338a /nose/pyversion.py | |
parent | c58f8d55e1aac4b1eec792e85cdd3b376ec4c4e2 (diff) | |
download | nose-c17eb8483f8f5ffa8933634b5ad0ec0f40419d97.tar.gz |
Converted (almost) all cmp functions to sort key functions instead.
Diffstat (limited to 'nose/pyversion.py')
-rw-r--r-- | nose/pyversion.py | 85 |
1 files changed, 41 insertions, 44 deletions
diff --git a/nose/pyversion.py b/nose/pyversion.py index 442132b..07e36ed 100644 --- a/nose/pyversion.py +++ b/nose/pyversion.py @@ -7,7 +7,8 @@ import types import inspect import nose.util -__all__ = ['make_instancemethod', 'cmp', 'sort_list', 'ClassType', 'TypeType', 'UNICODE_STRINGS', 'unbound_method', 'ismethod', 'isunboundmethod'] +__all__ = ['make_instancemethod', 'cmp_to_key', 'sort_list', 'ClassType', + 'TypeType', 'UNICODE_STRINGS', 'unbound_method', 'ismethod'] # In Python 3.x, all strings are unicode (the call to 'unicode()' in the 2.x # source will be replaced with 'str()' when running 2to3, so this test will @@ -15,49 +16,46 @@ __all__ = ['make_instancemethod', 'cmp', 'sort_list', 'ClassType', 'TypeType', ' UNICODE_STRINGS = (type(unicode()) == type(str())) # new.instancemethod() is obsolete for new-style classes (Python 3.x) -# We need to use descriptor functions instead. +# We need to use descriptor methods instead. try: import new def make_instancemethod(function, instance): - return new.instancemethod(function.im_func, instance, instance.__class__) + return new.instancemethod(function.im_func, instance, + instance.__class__) except ImportError: def make_instancemethod(function, instance): return function.__get__(instance, instance.__class__) -# Python 3.x has gotten rid of the 'cmp' option to list.sort (and the 'cmp' -# builtin). -# Unfortunately, using a 'key' argument isn't supported in Python 2.3, which -# we're still trying to support too... -if hasattr(__builtins__, 'cmp'): - def sort_list(l, cmp): - return l.sort(cmp) +# To be forward-compatible, we do all list sorts using keys instead of cmp +# functions. However, part of the unittest.TestLoader API involves a +# user-provideable cmp function, so we need some way to convert that. +def cmp_to_key(mycmp): + 'Convert a cmp= function into a key= function' + class Key(object): + def __init__(self, obj): + self.obj = obj + def __lt__(self, other): + return mycmp(self.obj, other.obj) < 0 + def __gt__(self, other): + return mycmp(self.obj, other.obj) > 0 + def __eq__(self, other): + return mycmp(self.obj, other.obj) == 0 + return Key + +# Python 2.3 also does not support list-sorting by key, so we need to convert +# keys to cmp functions if we're running on old Python.. +if sys.version_info < (2, 4): + def sort_list(l, key, reverse=False): + if reverse: + return l.sort(lambda a, b: cmp(key(b), key(a))) + else: + return l.sort(lambda a, b: cmp(key(a), key(b))) else: - def cmp(a, b): - return (a > b) - (a < b) - - def cmp_to_key(mycmp): - class K(object): - def __init__(self, obj, *args): - self.obj = obj - def __lt__(self, other): - return mycmp(self.obj, other.obj) < 0 - def __gt__(self, other): - return mycmp(self.obj, other.obj) > 0 - def __eq__(self, other): - return mycmp(self.obj, other.obj) == 0 - def __le__(self, other): - return mycmp(self.obj, other.obj) <= 0 - def __ge__(self, other): - return mycmp(self.obj, other.obj) >= 0 - def __ne__(self, other): - return mycmp(self.obj, other.obj) != 0 - return K - - def sort_list(l, cmp): - return l.sort(key=cmp_to_key(cmp)) + def sort_list(l, key, reverse=False): + return l.sort(key=key, reverse=reverse) # In Python 3.x, all objects are "new style" objects descended from 'type', and -# thus types.ClassType and types.TypeType doen't exist anymore. For +# thus types.ClassType and types.TypeType don't exist anymore. For # compatibility, we make sure they still work. if hasattr(types, 'ClassType'): ClassType = types.ClassType @@ -79,12 +77,13 @@ class UnboundMethod: def address(self): cls = self.__self__.cls - module = cls.__module__ - m = sys.modules[module] - file = getattr(m, '__file__', None) - if file is not None: - file = os.path.abspath(file) - return (nose.util.src(file), module, "%s.%s" % (cls.__name__, self._func.__name__)) + modname = cls.__module__ + module = sys.modules[modname] + filename = getattr(module, '__file__', None) + if filename is not None: + filename = os.path.abspath(filename) + return (nose.util.src(filename), modname, "%s.%s" % (cls.__name__, + self._func.__name__)) def __call__(self, *args, **kwargs): return self._func(*args, **kwargs) @@ -93,7 +92,8 @@ class UnboundMethod: return getattr(self._func, attr) def __repr__(self): - return '<unbound method %s.%s>' % (self.__self__.cls.__name__, self._func.__name__) + return '<unbound method %s.%s>' % (self.__self__.cls.__name__, + self._func.__name__) class UnboundSelf: def __init__(self, cls): @@ -116,6 +116,3 @@ def unbound_method(cls, func): def ismethod(obj): return inspect.ismethod(obj) or isinstance(obj, UnboundMethod) - -def isunboundmethod(obj): - return (inspect.ismethod(obj) and obj.im_self is None) or isinstance(obj, UnboundMethod) |