diff options
Diffstat (limited to 'Lib')
| -rw-r--r-- | Lib/_dummy_thread.py | 3 | ||||
| -rw-r--r-- | Lib/collections/__init__.py | 21 | ||||
| -rw-r--r-- | Lib/test/string_tests.py | 57 | ||||
| -rw-r--r-- | Lib/test/test_bytes.py | 62 | ||||
| -rw-r--r-- | Lib/test/test_logging.py | 29 | ||||
| -rw-r--r-- | Lib/test/test_os.py | 15 | ||||
| -rw-r--r-- | Lib/test/test_threading.py | 13 | ||||
| -rw-r--r-- | Lib/test/test_threadsignals.py | 7 | ||||
| -rw-r--r-- | Lib/threading.py | 3 |
9 files changed, 182 insertions, 28 deletions
diff --git a/Lib/_dummy_thread.py b/Lib/_dummy_thread.py index 13b1f26..f2465a9 100644 --- a/Lib/_dummy_thread.py +++ b/Lib/_dummy_thread.py @@ -149,3 +149,6 @@ def interrupt_main(): else: global _interrupt _interrupt = True + +def info(): + return {'name': 'dummy'} diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index a6bcaea..c0c2180 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -152,17 +152,6 @@ class OrderedDict(dict): link.next = first root.next = first.prev = link - def __reduce__(self): - 'Return state information for pickling' - items = [[k, self[k]] for k in self] - tmp = self.__map, self.__root, self.__hardroot - del self.__map, self.__root, self.__hardroot - inst_dict = vars(self).copy() - self.__map, self.__root, self.__hardroot = tmp - if inst_dict: - return (self.__class__, (items,), inst_dict) - return self.__class__, (items,) - def __sizeof__(self): sizeof = _sys.getsizeof n = len(self) + 1 # number of links including root @@ -203,6 +192,16 @@ class OrderedDict(dict): return '%s()' % (self.__class__.__name__,) return '%s(%r)' % (self.__class__.__name__, list(self.items())) + def __reduce__(self): + 'Return state information for pickling' + items = [[k, self[k]] for k in self] + inst_dict = vars(self).copy() + for k in vars(OrderedDict()): + inst_dict.pop(k, None) + if inst_dict: + return (self.__class__, (items,), inst_dict) + return self.__class__, (items,) + def copy(self): 'od.copy() -> a shallow copy of od' return self.__class__(self) diff --git a/Lib/test/string_tests.py b/Lib/test/string_tests.py index 1cc36d8..fca38c3 100644 --- a/Lib/test/string_tests.py +++ b/Lib/test/string_tests.py @@ -1183,6 +1183,63 @@ class MixinStrUnicodeUserStringTest: self.checkraises(ValueError, S, 'rpartition', '') self.checkraises(TypeError, S, 'rpartition', None) + def test_none_arguments(self): + # issue 11828 + s = 'hello' + self.checkequal(2, s, 'find', 'l', None) + self.checkequal(3, s, 'find', 'l', -2, None) + self.checkequal(2, s, 'find', 'l', None, -2) + self.checkequal(0, s, 'find', 'h', None, None) + + self.checkequal(3, s, 'rfind', 'l', None) + self.checkequal(3, s, 'rfind', 'l', -2, None) + self.checkequal(2, s, 'rfind', 'l', None, -2) + self.checkequal(0, s, 'rfind', 'h', None, None) + + self.checkequal(2, s, 'index', 'l', None) + self.checkequal(3, s, 'index', 'l', -2, None) + self.checkequal(2, s, 'index', 'l', None, -2) + self.checkequal(0, s, 'index', 'h', None, None) + + self.checkequal(3, s, 'rindex', 'l', None) + self.checkequal(3, s, 'rindex', 'l', -2, None) + self.checkequal(2, s, 'rindex', 'l', None, -2) + self.checkequal(0, s, 'rindex', 'h', None, None) + + self.checkequal(2, s, 'count', 'l', None) + self.checkequal(1, s, 'count', 'l', -2, None) + self.checkequal(1, s, 'count', 'l', None, -2) + self.checkequal(0, s, 'count', 'x', None, None) + + self.checkequal(True, s, 'endswith', 'o', None) + self.checkequal(True, s, 'endswith', 'lo', -2, None) + self.checkequal(True, s, 'endswith', 'l', None, -2) + self.checkequal(False, s, 'endswith', 'x', None, None) + + self.checkequal(True, s, 'startswith', 'h', None) + self.checkequal(True, s, 'startswith', 'l', -2, None) + self.checkequal(True, s, 'startswith', 'h', None, -2) + self.checkequal(False, s, 'startswith', 'x', None, None) + + def test_find_etc_raise_correct_error_messages(self): + # issue 11828 + s = 'hello' + x = 'x' + self.assertRaisesRegex(TypeError, r'^find\(', s.find, + x, None, None, None) + self.assertRaisesRegex(TypeError, r'^rfind\(', s.rfind, + x, None, None, None) + self.assertRaisesRegex(TypeError, r'^index\(', s.index, + x, None, None, None) + self.assertRaisesRegex(TypeError, r'^rindex\(', s.rindex, + x, None, None, None) + self.assertRaisesRegex(TypeError, r'^count\(', s.count, + x, None, None, None) + self.assertRaisesRegex(TypeError, r'^startswith\(', s.startswith, + x, None, None, None) + self.assertRaisesRegex(TypeError, r'^endswith\(', s.endswith, + x, None, None, None) + class MixinStrUnicodeTest: # Additional tests that only work with str and unicode. diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index 0b70c3a..5c6238b 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -478,6 +478,68 @@ class BaseBytesTest(unittest.TestCase): self.assertRaises(ValueError, self.type2test.maketrans, b'abc', b'xyzq') self.assertRaises(TypeError, self.type2test.maketrans, 'abc', 'def') + def test_none_arguments(self): + # issue 11828 + b = self.type2test(b'hello') + l = self.type2test(b'l') + h = self.type2test(b'h') + x = self.type2test(b'x') + o = self.type2test(b'o') + + self.assertEqual(2, b.find(l, None)) + self.assertEqual(3, b.find(l, -2, None)) + self.assertEqual(2, b.find(l, None, -2)) + self.assertEqual(0, b.find(h, None, None)) + + self.assertEqual(3, b.rfind(l, None)) + self.assertEqual(3, b.rfind(l, -2, None)) + self.assertEqual(2, b.rfind(l, None, -2)) + self.assertEqual(0, b.rfind(h, None, None)) + + self.assertEqual(2, b.index(l, None)) + self.assertEqual(3, b.index(l, -2, None)) + self.assertEqual(2, b.index(l, None, -2)) + self.assertEqual(0, b.index(h, None, None)) + + self.assertEqual(3, b.rindex(l, None)) + self.assertEqual(3, b.rindex(l, -2, None)) + self.assertEqual(2, b.rindex(l, None, -2)) + self.assertEqual(0, b.rindex(h, None, None)) + + self.assertEqual(2, b.count(l, None)) + self.assertEqual(1, b.count(l, -2, None)) + self.assertEqual(1, b.count(l, None, -2)) + self.assertEqual(0, b.count(x, None, None)) + + self.assertEqual(True, b.endswith(o, None)) + self.assertEqual(True, b.endswith(o, -2, None)) + self.assertEqual(True, b.endswith(l, None, -2)) + self.assertEqual(False, b.endswith(x, None, None)) + + self.assertEqual(True, b.startswith(h, None)) + self.assertEqual(True, b.startswith(l, -2, None)) + self.assertEqual(True, b.startswith(h, None, -2)) + self.assertEqual(False, b.startswith(x, None, None)) + + def test_find_etc_raise_correct_error_messages(self): + # issue 11828 + b = self.type2test(b'hello') + x = self.type2test(b'x') + self.assertRaisesRegex(TypeError, r'\bfind\b', b.find, + x, None, None, None) + self.assertRaisesRegex(TypeError, r'\brfind\b', b.rfind, + x, None, None, None) + self.assertRaisesRegex(TypeError, r'\bindex\b', b.index, + x, None, None, None) + self.assertRaisesRegex(TypeError, r'\brindex\b', b.rindex, + x, None, None, None) + self.assertRaisesRegex(TypeError, r'\bcount\b', b.count, + x, None, None, None) + self.assertRaisesRegex(TypeError, r'\bstartswith\b', b.startswith, + x, None, None, None) + self.assertRaisesRegex(TypeError, r'\bendswith\b', b.endswith, + x, None, None, None) + class BytesTest(BaseBytesTest): type2test = bytes diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index b2e3327..48add6d 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -2255,7 +2255,7 @@ class RecordingHandler(logging.NullHandler): class ShutdownTest(BaseTest): - """Tets suite for the shutdown method.""" + """Test suite for the shutdown method.""" def setUp(self): super(ShutdownTest, self).setUp() @@ -2342,7 +2342,7 @@ class ShutdownTest(BaseTest): class ModuleLevelMiscTest(BaseTest): - """Tets suite for some module level methods.""" + """Test suite for some module level methods.""" def test_disable(self): old_disable = logging.root.manager.disable @@ -2356,7 +2356,7 @@ class ModuleLevelMiscTest(BaseTest): def _test_log(self, method, level=None): called = [] patch(self, logging, 'basicConfig', - lambda *a, **kw: called.append(a, kw)) + lambda *a, **kw: called.append((a, kw))) recording = RecordingHandler() logging.root.addHandler(recording) @@ -2410,19 +2410,30 @@ class ModuleLevelMiscTest(BaseTest): class BasicConfigTest(unittest.TestCase): - """Tets suite for logging.basicConfig.""" + """Test suite for logging.basicConfig.""" def setUp(self): super(BasicConfigTest, self).setUp() - handlers = logging.root.handlers - self.addCleanup(lambda: setattr(logging.root, 'handlers', handlers)) + self.handlers = logging.root.handlers + self.saved_handlers = logging._handlers.copy() + self.saved_handler_list = logging._handlerList[:] + self.original_logging_level = logging.root.level + self.addCleanup(self.cleanup) logging.root.handlers = [] def tearDown(self): - logging.shutdown() + for h in logging.root.handlers[:]: + logging.root.removeHandler(h) + h.close() super(BasicConfigTest, self).tearDown() - @unittest.skipIf(True, "test disabled, issue #11557") + def cleanup(self): + setattr(logging.root, 'handlers', self.handlers) + logging._handlers.clear() + logging._handlers.update(self.saved_handlers) + logging._handlerList[:] = self.saved_handler_list + logging.root.level = self.original_logging_level + def test_no_kwargs(self): logging.basicConfig() @@ -2441,7 +2452,7 @@ class BasicConfigTest(unittest.TestCase): self.assertIsInstance(formatter._style, logging.PercentStyle) # level is not explicitely set - self.assertEqual(logging.root.level, logging.WARNING) + self.assertEqual(logging.root.level, self.original_logging_level) def test_filename(self): logging.basicConfig(filename='test.log') diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 35aa7fa..5432412 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -27,12 +27,15 @@ except ImportError: # and unmaintained) linuxthreads threading library. There's an issue # when combining linuxthreads with a failed execv call: see # http://bugs.python.org/issue4970. -if (hasattr(os, "confstr_names") and - "CS_GNU_LIBPTHREAD_VERSION" in os.confstr_names): - libpthread = os.confstr("CS_GNU_LIBPTHREAD_VERSION") - USING_LINUXTHREADS= libpthread.startswith("linuxthreads") -else: - USING_LINUXTHREADS= False +USING_LINUXTHREADS = False +if threading: + info = threading._info() + try: + pthread_version = info['pthread_version'] + except KeyError: + pass + else: + USING_LINUXTHREADS = pthread_version.startswith("linuxthreads") # Tests creating TESTFN class FileTests(unittest.TestCase): diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index c107652..fd63d39 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -718,6 +718,17 @@ class BoundedSemaphoreTests(lock_tests.BoundedSemaphoreTests): class BarrierTests(lock_tests.BarrierTests): barriertype = staticmethod(threading.Barrier) + +class MiscTests(unittest.TestCase): + def test_info(self): + info = threading._info() + self.assertIn(info['name'], + 'nt os2 pthread solaris'.split()) + if info['name'] == 'pthread': + self.assertIn(info['lock_implementation'], + ('semaphore', 'mutex+cond')) + + def test_main(): test.support.run_unittest(LockTests, PyRLockTests, CRLockTests, EventTests, ConditionAsRLockTests, ConditionTests, @@ -725,7 +736,7 @@ def test_main(): ThreadTests, ThreadJoinOnShutdown, ThreadingExceptionTests, - BarrierTests + BarrierTests, MiscTests, ) if __name__ == "__main__": diff --git a/Lib/test/test_threadsignals.py b/Lib/test/test_threadsignals.py index 46e405a..b0bc607 100644 --- a/Lib/test/test_threadsignals.py +++ b/Lib/test/test_threadsignals.py @@ -14,6 +14,9 @@ if sys.platform[:3] in ('win', 'os2') or sys.platform=='riscos': process_pid = os.getpid() signalled_all=thread.allocate_lock() +info = thread.info() +USING_PTHREAD_COND = (info['name'] == 'pthread' + and info['lock_implementation'] == 'mutex+cond') def registerSignals(for_usr1, for_usr2, for_alrm): usr1 = signal.signal(signal.SIGUSR1, for_usr1) @@ -70,6 +73,8 @@ class ThreadSignals(unittest.TestCase): def alarm_interrupt(self, sig, frame): raise KeyboardInterrupt + @unittest.skipIf(USING_PTHREAD_COND, + 'POSIX condition variables cannot be interrupted') def test_lock_acquire_interruption(self): # Mimic receiving a SIGINT (KeyboardInterrupt) with SIGALRM while stuck # in a deadlock. @@ -91,6 +96,8 @@ class ThreadSignals(unittest.TestCase): finally: signal.signal(signal.SIGALRM, oldalrm) + @unittest.skipIf(USING_PTHREAD_COND, + 'POSIX condition variables cannot be interrupted') def test_rlock_acquire_interruption(self): # Mimic receiving a SIGINT (KeyboardInterrupt) with SIGALRM while stuck # in a deadlock. diff --git a/Lib/threading.py b/Lib/threading.py index cb09afa..eb3cb62 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -19,7 +19,7 @@ from collections import deque __all__ = ['active_count', 'Condition', 'current_thread', 'enumerate', 'Event', 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread', 'Barrier', - 'Timer', 'setprofile', 'settrace', 'local', 'stack_size'] + 'Timer', 'setprofile', 'settrace', 'local', 'stack_size', '_info'] # Rename some stuff so "from threading import *" is safe _start_new_thread = _thread.start_new_thread @@ -31,6 +31,7 @@ try: except AttributeError: _CRLock = None TIMEOUT_MAX = _thread.TIMEOUT_MAX +_info = _thread.info del _thread |
