summaryrefslogtreecommitdiff
path: root/nose/pyversion.py
diff options
context:
space:
mode:
authorAlex Stewart <alex@foogod.com>2010-09-02 19:22:30 -0700
committerAlex Stewart <alex@foogod.com>2010-09-02 19:22:30 -0700
commitc17eb8483f8f5ffa8933634b5ad0ec0f40419d97 (patch)
tree14142dc1cba01d4a4cdb9bf37667c7b9e0fa338a /nose/pyversion.py
parentc58f8d55e1aac4b1eec792e85cdd3b376ec4c4e2 (diff)
downloadnose-c17eb8483f8f5ffa8933634b5ad0ec0f40419d97.tar.gz
Converted (almost) all cmp functions to sort key functions instead.
Diffstat (limited to 'nose/pyversion.py')
-rw-r--r--nose/pyversion.py85
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)