From e22072fb11246f125aa9ff7629c832b9e2407ef0 Mon Sep 17 00:00:00 2001 From: Alexander Marshalov <_@marshalov.org> Date: Tue, 24 Jul 2018 10:58:21 +0700 Subject: bpo-34149: Behavior of the min/max with key=None (GH-8328) Improve consistency with the signature for sorted(), heapq.nsmallest(), heapq.nlargest(), and itertools.groupby(). --- Doc/library/functions.rst | 6 ++++++ Lib/heapq.py | 10 ++-------- Lib/test/test_builtin.py | 4 ++++ .../Core and Builtins/2018-07-23-21-49-05.bpo-34149.WSV-_g.rst | 1 + Python/bltinmodule.c | 4 ++++ 5 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2018-07-23-21-49-05.bpo-34149.WSV-_g.rst diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 68a5dce..e52b090 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -869,6 +869,9 @@ are always available. They are listed here in alphabetical order. .. versionadded:: 3.4 The *default* keyword-only argument. + .. versionchanged:: 3.8 + The *key* can be ``None``. + .. _func-memoryview: .. function:: memoryview(obj) @@ -903,6 +906,9 @@ are always available. They are listed here in alphabetical order. .. versionadded:: 3.4 The *default* keyword-only argument. + .. versionchanged:: 3.8 + The *key* can be ``None``. + .. function:: next(iterator[, default]) diff --git a/Lib/heapq.py b/Lib/heapq.py index b31f418..0e3555c 100644 --- a/Lib/heapq.py +++ b/Lib/heapq.py @@ -468,10 +468,7 @@ def nsmallest(n, iterable, key=None): if n == 1: it = iter(iterable) sentinel = object() - if key is None: - result = min(it, default=sentinel) - else: - result = min(it, default=sentinel, key=key) + result = min(it, default=sentinel, key=key) return [] if result is sentinel else [result] # When n>=size, it's faster to use sorted() @@ -531,10 +528,7 @@ def nlargest(n, iterable, key=None): if n == 1: it = iter(iterable) sentinel = object() - if key is None: - result = max(it, default=sentinel) - else: - result = max(it, default=sentinel, key=key) + result = max(it, default=sentinel, key=key) return [] if result is sentinel else [result] # When n>=size, it's faster to use sorted() diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 8f91bc9..233c579 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -905,6 +905,8 @@ class BuiltinTest(unittest.TestCase): self.assertEqual(max((), default=1, key=neg), 1) self.assertEqual(max((1, 2), default=3, key=neg), 1) + self.assertEqual(max((1, 2), key=None), 2) + data = [random.randrange(200) for i in range(100)] keys = dict((elem, random.randrange(50)) for elem in data) f = keys.__getitem__ @@ -957,6 +959,8 @@ class BuiltinTest(unittest.TestCase): self.assertEqual(min((), default=1, key=neg), 1) self.assertEqual(min((1, 2), default=1, key=neg), 2) + self.assertEqual(min((1, 2), key=None), 1) + data = [random.randrange(200) for i in range(100)] keys = dict((elem, random.randrange(50)) for elem in data) f = keys.__getitem__ diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-07-23-21-49-05.bpo-34149.WSV-_g.rst b/Misc/NEWS.d/next/Core and Builtins/2018-07-23-21-49-05.bpo-34149.WSV-_g.rst new file mode 100644 index 0000000..9672bcf --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-07-23-21-49-05.bpo-34149.WSV-_g.rst @@ -0,0 +1 @@ +Fix min and max functions to get default behavior when key is None. diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 88a4bf9..7bb5687 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -1639,6 +1639,10 @@ min_max(PyObject *args, PyObject *kwds, int op) return NULL; } + if (keyfunc == Py_None) { + keyfunc = NULL; + } + maxitem = NULL; /* the result */ maxval = NULL; /* the value associated with the result */ while (( item = PyIter_Next(it) )) { -- cgit v0.12