summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorChristian Heimes <christian@cheimes.de>2008-02-24 00:38:49 (GMT)
committerChristian Heimes <christian@cheimes.de>2008-02-24 00:38:49 (GMT)
commitd3eb5a1581b78987621781e674ae514b3c5c68eb (patch)
tree02e5395173df64132335bc82ea31e5da0d40c10a /Lib
parent05e8be17fd15d8e649e026600f5ab20e1154599f (diff)
downloadcpython-d3eb5a1581b78987621781e674ae514b3c5c68eb.zip
cpython-d3eb5a1581b78987621781e674ae514b3c5c68eb.tar.gz
cpython-d3eb5a1581b78987621781e674ae514b3c5c68eb.tar.bz2
Merged revisions 61003-61033 via svnmerge from
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. ........
Diffstat (limited to 'Lib')
-rw-r--r--Lib/imaplib.py46
-rw-r--r--Lib/test/test_bisect.py265
-rw-r--r--Lib/test/test_heapq.py128
-rw-r--r--Lib/test/test_mutex.py33
-rw-r--r--Lib/test/test_operator.py38
-rw-r--r--Lib/test/test_threading.py28
-rw-r--r--Lib/threading.py9
7 files changed, 386 insertions, 161 deletions
diff --git a/Lib/imaplib.py b/Lib/imaplib.py
index 57046d3..0d9704e 100644
--- a/Lib/imaplib.py
+++ b/Lib/imaplib.py
@@ -1151,6 +1151,52 @@ else:
self.file = self.sock.makefile('rb')
+ def read(self, size):
+ """Read 'size' bytes from remote."""
+ # sslobj.read() sometimes returns < size bytes
+ chunks = []
+ read = 0
+ while read < size:
+ data = self.sslobj.read(min(size-read, 16384))
+ read += len(data)
+ chunks.append(data)
+
+ return b''.join(chunks)
+
+
+ def readline(self):
+ """Read line from remote."""
+ line = []
+ while 1:
+ char = self.sslobj.read(1)
+ line.append(char)
+ if char == b"\n": return b''.join(line)
+
+
+ def send(self, data):
+ """Send data to remote."""
+ bytes = len(data)
+ while bytes > 0:
+ sent = self.sslobj.write(data)
+ if sent == bytes:
+ break # avoid copy
+ data = data[sent:]
+ bytes = bytes - sent
+
+
+ def shutdown(self):
+ """Close I/O established in "open"."""
+ self.sock.close()
+
+
+ def socket(self):
+ """Return socket instance used to connect to IMAP4 server.
+
+ socket = <instance>.socket()
+ """
+ return self.sock
+
+
def ssl(self):
"""Return SSLObject instance used to communicate with the IMAP4 server.
diff --git a/Lib/test/test_bisect.py b/Lib/test/test_bisect.py
index dc18a0e..11495ba 100644
--- a/Lib/test/test_bisect.py
+++ b/Lib/test/test_bisect.py
@@ -1,91 +1,113 @@
+import sys
import unittest
from test import test_support
-from bisect import bisect_right, bisect_left, insort_left, insort_right, insort, bisect
from collections import UserList
-class TestBisect(unittest.TestCase):
+# 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']
- precomputedCases = [
- (bisect_right, [], 1, 0),
- (bisect_right, [1], 0, 0),
- (bisect_right, [1], 1, 1),
- (bisect_right, [1], 2, 1),
- (bisect_right, [1, 1], 0, 0),
- (bisect_right, [1, 1], 1, 2),
- (bisect_right, [1, 1], 2, 2),
- (bisect_right, [1, 1, 1], 0, 0),
- (bisect_right, [1, 1, 1], 1, 3),
- (bisect_right, [1, 1, 1], 2, 3),
- (bisect_right, [1, 1, 1, 1], 0, 0),
- (bisect_right, [1, 1, 1, 1], 1, 4),
- (bisect_right, [1, 1, 1, 1], 2, 4),
- (bisect_right, [1, 2], 0, 0),
- (bisect_right, [1, 2], 1, 1),
- (bisect_right, [1, 2], 1.5, 1),
- (bisect_right, [1, 2], 2, 2),
- (bisect_right, [1, 2], 3, 2),
- (bisect_right, [1, 1, 2, 2], 0, 0),
- (bisect_right, [1, 1, 2, 2], 1, 2),
- (bisect_right, [1, 1, 2, 2], 1.5, 2),
- (bisect_right, [1, 1, 2, 2], 2, 4),
- (bisect_right, [1, 1, 2, 2], 3, 4),
- (bisect_right, [1, 2, 3], 0, 0),
- (bisect_right, [1, 2, 3], 1, 1),
- (bisect_right, [1, 2, 3], 1.5, 1),
- (bisect_right, [1, 2, 3], 2, 2),
- (bisect_right, [1, 2, 3], 2.5, 2),
- (bisect_right, [1, 2, 3], 3, 3),
- (bisect_right, [1, 2, 3], 4, 3),
- (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 0, 0),
- (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1, 1),
- (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1.5, 1),
- (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2, 3),
- (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2.5, 3),
- (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3, 6),
- (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3.5, 6),
- (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 4, 10),
- (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 5, 10),
-
- (bisect_left, [], 1, 0),
- (bisect_left, [1], 0, 0),
- (bisect_left, [1], 1, 0),
- (bisect_left, [1], 2, 1),
- (bisect_left, [1, 1], 0, 0),
- (bisect_left, [1, 1], 1, 0),
- (bisect_left, [1, 1], 2, 2),
- (bisect_left, [1, 1, 1], 0, 0),
- (bisect_left, [1, 1, 1], 1, 0),
- (bisect_left, [1, 1, 1], 2, 3),
- (bisect_left, [1, 1, 1, 1], 0, 0),
- (bisect_left, [1, 1, 1, 1], 1, 0),
- (bisect_left, [1, 1, 1, 1], 2, 4),
- (bisect_left, [1, 2], 0, 0),
- (bisect_left, [1, 2], 1, 0),
- (bisect_left, [1, 2], 1.5, 1),
- (bisect_left, [1, 2], 2, 1),
- (bisect_left, [1, 2], 3, 2),
- (bisect_left, [1, 1, 2, 2], 0, 0),
- (bisect_left, [1, 1, 2, 2], 1, 0),
- (bisect_left, [1, 1, 2, 2], 1.5, 2),
- (bisect_left, [1, 1, 2, 2], 2, 2),
- (bisect_left, [1, 1, 2, 2], 3, 4),
- (bisect_left, [1, 2, 3], 0, 0),
- (bisect_left, [1, 2, 3], 1, 0),
- (bisect_left, [1, 2, 3], 1.5, 1),
- (bisect_left, [1, 2, 3], 2, 1),
- (bisect_left, [1, 2, 3], 2.5, 2),
- (bisect_left, [1, 2, 3], 3, 2),
- (bisect_left, [1, 2, 3], 4, 3),
- (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 0, 0),
- (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1, 0),
- (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1.5, 1),
- (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2, 1),
- (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2.5, 3),
- (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3, 3),
- (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3.5, 6),
- (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 4, 6),
- (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 5, 10)
- ]
+# 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:
@@ -98,12 +120,12 @@ class TestBisect(unittest.TestCase):
data = [randrange(0, n, 2) for j in range(i)]
data.sort()
elem = randrange(-1, n+1)
- ip = bisect_left(data, elem)
+ 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 = bisect_right(data, elem)
+ ip = self.module.bisect_right(data, elem)
if ip < len(data):
self.failUnless(elem < data[ip])
if ip > 0:
@@ -117,32 +139,39 @@ class TestBisect(unittest.TestCase):
hi = min(len(data), hi)
ip = func(data, elem, lo, hi)
self.failUnless(lo <= ip <= hi)
- if func is bisect_left and ip < hi:
+ if func is self.module.bisect_left and ip < hi:
self.failUnless(elem <= data[ip])
- if func is bisect_left and ip > lo:
+ if func is self.module.bisect_left and ip > lo:
self.failUnless(data[ip-1] < elem)
- if func is bisect_right and ip < hi:
+ if func is self.module.bisect_right and ip < hi:
self.failUnless(elem < data[ip])
- if func is bisect_right and ip > lo:
+ 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(bisect, bisect_right)
+ self.assertEqual(self.module.bisect, self.module.bisect_right)
def test_keyword_args(self):
data = [10, 20, 30, 40, 50]
- self.assertEqual(bisect_left(a=data, x=25, lo=1, hi=3), 2)
- self.assertEqual(bisect_right(a=data, x=25, lo=1, hi=3), 2)
- self.assertEqual(bisect(a=data, x=25, lo=1, hi=3), 2)
- insort_left(a=data, x=25, lo=1, hi=3)
- insort_right(a=data, x=25, lo=1, hi=3)
- insort(a=data, x=25, lo=1, hi=3)
+ 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
@@ -150,14 +179,20 @@ class TestInsort(unittest.TestCase):
for i in range(n):
digit = choice("0123456789")
if digit in "02468":
- f = insort_left
+ f = self.module.insort_left
else:
- f = insort_right
+ f = self.module.insort_right
f(insorted, digit)
self.assertEqual(sorted(insorted), insorted)
def test_backcompatibility(self):
- self.assertEqual(insort, insort_right)
+ self.assertEqual(self.module.insort, self.module.insort_right)
+
+class TestInsortPython(TestInsort):
+ module = py_bisect
+
+class TestInsortC(TestInsort):
+ module = c_bisect
#==============================================================================
@@ -183,32 +218,44 @@ class CmpErr:
__ne__ = __lt__
class TestErrorHandling(unittest.TestCase):
+ module = None
def test_non_sequence(self):
- for f in (bisect_left, bisect_right, insort_left, insort_right):
+ 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 (bisect_left, bisect_right, insort_left, insort_right):
+ 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 (bisect_left, bisect_right, insort_left, insort_right):
+ 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 (bisect_left, bisect_right, insort_left, insort_right):
+ 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 (bisect_left, bisect_right, insort_left, insort_right):
+ 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/lib/libbisect.tex
+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
@@ -234,12 +281,10 @@ __test__ = {'libreftest' : libreftest}
def test_main(verbose=None):
from test import test_bisect
- from types import BuiltinFunctionType
- import sys
- test_classes = [TestBisect, TestInsort]
- if isinstance(bisect_left, BuiltinFunctionType):
- test_classes.append(TestErrorHandling)
+ test_classes = [TestBisectPython, TestBisectC,
+ TestInsortPython, TestInsortC,
+ TestErrorHandlingPython, TestErrorHandlingC]
test_support.run_unittest(*test_classes)
test_support.run_doctest(test_bisect, verbose)
diff --git a/Lib/test/test_heapq.py b/Lib/test/test_heapq.py
index 62f9662..8ae1637 100644
--- a/Lib/test/test_heapq.py
+++ b/Lib/test/test_heapq.py
@@ -1,21 +1,32 @@
"""Unittests for heapq."""
-from heapq import heappush, heappop, heapify, heapreplace, merge, nlargest, nsmallest
import random
import unittest
from test import test_support
import sys
+# 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['_heapq'] = 0
+# We must also handle the case that heapq was imported before.
+if 'heapq' in sys.modules:
+ del sys.modules['heapq']
+
+# Now we can import the module and get the pure Python implementation.
+import heapq as py_heapq
+
+# Restore everything to normal.
+del sys.modules['_heapq']
+del sys.modules['heapq']
+
+# This is now the module with the C implementation.
+import heapq as c_heapq
-def heapiter(heap):
- # An iterator returning a heap's elements, smallest-first.
- try:
- while 1:
- yield heappop(heap)
- except IndexError:
- pass
class TestHeap(unittest.TestCase):
+ module = None
def test_push_pop(self):
# 1) Push 256 random numbers and pop them off, verifying all's OK.
@@ -25,11 +36,11 @@ class TestHeap(unittest.TestCase):
for i in range(256):
item = random.random()
data.append(item)
- heappush(heap, item)
+ self.module.heappush(heap, item)
self.check_invariant(heap)
results = []
while heap:
- item = heappop(heap)
+ item = self.module.heappop(heap)
self.check_invariant(heap)
results.append(item)
data_sorted = data[:]
@@ -38,10 +49,10 @@ class TestHeap(unittest.TestCase):
# 2) Check that the invariant holds for a sorted array
self.check_invariant(results)
- self.assertRaises(TypeError, heappush, [])
+ self.assertRaises(TypeError, self.module.heappush, [])
try:
- self.assertRaises(TypeError, heappush, None, None)
- self.assertRaises(TypeError, heappop, None)
+ self.assertRaises(TypeError, self.module.heappush, None, None)
+ self.assertRaises(TypeError, self.module.heappop, None)
except AttributeError:
pass
@@ -55,21 +66,29 @@ class TestHeap(unittest.TestCase):
def test_heapify(self):
for size in range(30):
heap = [random.random() for dummy in range(size)]
- heapify(heap)
+ self.module.heapify(heap)
self.check_invariant(heap)
- self.assertRaises(TypeError, heapify, None)
+ self.assertRaises(TypeError, self.module.heapify, None)
def test_naive_nbest(self):
data = [random.randrange(2000) for i in range(1000)]
heap = []
for item in data:
- heappush(heap, item)
+ self.module.heappush(heap, item)
if len(heap) > 10:
- heappop(heap)
+ self.module.heappop(heap)
heap.sort()
self.assertEqual(heap, sorted(data)[-10:])
+ def heapiter(self, heap):
+ # An iterator returning a heap's elements, smallest-first.
+ try:
+ while 1:
+ yield self.module.heappop(heap)
+ except IndexError:
+ pass
+
def test_nbest(self):
# Less-naive "N-best" algorithm, much faster (if len(data) is big
# enough <wink>) than sorting all of data. However, if we had a max
@@ -78,15 +97,15 @@ class TestHeap(unittest.TestCase):
# (10 log-time steps).
data = [random.randrange(2000) for i in range(1000)]
heap = data[:10]
- heapify(heap)
+ self.module.heapify(heap)
for item in data[10:]:
if item > heap[0]: # this gets rarer the longer we run
- heapreplace(heap, item)
- self.assertEqual(list(heapiter(heap)), sorted(data)[-10:])
+ self.module.heapreplace(heap, item)
+ self.assertEqual(list(self.heapiter(heap)), sorted(data)[-10:])
- self.assertRaises(TypeError, heapreplace, None)
- self.assertRaises(TypeError, heapreplace, None, None)
- self.assertRaises(IndexError, heapreplace, [], None)
+ self.assertRaises(TypeError, self.module.heapreplace, None)
+ self.assertRaises(TypeError, self.module.heapreplace, None, None)
+ self.assertRaises(IndexError, self.module.heapreplace, [], None)
def test_heapsort(self):
# Exercise everything with repeated heapsort checks
@@ -95,12 +114,12 @@ class TestHeap(unittest.TestCase):
data = [random.randrange(25) for i in range(size)]
if trial & 1: # Half of the time, use heapify
heap = data[:]
- heapify(heap)
+ self.module.heapify(heap)
else: # The rest of the time, use heappush
heap = []
for item in data:
- heappush(heap, item)
- heap_sorted = [heappop(heap) for i in range(size)]
+ self.module.heappush(heap, item)
+ heap_sorted = [self.module.heappop(heap) for i in range(size)]
self.assertEqual(heap_sorted, sorted(data))
def test_merge(self):
@@ -108,8 +127,8 @@ class TestHeap(unittest.TestCase):
for i in range(random.randrange(5)):
row = sorted(random.randrange(1000) for j in range(random.randrange(10)))
inputs.append(row)
- self.assertEqual(sorted(chain(*inputs)), list(merge(*inputs)))
- self.assertEqual(list(merge()), [])
+ self.assertEqual(sorted(chain(*inputs)), list(self.module.merge(*inputs)))
+ self.assertEqual(list(self.module.merge()), [])
def test_merge_stability(self):
class Int(int):
@@ -123,26 +142,33 @@ class TestHeap(unittest.TestCase):
inputs[stream].append(obj)
for stream in inputs:
stream.sort()
- result = [i.pair for i in merge(*inputs)]
+ result = [i.pair for i in self.module.merge(*inputs)]
self.assertEqual(result, sorted(result))
def test_nsmallest(self):
data = [(random.randrange(2000), i) for i in range(1000)]
for f in (None, lambda x: x[0] * 547 % 2000):
for n in (0, 1, 2, 10, 100, 400, 999, 1000, 1100):
- self.assertEqual(list(nsmallest(n, data)), sorted(data)[:n])
- self.assertEqual(list(nsmallest(n, data, key=f)),
+ self.assertEqual(list(self.module.nsmallest(n, data)),
+ sorted(data)[:n])
+ self.assertEqual(list(self.module.nsmallest(n, data, key=f)),
sorted(data, key=f)[:n])
def test_nlargest(self):
data = [(random.randrange(2000), i) for i in range(1000)]
for f in (None, lambda x: x[0] * 547 % 2000):
for n in (0, 1, 2, 10, 100, 400, 999, 1000, 1100):
- self.assertEqual(list(nlargest(n, data)),
+ self.assertEqual(list(self.module.nlargest(n, data)),
sorted(data, reverse=True)[:n])
- self.assertEqual(list(nlargest(n, data, key=f)),
+ self.assertEqual(list(self.module.nlargest(n, data, key=f)),
sorted(data, key=f, reverse=True)[:n])
+class TestHeapPython(TestHeap):
+ module = py_heapq
+
+class TestHeapC(TestHeap):
+ module = c_heapq
+
#==============================================================================
@@ -240,44 +266,49 @@ def L(seqn):
return chain(imap(lambda x:x, R(Ig(G(seqn)))))
class TestErrorHandling(unittest.TestCase):
+ # only for C implementation
+ module = c_heapq
def test_non_sequence(self):
- for f in (heapify, heappop):
+ for f in (self.module.heapify, self.module.heappop):
self.assertRaises(TypeError, f, 10)
- for f in (heappush, heapreplace, nlargest, nsmallest):
+ for f in (self.module.heappush, self.module.heapreplace,
+ self.module.nlargest, self.module.nsmallest):
self.assertRaises(TypeError, f, 10, 10)
def test_len_only(self):
- for f in (heapify, heappop):
+ for f in (self.module.heapify, self.module.heappop):
self.assertRaises(TypeError, f, LenOnly())
- for f in (heappush, heapreplace):
+ for f in (self.module.heappush, self.module.heapreplace):
self.assertRaises(TypeError, f, LenOnly(), 10)
- for f in (nlargest, nsmallest):
+ for f in (self.module.nlargest, self.module.nsmallest):
self.assertRaises(TypeError, f, 2, LenOnly())
def test_get_only(self):
- for f in (heapify, heappop):
+ for f in (self.module.heapify, self.module.heappop):
self.assertRaises(TypeError, f, GetOnly())
- for f in (heappush, heapreplace):
+ for f in (self.module.heappush, self.module.heapreplace):
self.assertRaises(TypeError, f, GetOnly(), 10)
- for f in (nlargest, nsmallest):
+ for f in (self.module.nlargest, self.module.nsmallest):
self.assertRaises(TypeError, f, 2, GetOnly())
def test_get_only(self):
seq = [CmpErr(), CmpErr(), CmpErr()]
- for f in (heapify, heappop):
+ for f in (self.module.heapify, self.module.heappop):
self.assertRaises(ZeroDivisionError, f, seq)
- for f in (heappush, heapreplace):
+ for f in (self.module.heappush, self.module.heapreplace):
self.assertRaises(ZeroDivisionError, f, seq, 10)
- for f in (nlargest, nsmallest):
+ for f in (self.module.nlargest, self.module.nsmallest):
self.assertRaises(ZeroDivisionError, f, 2, seq)
def test_arg_parsing(self):
- for f in (heapify, heappop, heappush, heapreplace, nlargest, nsmallest):
+ for f in (self.module.heapify, self.module.heappop,
+ self.module.heappush, self.module.heapreplace,
+ self.module.nlargest, self.module.nsmallest):
self.assertRaises(TypeError, f, 10)
def test_iterable_args(self):
- for f in (nlargest, nsmallest):
+ for f in (self.module.nlargest, self.module.nsmallest):
for s in ("123", "", range(1000), (1, 1.2), range(2000,2200,5)):
for g in (G, I, Ig, L, R):
self.assertEqual(list(f(2, g(s))), list(f(2,s)))
@@ -286,15 +317,14 @@ class TestErrorHandling(unittest.TestCase):
self.assertRaises(TypeError, f, 2, N(s))
self.assertRaises(ZeroDivisionError, f, 2, E(s))
+
#==============================================================================
def test_main(verbose=None):
from types import BuiltinFunctionType
- test_classes = [TestHeap]
- if isinstance(heapify, BuiltinFunctionType):
- test_classes.append(TestErrorHandling)
+ test_classes = [TestHeapPython, TestHeapC, TestErrorHandling]
test_support.run_unittest(*test_classes)
# verify reference counting
diff --git a/Lib/test/test_mutex.py b/Lib/test/test_mutex.py
new file mode 100644
index 0000000..6318c70
--- /dev/null
+++ b/Lib/test/test_mutex.py
@@ -0,0 +1,33 @@
+import mutex
+
+import unittest
+import test.test_support
+
+class MutexTest(unittest.TestCase):
+
+ def setUp(self):
+ self.mutex = mutex.mutex()
+
+ def called_by_mutex(self, some_data):
+ self.assert_(self.mutex.test(), "mutex not held")
+ # Nested locking
+ self.mutex.lock(self.called_by_mutex2, "eggs")
+
+ def called_by_mutex2(self, some_data):
+ self.assert_(self.ready_for_2,
+ "called_by_mutex2 called too soon")
+
+ def test_lock_and_unlock(self):
+ self.read_for_2 = False
+ self.mutex.lock(self.called_by_mutex, "spam")
+ self.ready_for_2 = True
+ # unlock both locks
+ self.mutex.unlock()
+ self.mutex.unlock()
+ self.failIf(self.mutex.test(), "mutex still held")
+
+def test_main():
+ test.test_support.run_unittest(MutexTest)
+
+if __name__ == "__main__":
+ test_main()
diff --git a/Lib/test/test_operator.py b/Lib/test/test_operator.py
index dbb8f9e..84b821e 100644
--- a/Lib/test/test_operator.py
+++ b/Lib/test/test_operator.py
@@ -368,6 +368,26 @@ class OperatorTestCase(unittest.TestCase):
raise SyntaxError
self.failUnlessRaises(SyntaxError, operator.attrgetter('foo'), C())
+ # recursive gets
+ a = A()
+ a.name = 'arthur'
+ a.child = A()
+ a.child.name = 'thomas'
+ f = operator.attrgetter('child.name')
+ self.assertEqual(f(a), 'thomas')
+ self.assertRaises(AttributeError, f, a.child)
+ f = operator.attrgetter('name', 'child.name')
+ self.assertEqual(f(a), ('arthur', 'thomas'))
+ f = operator.attrgetter('name', 'child.name', 'child.child.name')
+ self.assertRaises(AttributeError, f, a)
+
+ a.child.child = A()
+ a.child.child.name = 'johnson'
+ f = operator.attrgetter('child.child.name')
+ self.assertEqual(f(a), 'johnson')
+ f = operator.attrgetter('name', 'child.name', 'child.child.name')
+ self.assertEqual(f(a), ('arthur', 'thomas', 'johnson'))
+
def test_itemgetter(self):
a = 'ABCDE'
f = operator.itemgetter(2)
@@ -402,6 +422,24 @@ class OperatorTestCase(unittest.TestCase):
self.assertEqual(operator.itemgetter(2,10,5)(data), ('2', '10', '5'))
self.assertRaises(TypeError, operator.itemgetter(2, 'x', 5), data)
+ def test_methodcaller(self):
+ self.assertRaises(TypeError, operator.methodcaller)
+ class A:
+ def foo(self, *args, **kwds):
+ return args[0] + args[1]
+ def bar(self, f=42):
+ return f
+ a = A()
+ f = operator.methodcaller('foo')
+ self.assertRaises(IndexError, f, a)
+ f = operator.methodcaller('foo', 1, 2)
+ self.assertEquals(f(a), 3)
+ f = operator.methodcaller('bar')
+ self.assertEquals(f(a), 42)
+ self.assertRaises(TypeError, f, a, a)
+ f = operator.methodcaller('bar', f=5)
+ self.assertEquals(f(a), 5)
+
def test_inplace(self):
class C(object):
def __iadd__ (self, other): return "iadd"
diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py
index 1ce5950..3d5c120 100644
--- a/Lib/test/test_threading.py
+++ b/Lib/test/test_threading.py
@@ -8,6 +8,7 @@ import threading
import thread
import time
import unittest
+import weakref
# A trivial mutable counter.
class Counter(object):
@@ -253,6 +254,33 @@ class ThreadTests(unittest.TestCase):
finally:
sys.setcheckinterval(old_interval)
+ def test_no_refcycle_through_target(self):
+ class RunSelfFunction(object):
+ def __init__(self, should_raise):
+ # The links in this refcycle from Thread back to self
+ # should be cleaned up when the thread completes.
+ self.should_raise = should_raise
+ self.thread = threading.Thread(target=self._run,
+ args=(self,),
+ kwargs={'yet_another':self})
+ self.thread.start()
+
+ def _run(self, other_ref, yet_another):
+ if self.should_raise:
+ raise SystemExit
+
+ cyclic_object = RunSelfFunction(should_raise=False)
+ weak_cyclic_object = weakref.ref(cyclic_object)
+ cyclic_object.thread.join()
+ del cyclic_object
+ self.assertEquals(None, weak_cyclic_object())
+
+ raising_cyclic_object = RunSelfFunction(should_raise=True)
+ weak_raising_cyclic_object = weakref.ref(raising_cyclic_object)
+ raising_cyclic_object.thread.join()
+ del raising_cyclic_object
+ self.assertEquals(None, weak_raising_cyclic_object())
+
class ThreadingExceptionTests(unittest.TestCase):
# A RuntimeError should be raised if Thread.start() is called
diff --git a/Lib/threading.py b/Lib/threading.py
index a20ff06..c09ec6a 100644
--- a/Lib/threading.py
+++ b/Lib/threading.py
@@ -441,8 +441,13 @@ class Thread(_Verbose):
_sleep(0.000001) # 1 usec, to let the thread run (Solaris hack)
def run(self):
- if self._target:
- self._target(*self._args, **self._kwargs)
+ try:
+ if self._target:
+ self._target(*self._args, **self._kwargs)
+ finally:
+ # Avoid a refcycle if the thread is running a function with
+ # an argument that has a member that points to the thread.
+ del self._target, self._args, self._kwargs
def _bootstrap(self):
# Wrapper around the real bootstrap code that ignores