diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst
index 0f4531912eb..cfb1945988f 100644
--- a/Doc/library/functions.rst
+++ b/Doc/library/functions.rst
@@ -1154,9 +1154,8 @@ available. They are listed here in alphabetical order.
In general, the *key* and *reverse* conversion processes are much faster
than specifying an equivalent *cmp* function. This is because *cmp* is
called multiple times for each list element while *key* and *reverse* touch
- each element only once. To convert an old-style *cmp* function to a *key*
- function, see the `CmpToKey recipe in the ASPN cookbook
- `_\.
+ each element only once. Use :func:`functools.cmp_to_key` to convert an
+ old-style *cmp* function to a *key* function.
For sorting examples and a brief sorting tutorial, see `Sorting HowTo
`_\.
diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst
index 3337ead1c54..15c4a95ab49 100644
--- a/Doc/library/functools.rst
+++ b/Doc/library/functools.rst
@@ -17,7 +17,7 @@ function for the purposes of this module.
The :mod:`functools` module defines the following functions:
-.. function:: CmpToKey(func)
+.. function:: cmp_to_key(func)
Transform an old-style comparison function to a key-function. Used with
tools that accept key functions (such as :func:`sorted`, :func:`min`,
@@ -35,7 +35,7 @@ The :mod:`functools` module defines the following functions:
Example::
- sorted(iterable, key=CmpToKey(locale.strcoll)) # locale-aware sort order
+ sorted(iterable, key=cmp_to_key(locale.strcoll)) # locale-aware sort order
.. versionadded:: 2.7
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
index 330768589d3..0a6178bf941 100644
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -1618,7 +1618,8 @@ Notes:
In general, the *key* and *reverse* conversion processes are much faster than
specifying an equivalent *cmp* function. This is because *cmp* is called
multiple times for each list element while *key* and *reverse* touch each
- element only once.
+ element only once. Use :func:`functools.cmp_to_key` to convert an
+ old-style *cmp* function to a *key* function.
.. versionchanged:: 2.3
Support for ``None`` as an equivalent to omitting *cmp* was added.
diff --git a/Lib/functools.py b/Lib/functools.py
index d31b09042e5..ad1cccc77f0 100644
--- a/Lib/functools.py
+++ b/Lib/functools.py
@@ -76,7 +76,7 @@ def total_ordering(cls):
setattr(cls, opname, opfunc)
return cls
-def CmpToKey(mycmp):
+def cmp_to_key(mycmp):
'Convert a cmp= function into a key= function'
class K(object):
def __init__(self, obj, *args):
diff --git a/Lib/pstats.py b/Lib/pstats.py
index 0effa1c41c5..8b6081040a5 100644
--- a/Lib/pstats.py
+++ b/Lib/pstats.py
@@ -37,6 +37,7 @@ import os
import time
import marshal
import re
+from functools import cmp_to_key
__all__ = ["Stats"]
@@ -238,7 +239,7 @@ class Stats:
stats_list.append((cc, nc, tt, ct) + func +
(func_std_string(func), func))
- stats_list.sort(key=CmpToKey(TupleComp(sort_tuple).compare))
+ stats_list.sort(key=cmp_to_key(TupleComp(sort_tuple).compare))
self.fcn_list = fcn_list = []
for tuple in stats_list:
@@ -471,16 +472,6 @@ class TupleComp:
return direction
return 0
-def CmpToKey(mycmp):
- """Convert a cmp= function into a key= function"""
- class K(object):
- def __init__(self, obj):
- self.obj = obj
- def __lt__(self, other):
- return mycmp(self.obj, other.obj) == -1
- return K
-
-
#**************************************************************************
# func_name is a triple (file:string, line:int, name:string)
diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py
index 2549e05c149..44992b8c5bb 100644
--- a/Lib/test/test_functools.py
+++ b/Lib/test/test_functools.py
@@ -338,7 +338,12 @@ class TestReduce(unittest.TestCase):
self.assertEqual(reduce(42, "", "1"), "1") # func is never called with one item
self.assertRaises(TypeError, reduce, 42, (42, 42))
-
+class TestCmpToKey(unittest.TestCase):
+ def test_cmp_to_key(self):
+ def mycmp(x, y):
+ return y - x
+ self.assertEqual(sorted(range(5), key=functools.cmp_to_key(mycmp)),
+ [4, 3, 2, 1, 0])
def test_main(verbose=None):
diff --git a/Lib/unittest/loader.py b/Lib/unittest/loader.py
index e0b8585209b..f0cc157415f 100644
--- a/Lib/unittest/loader.py
+++ b/Lib/unittest/loader.py
@@ -6,23 +6,13 @@ import sys
import traceback
import types
+from functools import cmp_to_key as _CmpToKey
from fnmatch import fnmatch
from . import case, suite
__unittest = True
-
-def _CmpToKey(mycmp):
- 'Convert a cmp= function into a key= function'
- class K(object):
- def __init__(self, obj):
- self.obj = obj
- def __lt__(self, other):
- return mycmp(self.obj, other.obj) == -1
- return K
-
-
# what about .pyc or .pyo (etc)
# we would need to avoid loading the same tests multiple times
# from '.py', '.pyc' *and* '.pyo'
diff --git a/Misc/NEWS b/Misc/NEWS
index 0f1f225bc72..4cb76adc01b 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -60,7 +60,7 @@ Library
- the functools module now has a total_ordering() class decorator
to simplify the specifying rich comparisons.
-- The functools module also adds CmpToKey() as a tool to transition
+- The functools module also adds cmp_to_key() as a tool to transition
old-style comparison functions to new-style key-functions.
- Issue #8294: The Fraction constructor now accepts Decimal and float