mirror of
https://github.com/python/cpython.git
synced 2025-07-13 14:25:18 +00:00

svn+ssh://pythondev@svn.python.org/python/trunk ........ r61004 | georg.brandl | 2008-02-23 19:47:04 +0100 (Sat, 23 Feb 2008) | 2 lines Documentation coverage builder, part 1. ........ r61006 | andrew.kuchling | 2008-02-23 20:02:33 +0100 (Sat, 23 Feb 2008) | 1 line #1389051: IMAP module tries to read entire message in one chunk. Patch by Fredrik Lundh. ........ r61008 | andrew.kuchling | 2008-02-23 20:28:58 +0100 (Sat, 23 Feb 2008) | 1 line #1389051, #1092502: fix excessively large allocations when using read() on a socket ........ r61011 | jeffrey.yasskin | 2008-02-23 20:40:54 +0100 (Sat, 23 Feb 2008) | 13 lines Prevent classes like: class RunSelfFunction(object): def __init__(self): self.thread = threading.Thread(target=self._run) self.thread.start() def _run(self): pass from creating a permanent cycle between the object and the thread by having the Thread delete its references to the object when it completes. As an example of the effect of this bug, paramiko.Transport inherits from Thread to avoid it. ........ r61013 | jeffrey.yasskin | 2008-02-23 21:40:35 +0100 (Sat, 23 Feb 2008) | 3 lines Followup to r61011: Also avoid the reference cycle when the Thread's target raises an exception. ........ r61017 | georg.brandl | 2008-02-23 22:59:11 +0100 (Sat, 23 Feb 2008) | 2 lines #2101: fix removeAttribute docs. ........ r61018 | georg.brandl | 2008-02-23 23:05:38 +0100 (Sat, 23 Feb 2008) | 2 lines Add examples to modulefinder docs. Written for GHOP by Josip Dzolonga. ........ r61019 | georg.brandl | 2008-02-23 23:09:24 +0100 (Sat, 23 Feb 2008) | 2 lines Use os.closerange() in popen2. ........ r61020 | georg.brandl | 2008-02-23 23:14:02 +0100 (Sat, 23 Feb 2008) | 2 lines Use os.closerange(). ........ r61021 | georg.brandl | 2008-02-23 23:35:33 +0100 (Sat, 23 Feb 2008) | 3 lines In test_heapq and test_bisect, test both the Python and the C implementation. Originally written for GHOP by Josip Dzolonga, heavily patched by me. ........ r61024 | facundo.batista | 2008-02-23 23:54:12 +0100 (Sat, 23 Feb 2008) | 3 lines Added simple test case. Thanks Benjamin Peterson. ........ r61025 | georg.brandl | 2008-02-23 23:55:18 +0100 (Sat, 23 Feb 2008) | 2 lines #1825: correctly document msilib.add_data. ........ r61027 | georg.brandl | 2008-02-24 00:02:23 +0100 (Sun, 24 Feb 2008) | 2 lines #1826: allow dotted attribute paths in operator.attrgetter. ........ r61028 | georg.brandl | 2008-02-24 00:04:35 +0100 (Sun, 24 Feb 2008) | 2 lines #1506171: added operator.methodcaller(). ........ r61029 | georg.brandl | 2008-02-24 00:25:26 +0100 (Sun, 24 Feb 2008) | 2 lines Document import ./. threading issues. #1720705. ........ r61032 | georg.brandl | 2008-02-24 00:43:01 +0100 (Sun, 24 Feb 2008) | 2 lines Specify what kind of warning -3 emits. ........ r61033 | christian.heimes | 2008-02-24 00:59:45 +0100 (Sun, 24 Feb 2008) | 1 line MS Windows doesn't have mode_t but stat.st_mode is defined as unsigned short. ........
303 lines
12 KiB
Python
303 lines
12 KiB
Python
import sys
|
|
import unittest
|
|
from test import test_support
|
|
from collections import UserList
|
|
|
|
# We do a bit of trickery here to be able to test both the C implementation
|
|
# and the Python implementation of the module.
|
|
|
|
# Make it impossible to import the C implementation anymore.
|
|
sys.modules['_bisect'] = 0
|
|
# We must also handle the case that bisect was imported before.
|
|
if 'bisect' in sys.modules:
|
|
del sys.modules['bisect']
|
|
|
|
# Now we can import the module and get the pure Python implementation.
|
|
import bisect as py_bisect
|
|
|
|
# Restore everything to normal.
|
|
del sys.modules['_bisect']
|
|
del sys.modules['bisect']
|
|
|
|
# This is now the module with the C implementation.
|
|
import bisect as c_bisect
|
|
|
|
|
|
class TestBisect(unittest.TestCase):
|
|
module = None
|
|
|
|
def setUp(self):
|
|
self.precomputedCases = [
|
|
(self.module.bisect_right, [], 1, 0),
|
|
(self.module.bisect_right, [1], 0, 0),
|
|
(self.module.bisect_right, [1], 1, 1),
|
|
(self.module.bisect_right, [1], 2, 1),
|
|
(self.module.bisect_right, [1, 1], 0, 0),
|
|
(self.module.bisect_right, [1, 1], 1, 2),
|
|
(self.module.bisect_right, [1, 1], 2, 2),
|
|
(self.module.bisect_right, [1, 1, 1], 0, 0),
|
|
(self.module.bisect_right, [1, 1, 1], 1, 3),
|
|
(self.module.bisect_right, [1, 1, 1], 2, 3),
|
|
(self.module.bisect_right, [1, 1, 1, 1], 0, 0),
|
|
(self.module.bisect_right, [1, 1, 1, 1], 1, 4),
|
|
(self.module.bisect_right, [1, 1, 1, 1], 2, 4),
|
|
(self.module.bisect_right, [1, 2], 0, 0),
|
|
(self.module.bisect_right, [1, 2], 1, 1),
|
|
(self.module.bisect_right, [1, 2], 1.5, 1),
|
|
(self.module.bisect_right, [1, 2], 2, 2),
|
|
(self.module.bisect_right, [1, 2], 3, 2),
|
|
(self.module.bisect_right, [1, 1, 2, 2], 0, 0),
|
|
(self.module.bisect_right, [1, 1, 2, 2], 1, 2),
|
|
(self.module.bisect_right, [1, 1, 2, 2], 1.5, 2),
|
|
(self.module.bisect_right, [1, 1, 2, 2], 2, 4),
|
|
(self.module.bisect_right, [1, 1, 2, 2], 3, 4),
|
|
(self.module.bisect_right, [1, 2, 3], 0, 0),
|
|
(self.module.bisect_right, [1, 2, 3], 1, 1),
|
|
(self.module.bisect_right, [1, 2, 3], 1.5, 1),
|
|
(self.module.bisect_right, [1, 2, 3], 2, 2),
|
|
(self.module.bisect_right, [1, 2, 3], 2.5, 2),
|
|
(self.module.bisect_right, [1, 2, 3], 3, 3),
|
|
(self.module.bisect_right, [1, 2, 3], 4, 3),
|
|
(self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 0, 0),
|
|
(self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1, 1),
|
|
(self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1.5, 1),
|
|
(self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2, 3),
|
|
(self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2.5, 3),
|
|
(self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3, 6),
|
|
(self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3.5, 6),
|
|
(self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 4, 10),
|
|
(self.module.bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 5, 10),
|
|
|
|
(self.module.bisect_left, [], 1, 0),
|
|
(self.module.bisect_left, [1], 0, 0),
|
|
(self.module.bisect_left, [1], 1, 0),
|
|
(self.module.bisect_left, [1], 2, 1),
|
|
(self.module.bisect_left, [1, 1], 0, 0),
|
|
(self.module.bisect_left, [1, 1], 1, 0),
|
|
(self.module.bisect_left, [1, 1], 2, 2),
|
|
(self.module.bisect_left, [1, 1, 1], 0, 0),
|
|
(self.module.bisect_left, [1, 1, 1], 1, 0),
|
|
(self.module.bisect_left, [1, 1, 1], 2, 3),
|
|
(self.module.bisect_left, [1, 1, 1, 1], 0, 0),
|
|
(self.module.bisect_left, [1, 1, 1, 1], 1, 0),
|
|
(self.module.bisect_left, [1, 1, 1, 1], 2, 4),
|
|
(self.module.bisect_left, [1, 2], 0, 0),
|
|
(self.module.bisect_left, [1, 2], 1, 0),
|
|
(self.module.bisect_left, [1, 2], 1.5, 1),
|
|
(self.module.bisect_left, [1, 2], 2, 1),
|
|
(self.module.bisect_left, [1, 2], 3, 2),
|
|
(self.module.bisect_left, [1, 1, 2, 2], 0, 0),
|
|
(self.module.bisect_left, [1, 1, 2, 2], 1, 0),
|
|
(self.module.bisect_left, [1, 1, 2, 2], 1.5, 2),
|
|
(self.module.bisect_left, [1, 1, 2, 2], 2, 2),
|
|
(self.module.bisect_left, [1, 1, 2, 2], 3, 4),
|
|
(self.module.bisect_left, [1, 2, 3], 0, 0),
|
|
(self.module.bisect_left, [1, 2, 3], 1, 0),
|
|
(self.module.bisect_left, [1, 2, 3], 1.5, 1),
|
|
(self.module.bisect_left, [1, 2, 3], 2, 1),
|
|
(self.module.bisect_left, [1, 2, 3], 2.5, 2),
|
|
(self.module.bisect_left, [1, 2, 3], 3, 2),
|
|
(self.module.bisect_left, [1, 2, 3], 4, 3),
|
|
(self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 0, 0),
|
|
(self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1, 0),
|
|
(self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1.5, 1),
|
|
(self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2, 1),
|
|
(self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2.5, 3),
|
|
(self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3, 3),
|
|
(self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3.5, 6),
|
|
(self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 4, 6),
|
|
(self.module.bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 5, 10)
|
|
]
|
|
|
|
def test_precomputed(self):
|
|
for func, data, elem, expected in self.precomputedCases:
|
|
self.assertEqual(func(data, elem), expected)
|
|
self.assertEqual(func(UserList(data), elem), expected)
|
|
|
|
def test_random(self, n=25):
|
|
from random import randrange
|
|
for i in range(n):
|
|
data = [randrange(0, n, 2) for j in range(i)]
|
|
data.sort()
|
|
elem = randrange(-1, n+1)
|
|
ip = self.module.bisect_left(data, elem)
|
|
if ip < len(data):
|
|
self.failUnless(elem <= data[ip])
|
|
if ip > 0:
|
|
self.failUnless(data[ip-1] < elem)
|
|
ip = self.module.bisect_right(data, elem)
|
|
if ip < len(data):
|
|
self.failUnless(elem < data[ip])
|
|
if ip > 0:
|
|
self.failUnless(data[ip-1] <= elem)
|
|
|
|
def test_optionalSlicing(self):
|
|
for func, data, elem, expected in self.precomputedCases:
|
|
for lo in range(4):
|
|
lo = min(len(data), lo)
|
|
for hi in range(3,8):
|
|
hi = min(len(data), hi)
|
|
ip = func(data, elem, lo, hi)
|
|
self.failUnless(lo <= ip <= hi)
|
|
if func is self.module.bisect_left and ip < hi:
|
|
self.failUnless(elem <= data[ip])
|
|
if func is self.module.bisect_left and ip > lo:
|
|
self.failUnless(data[ip-1] < elem)
|
|
if func is self.module.bisect_right and ip < hi:
|
|
self.failUnless(elem < data[ip])
|
|
if func is self.module.bisect_right and ip > lo:
|
|
self.failUnless(data[ip-1] <= elem)
|
|
self.assertEqual(ip, max(lo, min(hi, expected)))
|
|
|
|
def test_backcompatibility(self):
|
|
self.assertEqual(self.module.bisect, self.module.bisect_right)
|
|
|
|
def test_keyword_args(self):
|
|
data = [10, 20, 30, 40, 50]
|
|
self.assertEqual(self.module.bisect_left(a=data, x=25, lo=1, hi=3), 2)
|
|
self.assertEqual(self.module.bisect_right(a=data, x=25, lo=1, hi=3), 2)
|
|
self.assertEqual(self.module.bisect(a=data, x=25, lo=1, hi=3), 2)
|
|
self.module.insort_left(a=data, x=25, lo=1, hi=3)
|
|
self.module.insort_right(a=data, x=25, lo=1, hi=3)
|
|
self.module.insort(a=data, x=25, lo=1, hi=3)
|
|
self.assertEqual(data, [10, 20, 25, 25, 25, 30, 40, 50])
|
|
|
|
class TestBisectPython(TestBisect):
|
|
module = py_bisect
|
|
|
|
class TestBisectC(TestBisect):
|
|
module = c_bisect
|
|
|
|
#==============================================================================
|
|
|
|
class TestInsort(unittest.TestCase):
|
|
module = None
|
|
|
|
def test_vsBuiltinSort(self, n=500):
|
|
from random import choice
|
|
for insorted in (list(), UserList()):
|
|
for i in range(n):
|
|
digit = choice("0123456789")
|
|
if digit in "02468":
|
|
f = self.module.insort_left
|
|
else:
|
|
f = self.module.insort_right
|
|
f(insorted, digit)
|
|
self.assertEqual(sorted(insorted), insorted)
|
|
|
|
def test_backcompatibility(self):
|
|
self.assertEqual(self.module.insort, self.module.insort_right)
|
|
|
|
class TestInsortPython(TestInsort):
|
|
module = py_bisect
|
|
|
|
class TestInsortC(TestInsort):
|
|
module = c_bisect
|
|
|
|
#==============================================================================
|
|
|
|
|
|
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 __lt__(self, other):
|
|
raise ZeroDivisionError
|
|
__gt__ = __lt__
|
|
__le__ = __lt__
|
|
__ge__ = __lt__
|
|
__eq__ = __lt__
|
|
__ne__ = __lt__
|
|
|
|
class TestErrorHandling(unittest.TestCase):
|
|
module = None
|
|
|
|
def test_non_sequence(self):
|
|
for f in (self.module.bisect_left, self.module.bisect_right,
|
|
self.module.insort_left, self.module.insort_right):
|
|
self.assertRaises(TypeError, f, 10, 10)
|
|
|
|
def test_len_only(self):
|
|
for f in (self.module.bisect_left, self.module.bisect_right,
|
|
self.module.insort_left, self.module.insort_right):
|
|
self.assertRaises(TypeError, f, LenOnly(), 10)
|
|
|
|
def test_get_only(self):
|
|
for f in (self.module.bisect_left, self.module.bisect_right,
|
|
self.module.insort_left, self.module.insort_right):
|
|
self.assertRaises(TypeError, f, GetOnly(), 10)
|
|
|
|
def test_cmp_err(self):
|
|
seq = [CmpErr(), CmpErr(), CmpErr()]
|
|
for f in (self.module.bisect_left, self.module.bisect_right,
|
|
self.module.insort_left, self.module.insort_right):
|
|
self.assertRaises(ZeroDivisionError, f, seq, 10)
|
|
|
|
def test_arg_parsing(self):
|
|
for f in (self.module.bisect_left, self.module.bisect_right,
|
|
self.module.insort_left, self.module.insort_right):
|
|
self.assertRaises(TypeError, f, 10)
|
|
|
|
class TestErrorHandlingPython(TestErrorHandling):
|
|
module = py_bisect
|
|
|
|
class TestErrorHandlingC(TestErrorHandling):
|
|
module = c_bisect
|
|
|
|
#==============================================================================
|
|
|
|
libreftest = """
|
|
Example from the Library Reference: Doc/library/bisect.rst
|
|
|
|
The bisect() function is generally useful for categorizing numeric data.
|
|
This example uses bisect() to look up a letter grade for an exam total
|
|
(say) based on a set of ordered numeric breakpoints: 85 and up is an `A',
|
|
75..84 is a `B', etc.
|
|
|
|
>>> grades = "FEDCBA"
|
|
>>> breakpoints = [30, 44, 66, 75, 85]
|
|
>>> from bisect import bisect
|
|
>>> def grade(total):
|
|
... return grades[bisect(breakpoints, total)]
|
|
...
|
|
>>> grade(66)
|
|
'C'
|
|
>>> list(map(grade, [33, 99, 77, 44, 12, 88]))
|
|
['E', 'A', 'B', 'D', 'F', 'A']
|
|
|
|
"""
|
|
|
|
#------------------------------------------------------------------------------
|
|
|
|
__test__ = {'libreftest' : libreftest}
|
|
|
|
def test_main(verbose=None):
|
|
from test import test_bisect
|
|
|
|
test_classes = [TestBisectPython, TestBisectC,
|
|
TestInsortPython, TestInsortC,
|
|
TestErrorHandlingPython, TestErrorHandlingC]
|
|
|
|
test_support.run_unittest(*test_classes)
|
|
test_support.run_doctest(test_bisect, verbose)
|
|
|
|
# verify reference counting
|
|
if verbose and hasattr(sys, "gettotalrefcount"):
|
|
import gc
|
|
counts = [None] * 5
|
|
for i in range(len(counts)):
|
|
test_support.run_unittest(*test_classes)
|
|
gc.collect()
|
|
counts[i] = sys.gettotalrefcount()
|
|
print(counts)
|
|
|
|
if __name__ == "__main__":
|
|
test_main(verbose=True)
|