diff options
author | Georg Brandl <georg@python.org> | 2008-06-10 17:40:04 (GMT) |
---|---|---|
committer | Georg Brandl <georg@python.org> | 2008-06-10 17:40:04 (GMT) |
commit | f78e02b79862ac555fe052240bda55fa770a2d6f (patch) | |
tree | 885defd9b02e7865a9475b1d18b9c91a1fb8e93a /Modules/_heapqmodule.c | |
parent | 4066186c8934d66ac1ac795c7380a68468ad157a (diff) | |
download | cpython-f78e02b79862ac555fe052240bda55fa770a2d6f.zip cpython-f78e02b79862ac555fe052240bda55fa770a2d6f.tar.gz cpython-f78e02b79862ac555fe052240bda55fa770a2d6f.tar.bz2 |
Merged revisions 63562,63570,63728,63734,63784,63788,63802,63817,63827,63839,63887,63975,63998 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r63562 | martin.v.loewis | 2008-05-23 17:06:50 +0200 (Fri, 23 May 2008) | 2 lines
Patch #1722225: Support QNX 6.
........
r63570 | trent.nelson | 2008-05-23 22:33:14 +0200 (Fri, 23 May 2008) | 1 line
Introduce a user macro named $(externalsDir), which should point to the root directory of where all the external sources should live. Developers can change this value if their external sources live elsewhere. The default of '..\..' matches the current status quo.
........
r63728 | gregory.p.smith | 2008-05-26 23:16:34 +0200 (Mon, 26 May 2008) | 4 lines
Fix issue2589: there was a potential integer overflow leading to
memory corruption on esoteric platforms and incorrect behavior on
normal platforms.
........
r63734 | gregory.p.smith | 2008-05-27 00:07:28 +0200 (Tue, 27 May 2008) | 3 lines
Fix issue2588: Do not execute str[size-1] = '\0' when a 0 size is
passed in. (The assert won't prevent this in non-debug builds).
........
r63784 | raymond.hettinger | 2008-05-29 10:38:23 +0200 (Thu, 29 May 2008) | 1 line
Fix two typos.
........
r63788 | facundo.batista | 2008-05-29 18:39:26 +0200 (Thu, 29 May 2008) | 6 lines
Fixed the semantic of timeout for socket.create_connection and
all the upper level libraries that use it, including urllib2.
Added and fixed some tests, and changed docs correspondingly.
Thanks to John J Lee for the patch and the pusing, :)
........
r63802 | mark.dickinson | 2008-05-30 04:46:53 +0200 (Fri, 30 May 2008) | 2 lines
Fix typo in testSum
........
r63817 | raymond.hettinger | 2008-05-30 20:20:50 +0200 (Fri, 30 May 2008) | 8 lines
* Mark intermedidate computes values (hi, lo, yr) as volatile.
* Expand comments.
* Swap variable names in the sum_exact code so that x and y
are consistently chosen as the larger and smaller magnitude
values respectively.
........
r63827 | raymond.hettinger | 2008-05-31 05:24:31 +0200 (Sat, 31 May 2008) | 1 line
Implement heapq in terms of less-than (to match list.sort()).
........
r63839 | gerhard.haering | 2008-05-31 23:33:27 +0200 (Sat, 31 May 2008) | 2 lines
Fixed rowcount for SELECT statements. They're -1 now (again), for better DB-API 2.0 compliance.
........
r63887 | gregory.p.smith | 2008-06-02 06:05:52 +0200 (Mon, 02 Jun 2008) | 4 lines
Fix issue 2782: be less strict about the format string type in strftime.
Accept unicode and anything else ParseTuple "s#" can deal with. This
matches the time.strftime behavior.
........
r63975 | neal.norwitz | 2008-06-06 06:47:01 +0200 (Fri, 06 Jun 2008) | 3 lines
Aldo Cortesi confirmed this is still needed for OpenBSD 4.2 and 4.3.
(I didn't regen configure, since I don't have a working autoconf.)
........
r63998 | raymond.hettinger | 2008-06-06 23:47:51 +0200 (Fri, 06 Jun 2008) | 1 line
Issue 3501: Make heapq support both __le__ and __lt__.
........
Diffstat (limited to 'Modules/_heapqmodule.c')
-rw-r--r-- | Modules/_heapqmodule.c | 61 |
1 files changed, 45 insertions, 16 deletions
diff --git a/Modules/_heapqmodule.c b/Modules/_heapqmodule.c index 97ccd86..a5a5605 100644 --- a/Modules/_heapqmodule.c +++ b/Modules/_heapqmodule.c @@ -8,6 +8,25 @@ annotated by François Pinard, and converted to C by Raymond Hettinger. #include "Python.h" +/* Older implementations of heapq used Py_LE for comparisons. Now, it uses + Py_LT so it will match min(), sorted(), and bisect(). Unfortunately, some + client code (Twisted for example) relied on Py_LE, so this little function + restores compatability by trying both. +*/ +static int +cmp_lt(PyObject *x, PyObject *y) +{ + int cmp; + cmp = PyObject_RichCompareBool(x, y, Py_LT); + if (cmp == -1 && PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + cmp = PyObject_RichCompareBool(y, x, Py_LE); + if (cmp != -1) + cmp = 1 - cmp; + } + return cmp; +} + static int _siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) { @@ -28,12 +47,12 @@ _siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) while (pos > startpos){ parentpos = (pos - 1) >> 1; parent = PyList_GET_ITEM(heap, parentpos); - cmp = PyObject_RichCompareBool(parent, newitem, Py_LE); + cmp = cmp_lt(newitem, parent); if (cmp == -1) { Py_DECREF(newitem); return -1; } - if (cmp == 1) + if (cmp == 0) break; Py_INCREF(parent); Py_DECREF(PyList_GET_ITEM(heap, pos)); @@ -68,15 +87,14 @@ _siftup(PyListObject *heap, Py_ssize_t pos) /* Set childpos to index of smaller child. */ rightpos = childpos + 1; if (rightpos < endpos) { - cmp = PyObject_RichCompareBool( - PyList_GET_ITEM(heap, rightpos), + cmp = cmp_lt( PyList_GET_ITEM(heap, childpos), - Py_LE); + PyList_GET_ITEM(heap, rightpos)); if (cmp == -1) { Py_DECREF(newitem); return -1; } - if (cmp == 1) + if (cmp == 0) childpos = rightpos; } /* Move the smaller child up. */ @@ -214,10 +232,10 @@ heappushpop(PyObject *self, PyObject *args) return item; } - cmp = PyObject_RichCompareBool(item, PyList_GET_ITEM(heap, 0), Py_LE); + cmp = cmp_lt(PyList_GET_ITEM(heap, 0), item); if (cmp == -1) return NULL; - if (cmp == 1) { + if (cmp == 0) { Py_INCREF(item); return item; } @@ -270,6 +288,7 @@ nlargest(PyObject *self, PyObject *args) { PyObject *heap=NULL, *elem, *iterable, *sol, *it, *oldelem; Py_ssize_t i, n; + int cmp; if (!PyArg_ParseTuple(args, "nO:nlargest", &n, &iterable)) return NULL; @@ -312,7 +331,12 @@ nlargest(PyObject *self, PyObject *args) else goto sortit; } - if (PyObject_RichCompareBool(elem, sol, Py_LE)) { + cmp = cmp_lt(sol, elem); + if (cmp == -1) { + Py_DECREF(elem); + goto fail; + } + if (cmp == 0) { Py_DECREF(elem); continue; } @@ -362,12 +386,12 @@ _siftdownmax(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) while (pos > startpos){ parentpos = (pos - 1) >> 1; parent = PyList_GET_ITEM(heap, parentpos); - cmp = PyObject_RichCompareBool(newitem, parent, Py_LE); + cmp = cmp_lt(parent, newitem); if (cmp == -1) { Py_DECREF(newitem); return -1; } - if (cmp == 1) + if (cmp == 0) break; Py_INCREF(parent); Py_DECREF(PyList_GET_ITEM(heap, pos)); @@ -402,15 +426,14 @@ _siftupmax(PyListObject *heap, Py_ssize_t pos) /* Set childpos to index of smaller child. */ rightpos = childpos + 1; if (rightpos < endpos) { - cmp = PyObject_RichCompareBool( - PyList_GET_ITEM(heap, childpos), + cmp = cmp_lt( PyList_GET_ITEM(heap, rightpos), - Py_LE); + PyList_GET_ITEM(heap, childpos)); if (cmp == -1) { Py_DECREF(newitem); return -1; } - if (cmp == 1) + if (cmp == 0) childpos = rightpos; } /* Move the smaller child up. */ @@ -434,6 +457,7 @@ nsmallest(PyObject *self, PyObject *args) { PyObject *heap=NULL, *elem, *iterable, *los, *it, *oldelem; Py_ssize_t i, n; + int cmp; if (!PyArg_ParseTuple(args, "nO:nsmallest", &n, &iterable)) return NULL; @@ -477,7 +501,12 @@ nsmallest(PyObject *self, PyObject *args) else goto sortit; } - if (PyObject_RichCompareBool(los, elem, Py_LE)) { + cmp = cmp_lt(elem, los); + if (cmp == -1) { + Py_DECREF(elem); + goto fail; + } + if (cmp == 0) { Py_DECREF(elem); continue; } |