Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
dfad22da
Commit
dfad22da
authored
Sep 28, 2004
by
Raymond Hettinger
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Plug a leak and beef-up test coverage.
parent
642587c2
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
161 additions
and
4 deletions
+161
-4
Lib/test/test_heapq.py
Lib/test/test_heapq.py
+149
-0
Modules/_heapqmodule.c
Modules/_heapqmodule.c
+12
-4
No files found.
Lib/test/test_heapq.py
View file @
dfad22da
...
@@ -110,8 +110,157 @@ class TestHeap(unittest.TestCase):
...
@@ -110,8 +110,157 @@ class TestHeap(unittest.TestCase):
for
n
in
(
0
,
1
,
2
,
10
,
100
,
400
,
999
,
1000
,
1100
):
for
n
in
(
0
,
1
,
2
,
10
,
100
,
400
,
999
,
1000
,
1100
):
self
.
assertEqual
(
nlargest
(
n
,
data
),
sorted
(
data
,
reverse
=
True
)[:
n
])
self
.
assertEqual
(
nlargest
(
n
,
data
),
sorted
(
data
,
reverse
=
True
)[:
n
])
#==============================================================================
class
LenOnly
:
"Dummy sequence class defining __len__ but not __getitem__."
def
__len__
(
self
):
return
10
class
GetOnly
:
"Dummy sequence class defining __getitem__ but not __len__."
def
__getitem__
(
self
,
ndx
):
return
10
class
CmpErr
:
"Dummy element that always raises an error during comparison"
def
__cmp__
(
self
,
other
):
raise
ZeroDivisionError
def
R
(
seqn
):
'Regular generator'
for
i
in
seqn
:
yield
i
class
G
:
'Sequence using __getitem__'
def
__init__
(
self
,
seqn
):
self
.
seqn
=
seqn
def
__getitem__
(
self
,
i
):
return
self
.
seqn
[
i
]
class
I
:
'Sequence using iterator protocol'
def
__init__
(
self
,
seqn
):
self
.
seqn
=
seqn
self
.
i
=
0
def
__iter__
(
self
):
return
self
def
next
(
self
):
if
self
.
i
>=
len
(
self
.
seqn
):
raise
StopIteration
v
=
self
.
seqn
[
self
.
i
]
self
.
i
+=
1
return
v
class
Ig
:
'Sequence using iterator protocol defined with a generator'
def
__init__
(
self
,
seqn
):
self
.
seqn
=
seqn
self
.
i
=
0
def
__iter__
(
self
):
for
val
in
self
.
seqn
:
yield
val
class
X
:
'Missing __getitem__ and __iter__'
def
__init__
(
self
,
seqn
):
self
.
seqn
=
seqn
self
.
i
=
0
def
next
(
self
):
if
self
.
i
>=
len
(
self
.
seqn
):
raise
StopIteration
v
=
self
.
seqn
[
self
.
i
]
self
.
i
+=
1
return
v
class
N
:
'Iterator missing next()'
def
__init__
(
self
,
seqn
):
self
.
seqn
=
seqn
self
.
i
=
0
def
__iter__
(
self
):
return
self
class
E
:
'Test propagation of exceptions'
def
__init__
(
self
,
seqn
):
self
.
seqn
=
seqn
self
.
i
=
0
def
__iter__
(
self
):
return
self
def
next
(
self
):
3
//
0
class
S
:
'Test immediate stop'
def
__init__
(
self
,
seqn
):
pass
def
__iter__
(
self
):
return
self
def
next
(
self
):
raise
StopIteration
from
itertools
import
chain
,
imap
def
L
(
seqn
):
'Test multiple tiers of iterators'
return
chain
(
imap
(
lambda
x
:
x
,
R
(
Ig
(
G
(
seqn
)))))
class
TestErrorHandling
(
unittest
.
TestCase
):
def
test_non_sequence
(
self
):
for
f
in
(
heapify
,
heappop
):
self
.
assertRaises
(
TypeError
,
f
,
10
)
for
f
in
(
heappush
,
heapreplace
,
nlargest
,
nsmallest
):
self
.
assertRaises
(
TypeError
,
f
,
10
,
10
)
def
test_len_only
(
self
):
for
f
in
(
heapify
,
heappop
):
self
.
assertRaises
(
TypeError
,
f
,
LenOnly
())
for
f
in
(
heappush
,
heapreplace
):
self
.
assertRaises
(
TypeError
,
f
,
LenOnly
(),
10
)
for
f
in
(
nlargest
,
nsmallest
):
self
.
assertRaises
(
TypeError
,
f
,
2
,
LenOnly
())
def
test_get_only
(
self
):
for
f
in
(
heapify
,
heappop
):
self
.
assertRaises
(
TypeError
,
f
,
GetOnly
())
for
f
in
(
heappush
,
heapreplace
):
self
.
assertRaises
(
TypeError
,
f
,
GetOnly
(),
10
)
for
f
in
(
nlargest
,
nsmallest
):
self
.
assertRaises
(
TypeError
,
f
,
2
,
GetOnly
())
def
test_get_only
(
self
):
seq
=
[
CmpErr
(),
CmpErr
(),
CmpErr
()]
for
f
in
(
heapify
,
heappop
):
self
.
assertRaises
(
ZeroDivisionError
,
f
,
seq
)
for
f
in
(
heappush
,
heapreplace
):
self
.
assertRaises
(
ZeroDivisionError
,
f
,
seq
,
10
)
for
f
in
(
nlargest
,
nsmallest
):
self
.
assertRaises
(
ZeroDivisionError
,
f
,
2
,
seq
)
def
test_arg_parsing
(
self
):
for
f
in
(
heapify
,
heappop
,
heappush
,
heapreplace
,
nlargest
,
nsmallest
):
self
.
assertRaises
(
TypeError
,
f
,
10
)
def
test_iterable_args
(
self
):
for
f
in
(
nlargest
,
nsmallest
):
for
s
in
(
"123"
,
""
,
range
(
1000
),
(
'do'
,
1.2
),
xrange
(
2000
,
2200
,
5
)):
for
g
in
(
G
,
I
,
Ig
,
L
,
R
):
self
.
assertEqual
(
f
(
2
,
g
(
s
)),
f
(
2
,
s
))
self
.
assertEqual
(
f
(
2
,
S
(
s
)),
[])
self
.
assertRaises
(
TypeError
,
f
,
2
,
X
(
s
))
self
.
assertRaises
(
TypeError
,
f
,
2
,
N
(
s
))
self
.
assertRaises
(
ZeroDivisionError
,
f
,
2
,
E
(
s
))
#==============================================================================
def
test_main
(
verbose
=
None
):
def
test_main
(
verbose
=
None
):
from
types
import
BuiltinFunctionType
test_classes
=
[
TestHeap
]
test_classes
=
[
TestHeap
]
if
isinstance
(
heapify
,
BuiltinFunctionType
):
test_classes
.
append
(
TestErrorHandling
)
test_support
.
run_unittest
(
*
test_classes
)
test_support
.
run_unittest
(
*
test_classes
)
# verify reference counting
# verify reference counting
...
...
Modules/_heapqmodule.c
View file @
dfad22da
...
@@ -28,8 +28,10 @@ _siftdown(PyListObject *heap, int startpos, int pos)
...
@@ -28,8 +28,10 @@ _siftdown(PyListObject *heap, int startpos, int pos)
parentpos
=
(
pos
-
1
)
>>
1
;
parentpos
=
(
pos
-
1
)
>>
1
;
parent
=
PyList_GET_ITEM
(
heap
,
parentpos
);
parent
=
PyList_GET_ITEM
(
heap
,
parentpos
);
cmp
=
PyObject_RichCompareBool
(
parent
,
newitem
,
Py_LE
);
cmp
=
PyObject_RichCompareBool
(
parent
,
newitem
,
Py_LE
);
if
(
cmp
==
-
1
)
if
(
cmp
==
-
1
)
{
Py_DECREF
(
newitem
);
return
-
1
;
return
-
1
;
}
if
(
cmp
==
1
)
if
(
cmp
==
1
)
break
;
break
;
Py_INCREF
(
parent
);
Py_INCREF
(
parent
);
...
@@ -69,8 +71,10 @@ _siftup(PyListObject *heap, int pos)
...
@@ -69,8 +71,10 @@ _siftup(PyListObject *heap, int pos)
PyList_GET_ITEM
(
heap
,
rightpos
),
PyList_GET_ITEM
(
heap
,
rightpos
),
PyList_GET_ITEM
(
heap
,
childpos
),
PyList_GET_ITEM
(
heap
,
childpos
),
Py_LE
);
Py_LE
);
if
(
cmp
==
-
1
)
if
(
cmp
==
-
1
)
{
Py_DECREF
(
newitem
);
return
-
1
;
return
-
1
;
}
if
(
cmp
==
1
)
if
(
cmp
==
1
)
childpos
=
rightpos
;
childpos
=
rightpos
;
}
}
...
@@ -315,8 +319,10 @@ _siftdownmax(PyListObject *heap, int startpos, int pos)
...
@@ -315,8 +319,10 @@ _siftdownmax(PyListObject *heap, int startpos, int pos)
parentpos
=
(
pos
-
1
)
>>
1
;
parentpos
=
(
pos
-
1
)
>>
1
;
parent
=
PyList_GET_ITEM
(
heap
,
parentpos
);
parent
=
PyList_GET_ITEM
(
heap
,
parentpos
);
cmp
=
PyObject_RichCompareBool
(
newitem
,
parent
,
Py_LE
);
cmp
=
PyObject_RichCompareBool
(
newitem
,
parent
,
Py_LE
);
if
(
cmp
==
-
1
)
if
(
cmp
==
-
1
)
{
Py_DECREF
(
newitem
);
return
-
1
;
return
-
1
;
}
if
(
cmp
==
1
)
if
(
cmp
==
1
)
break
;
break
;
Py_INCREF
(
parent
);
Py_INCREF
(
parent
);
...
@@ -356,8 +362,10 @@ _siftupmax(PyListObject *heap, int pos)
...
@@ -356,8 +362,10 @@ _siftupmax(PyListObject *heap, int pos)
PyList_GET_ITEM
(
heap
,
childpos
),
PyList_GET_ITEM
(
heap
,
childpos
),
PyList_GET_ITEM
(
heap
,
rightpos
),
PyList_GET_ITEM
(
heap
,
rightpos
),
Py_LE
);
Py_LE
);
if
(
cmp
==
-
1
)
if
(
cmp
==
-
1
)
{
Py_DECREF
(
newitem
);
return
-
1
;
return
-
1
;
}
if
(
cmp
==
1
)
if
(
cmp
==
1
)
childpos
=
rightpos
;
childpos
=
rightpos
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment