From e549ead8263819ac47f60cdd0239592750888f0b Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 28 Mar 2009 21:42:05 +0000 Subject: [PATCH] Merged revisions 70554,70588-70589,70598,70605,70611-70621,70623-70624,70626-70627 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r70554 | benjamin.peterson | 2009-03-23 16:25:15 -0500 (Mon, 23 Mar 2009) | 1 line complain when there's no last exception ........ r70588 | benjamin.peterson | 2009-03-24 17:56:32 -0500 (Tue, 24 Mar 2009) | 1 line fix newline issue in test summary ........ r70589 | benjamin.peterson | 2009-03-24 18:07:07 -0500 (Tue, 24 Mar 2009) | 1 line another style nit ........ r70598 | benjamin.peterson | 2009-03-25 16:24:04 -0500 (Wed, 25 Mar 2009) | 1 line add shorthands for expected failures and unexpected success ........ r70605 | benjamin.peterson | 2009-03-26 11:32:23 -0500 (Thu, 26 Mar 2009) | 1 line remove uneeded function ........ r70611 | benjamin.peterson | 2009-03-26 13:35:37 -0500 (Thu, 26 Mar 2009) | 1 line add much better tests for python version information parsing ........ r70612 | benjamin.peterson | 2009-03-26 13:55:48 -0500 (Thu, 26 Mar 2009) | 1 line more and more implementations now support sys.subversion ........ r70613 | benjamin.peterson | 2009-03-26 13:58:30 -0500 (Thu, 26 Mar 2009) | 1 line roll old test in with new one ........ r70614 | benjamin.peterson | 2009-03-26 14:09:21 -0500 (Thu, 26 Mar 2009) | 1 line add support for PyPy ........ r70615 | benjamin.peterson | 2009-03-26 14:58:18 -0500 (Thu, 26 Mar 2009) | 5 lines add some useful utilities for skipping tests with unittest's new skipping ability most significantly apply a modified portion of the patch from #4242 with patches for skipping implementation details ........ r70616 | benjamin.peterson | 2009-03-26 15:05:50 -0500 (Thu, 26 Mar 2009) | 1 line rename TestCase.skip() to skipTest() because it causes annoying problems with trial #5571 ........ r70617 | benjamin.peterson | 2009-03-26 15:17:27 -0500 (Thu, 26 Mar 2009) | 1 line apply the second part of #4242's patch; classify all the implementation details in test_descr ........ r70618 | benjamin.peterson | 2009-03-26 15:48:25 -0500 (Thu, 26 Mar 2009) | 1 line remove test_support.TestSkipped and just use unittest.SkipTest ........ r70619 | benjamin.peterson | 2009-03-26 15:49:40 -0500 (Thu, 26 Mar 2009) | 1 line fix naming ........ r70620 | benjamin.peterson | 2009-03-26 16:10:30 -0500 (Thu, 26 Mar 2009) | 1 line fix incorrect auto-translation of TestSkipped -> unittest.SkipTest ........ r70621 | benjamin.peterson | 2009-03-26 16:11:16 -0500 (Thu, 26 Mar 2009) | 1 line must pass argument to get expected behavior ;) ........ r70623 | benjamin.peterson | 2009-03-26 16:30:10 -0500 (Thu, 26 Mar 2009) | 1 line add missing import ........ r70624 | benjamin.peterson | 2009-03-26 16:30:54 -0500 (Thu, 26 Mar 2009) | 1 line ** is required here ........ r70626 | benjamin.peterson | 2009-03-26 16:40:29 -0500 (Thu, 26 Mar 2009) | 1 line update email tests to use SkipTest ........ r70627 | benjamin.peterson | 2009-03-26 16:44:43 -0500 (Thu, 26 Mar 2009) | 1 line fix another name ........ --- Doc/library/unittest.rst | 2 +- Lib/email/test/test_email_codecs.py | 4 +- Lib/platform.py | 43 +++++---- Lib/test/regrtest.py | 3 +- Lib/test/support.py | 96 ++++++++++++++----- Lib/test/test__locale.py | 4 +- Lib/test/test_curses.py | 6 +- Lib/test/test_decimal.py | 5 +- Lib/test/test_descr.py | 139 +++++++++++++++++++--------- Lib/test/test_epoll.py | 4 +- Lib/test/test_fork1.py | 4 +- Lib/test/test_ioctl.py | 10 +- Lib/test/test_kqueue.py | 2 +- Lib/test/test_largefile.py | 6 +- Lib/test/test_locale.py | 10 +- Lib/test/test_minidom.py | 2 +- Lib/test/test_multiprocessing.py | 5 +- Lib/test/test_nis.py | 4 +- Lib/test/test_openpty.py | 4 +- Lib/test/test_ossaudiodev.py | 6 +- Lib/test/test_pep277.py | 2 +- Lib/test/test_pipes.py | 4 +- Lib/test/test_platform.py | 97 ++++++++++++------- Lib/test/test_poll.py | 4 +- Lib/test/test_posix.py | 8 +- Lib/test/test_pty.py | 4 +- Lib/test/test_signal.py | 2 +- Lib/test/test_site.py | 4 +- Lib/test/test_socketserver.py | 4 +- Lib/test/test_sqlite.py | 5 +- Lib/test/test_ssl.py | 2 +- Lib/test/test_tempfile.py | 8 +- Lib/test/test_threaded_import.py | 4 +- Lib/test/test_threadsignals.py | 6 +- Lib/test/test_tk.py | 3 +- Lib/test/test_ttk_guionly.py | 3 +- Lib/test/test_unicode_file.py | 4 +- Lib/test/test_unittest.py | 4 +- Lib/test/test_univnewlines.py | 4 +- Lib/test/test_wait3.py | 7 +- Lib/test/test_wait4.py | 6 +- Lib/traceback.py | 2 + Lib/unittest.py | 28 +++--- 43 files changed, 359 insertions(+), 215 deletions(-) diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index 22bf7f37518..3a1e63aaaee 100644 --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -575,7 +575,7 @@ Test cases instance. - .. method:: skip(reason) + .. method:: skipTest(reason) Calling this during the a test method or :meth:`setUp` skips the current test. See :ref:`unittest-skipping` for more information. diff --git a/Lib/email/test/test_email_codecs.py b/Lib/email/test/test_email_codecs.py index a7bcb892fa7..8accabe158b 100644 --- a/Lib/email/test/test_email_codecs.py +++ b/Lib/email/test/test_email_codecs.py @@ -3,7 +3,7 @@ # email package unit tests for (optional) Asian codecs import unittest -from test.support import TestSkipped, run_unittest +from test.support import run_unittest from email.test.test_email import TestEmailBase from email.Charset import Charset @@ -15,7 +15,7 @@ from email.Message import Message try: str('foo', 'euc-jp') except LookupError: - raise TestSkipped + raise unittest.SkipTest diff --git a/Lib/platform.py b/Lib/platform.py index 04f7f9bd01a..21e098b989d 100755 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -1240,15 +1240,17 @@ _sys_version_parser = re.compile( '\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*' '\[([^\]]+)\]?', re.ASCII) -_jython_sys_version_parser = re.compile( - r'([\d\.]+)', re.ASCII) - _ironpython_sys_version_parser = re.compile( r'IronPython\s*' '([\d\.]+)' '(?: \(([\d\.]+)\))?' ' on (.NET [\d\.]+)', re.ASCII) +_pypy_sys_version_parser = re.compile( + r'([\w.+]+)\s*' + '\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*' + '\[PyPy [^\]]+\]?') + _sys_version_cache = {} def _sys_version(sys_version=None): @@ -1290,25 +1292,29 @@ def _sys_version(sys_version=None): 'failed to parse IronPython sys.version: %s' % repr(sys_version)) version, alt_version, compiler = match.groups() - branch = '' - revision = '' buildno = '' builddate = '' elif sys.platform[:4] == 'java': # Jython name = 'Jython' - match = _jython_sys_version_parser.match(sys_version) + match = _sys_version_parser.match(sys_version) if match is None: raise ValueError( 'failed to parse Jython sys.version: %s' % repr(sys_version)) - version, = match.groups() - branch = '' - revision = '' + version, buildno, builddate, buildtime, _ = match.groups() compiler = sys.platform - buildno = '' - builddate = '' + + elif "PyPy" in sys_version: + # PyPy + name = "PyPy" + match = _pypy_sys_version_parser.match(sys_version) + if match is None: + raise ValueError("failed to parse PyPy sys.version: %s" % + repr(sys_version)) + version, buildno, builddate, buildtime = match.groups() + compiler = "" else: # CPython @@ -1319,15 +1325,16 @@ def _sys_version(sys_version=None): repr(sys_version)) version, buildno, builddate, buildtime, compiler = \ match.groups() - if hasattr(sys, 'subversion'): - # sys.subversion was added in Python 2.5 - name, branch, revision = sys.subversion - else: - name = 'CPython' - branch = '' - revision = '' + name = 'CPython' builddate = builddate + ' ' + buildtime + if hasattr(sys, 'subversion'): + # sys.subversion was added in Python 2.5 + _, branch, revision = sys.subversion + else: + branch = '' + revision = '' + # Add the patchlevel version if missing l = version.split('.') if len(l) == 2: diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py index 203bd955f5f..66c39d6cb22 100755 --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -139,6 +139,7 @@ import sys import time import traceback import warnings +import unittest from inspect import isabstract # I see no other way to suppress these warnings; @@ -614,7 +615,7 @@ def runtest_inner(test, generate, verbose, quiet, test_times, print(test, "skipped --", msg) sys.stdout.flush() return -2 - except (ImportError, support.TestSkipped) as msg: + except (ImportError, unittest.SkipTest) as msg: if not quiet: print(test, "skipped --", msg) sys.stdout.flush() diff --git a/Lib/test/support.py b/Lib/test/support.py index 0fa9d6bcafa..e20917007d6 100644 --- a/Lib/test/support.py +++ b/Lib/test/support.py @@ -8,12 +8,12 @@ import errno import socket import sys import os -import os.path +import platform import shutil import warnings import unittest -__all__ = ["Error", "TestFailed", "TestSkipped", "ResourceDenied", "import_module", +__all__ = ["Error", "TestFailed", "ResourceDenied", "import_module", "verbose", "use_resources", "max_memuse", "record_original_stdout", "get_original_stdout", "unload", "unlink", "rmtree", "forget", "is_resource_enabled", "requires", "find_unused_port", "bind_port", @@ -24,7 +24,7 @@ __all__ = ["Error", "TestFailed", "TestSkipped", "ResourceDenied", "import_modul "TransientResource", "transient_internet", "run_with_locale", "set_memlimit", "bigmemtest", "bigaddrspacetest", "BasicTestRunner", "run_unittest", "run_doctest", "threading_setup", "threading_cleanup", - "reap_children"] + "reap_children", "cpython_only", "check_impl_detail"] class Error(Exception): """Base class for regression test exceptions.""" @@ -32,17 +32,7 @@ class Error(Exception): class TestFailed(Error): """Test failed.""" -class TestSkipped(Error): - """Test skipped. - - This can be raised to indicate that a test was deliberatly - skipped, but not because a feature wasn't available. For - example, if some resource can't be used, such as the network - appears to be unavailable, this should be raised instead of - TestFailed. - """ - -class ResourceDenied(TestSkipped): +class ResourceDenied(unittest.SkipTest): """Test skipped because it requested a disallowed resource. This is raised when a test calls requires() for a resource that @@ -51,7 +41,7 @@ class ResourceDenied(TestSkipped): """ def import_module(name, deprecated=False): - """Import the module to be tested, raising TestSkipped if it is not + """Import the module to be tested, raising SkipTest if it is not available.""" with warnings.catch_warnings(): if deprecated: @@ -60,7 +50,7 @@ def import_module(name, deprecated=False): try: module = __import__(name, level=0) except ImportError: - raise TestSkipped("No module named " + name) + raise unittest.SkipTest("No module named " + name) else: return module @@ -124,7 +114,7 @@ def requires(resource, msg=None): possibility of False being returned occurs when regrtest.py is executing.""" # see if the caller's module is __main__ - if so, treat as if # the resource was set - if sys._getframe().f_back.f_globals.get("__name__") == "__main__": + if sys._getframe(1).f_globals.get("__name__") == "__main__": return if not is_resource_enabled(resource): if msg is None: @@ -357,12 +347,8 @@ def make_bad_fd(): unlink(TESTFN) def check_syntax_error(testcase, statement): - try: - compile(statement, '', 'exec') - except SyntaxError: - pass - else: - testcase.fail('Missing SyntaxError: "%s"' % statement) + testcase.assertRaises(SyntaxError, compile, statement, + '', 'exec') def open_urlresource(url, *args, **kw): import urllib.request, urllib.parse @@ -522,6 +508,21 @@ def captured_output(stream_name): def captured_stdout(): return captured_output("stdout") +def gc_collect(): + """Force as many objects as possible to be collected. + + In non-CPython implementations of Python, this is needed because timely + deallocation is not guaranteed by the garbage collector. (Even in CPython + this can be the case in case of reference cycles.) This means that __del__ + methods may be called later than expected and weakrefs may remain alive for + longer than expected. This function tries its best to force all garbage + objects to disappear. + """ + import gc + gc.collect() + gc.collect() + gc.collect() + #======================================================================= # Decorator for running a function in a different locale, correctly resetting @@ -681,6 +682,55 @@ class BasicTestRunner: test(result) return result +def _id(obj): + return obj + +def requires_resource(resource): + if resource_is_enabled(resource): + return _id + else: + return unittest.skip("resource {0!r} is not enabled".format(resource)) + +def cpython_only(test): + """ + Decorator for tests only applicable on CPython. + """ + return impl_detail(cpython=True)(test) + +def impl_detail(msg=None, **guards): + if check_impl_detail(**guards): + return _id + if msg is None: + guardnames, default = _parse_guards(guards) + if default: + msg = "implementation detail not available on {0}" + else: + msg = "implementation detail specific to {0}" + guardnames = sorted(guardnames.keys()) + msg = msg.format(' or '.join(guardnames)) + return unittest.skip(msg) + +def _parse_guards(guards): + # Returns a tuple ({platform_name: run_me}, default_value) + if not guards: + return ({'cpython': True}, False) + is_true = guards.values()[0] + assert guards.values() == [is_true] * len(guards) # all True or all False + return (guards, not is_true) + +# Use the following check to guard CPython's implementation-specific tests -- +# or to run them only on the implementation(s) guarded by the arguments. +def check_impl_detail(**guards): + """This function returns True or False depending on the host platform. + Examples: + if check_impl_detail(): # only on CPython (default) + if check_impl_detail(jython=True): # only on Jython + if check_impl_detail(cpython=False): # everywhere except on CPython + """ + guards, default = _parse_guards(guards) + return guards.get(platform.python_implementation().lower(), default) + + def _run_suite(suite): """Run tests from a unittest.TestSuite-derived class.""" diff --git a/Lib/test/test__locale.py b/Lib/test/test__locale.py index 9dec027d21f..918be890975 100644 --- a/Lib/test/test__locale.py +++ b/Lib/test/test__locale.py @@ -1,4 +1,4 @@ -from test.support import verbose, TestSkipped, run_unittest +from test.support import verbose, run_unittest from _locale import (setlocale, LC_ALL, LC_CTYPE, LC_NUMERIC, RADIXCHAR, THOUSEP, nl_langinfo, localeconv, Error) import unittest @@ -7,7 +7,7 @@ from platform import uname if uname()[0] == "Darwin": maj, min, mic = [int(part) for part in uname()[2].split(".")] if (maj, min, mic) < (8, 0, 0): - raise TestSkipped("locale support broken for OS X < 10.4") + raise unittest.SkipTest("locale support broken for OS X < 10.4") candidate_locales = ['es_UY', 'fr_FR', 'fi_FI', 'es_CO', 'pt_PT', 'it_IT', 'et_EE', 'es_PY', 'no_NO', 'nl_NL', 'lv_LV', 'el_GR', 'be_BY', 'fr_BE', diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py index ebeb9263208..ed93946229c 100644 --- a/Lib/test/test_curses.py +++ b/Lib/test/test_curses.py @@ -16,16 +16,16 @@ import curses.panel # 'curses' resource be given on the regrtest command line using the -u # option. If not available, nothing after this line will be executed. -from test.support import requires, TestSkipped +from test.support import requires requires('curses') # XXX: if newterm was supported we could use it instead of initscr and not exit term = os.environ.get('TERM') if not term or term == 'unknown': - raise TestSkipped("$TERM=%r, calling initscr() may cause exit" % term) + raise unittest.SkipTest("$TERM=%r, calling initscr() may cause exit" % term) if sys.platform == "cygwin": - raise TestSkipped("cygwin's curses mostly just hangs") + raise unittest.SkipTest("cygwin's curses mostly just hangs") def window_funcs(stdscr): "Test the methods of windows" diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 219348c616a..ceca1868207 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -31,8 +31,7 @@ import pickle, copy import unittest from decimal import * import numbers -from test.support import (TestSkipped, run_unittest, run_doctest, - is_resource_enabled) +from test.support import run_unittest, run_doctest, is_resource_enabled import random try: import threading @@ -194,7 +193,7 @@ class DecimalTest(unittest.TestCase): def eval_file(self, file): global skip_expected if skip_expected: - raise TestSkipped + raise unittest.SkipTest return for line in open(file): line = line.replace('\r\n', '').replace('\n', '') diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 0554fc2fc85..6dba040f49b 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -65,8 +65,9 @@ class OperatorsTest(unittest.TestCase): # Find method in parent class while meth not in t.__dict__: t = t.__bases__[0] - - self.assertEqual(m, t.__dict__[meth]) + # in some implementations (e.g. PyPy), 'm' can be a regular unbound + # method object; the getattr() below obtains its underlying function. + self.assertEqual(getattr(m, 'im_func', m), t.__dict__[meth]) self.assertEqual(m(a), res) bm = getattr(a, meth) self.assertEqual(bm(), res) @@ -85,7 +86,9 @@ class OperatorsTest(unittest.TestCase): m = getattr(t, meth) while meth not in t.__dict__: t = t.__bases__[0] - self.assertEqual(m, t.__dict__[meth]) + # in some implementations (e.g. PyPy), 'm' can be a regular unbound + # method object; the getattr() below obtains its underlying function. + self.assertEqual(getattr(m, 'im_func', m), t.__dict__[meth]) self.assertEqual(m(a, b), res) bm = getattr(a, meth) self.assertEqual(bm(b), res) @@ -97,7 +100,9 @@ class OperatorsTest(unittest.TestCase): m = getattr(t, meth) while meth not in t.__dict__: t = t.__bases__[0] - self.assertEqual(m, t.__dict__[meth]) + # in some implementations (e.g. PyPy), 'm' can be a regular unbound + # method object; the getattr() below obtains its underlying function. + self.assertEqual(getattr(m, 'im_func', m), t.__dict__[meth]) self.assertEqual(m(a, slice(b, c)), res) bm = getattr(a, meth) self.assertEqual(bm(slice(b, c)), res) @@ -110,7 +115,9 @@ class OperatorsTest(unittest.TestCase): m = getattr(t, meth) while meth not in t.__dict__: t = t.__bases__[0] - self.assertEqual(m, t.__dict__[meth]) + # in some implementations (e.g. PyPy), 'm' can be a regular unbound + # method object; the getattr() below obtains its underlying function. + self.assertEqual(getattr(m, 'im_func', m), t.__dict__[meth]) d['a'] = deepcopy(a) m(d['a'], b) self.assertEqual(d['a'], res) @@ -127,7 +134,9 @@ class OperatorsTest(unittest.TestCase): m = getattr(t, meth) while meth not in t.__dict__: t = t.__bases__[0] - self.assertEqual(m, t.__dict__[meth]) + # in some implementations (e.g. PyPy), 'm' can be a regular unbound + # method object; the getattr() below obtains its underlying function. + self.assertEqual(getattr(m, 'im_func', m), t.__dict__[meth]) d['a'] = deepcopy(a) m(d['a'], b, c) self.assertEqual(d['a'], res) @@ -144,7 +153,9 @@ class OperatorsTest(unittest.TestCase): while meth not in t.__dict__: t = t.__bases__[0] m = getattr(t, meth) - self.assertEqual(m, t.__dict__[meth]) + # in some implementations (e.g. PyPy), 'm' can be a regular unbound + # method object; the getattr() below obtains its underlying function. + self.assertEqual(getattr(m, 'im_func', m), t.__dict__[meth]) dictionary['a'] = deepcopy(a) m(dictionary['a'], slice(b, c), d) self.assertEqual(dictionary['a'], res) @@ -276,6 +287,7 @@ class OperatorsTest(unittest.TestCase): self.assertEqual(repr(a), "234.5") self.assertEqual(a.prec, 12) + @support.impl_detail("the module 'xxsubtype' is internal") def test_spam_lists(self): # Testing spamlist operations... import copy, xxsubtype as spam @@ -319,6 +331,7 @@ class OperatorsTest(unittest.TestCase): a.setstate(42) self.assertEqual(a.getstate(), 42) + @support.impl_detail("the module 'xxsubtype' is internal") def test_spam_dicts(self): # Testing spamdict operations... import copy, xxsubtype as spam @@ -778,8 +791,11 @@ order (MRO) for bases """ try: callable(*args) except exc as msg: - if not str(msg).startswith(expected): - self.fail("Message %r, expected %r" % (str(msg), expected)) + # the exact msg is generally considered an impl detail + if support.check_impl_detail(): + if not str(msg).startswith(expected): + self.fail("Message %r, expected %r" % + (str(msg), expected)) else: self.fail("Expected %s" % exc) @@ -967,6 +983,7 @@ order (MRO) for bases """ x.c = Counted() self.assertEqual(Counted.counter, 3) del x + support.gc_collect() self.assertEqual(Counted.counter, 0) class D(C): pass @@ -975,6 +992,7 @@ order (MRO) for bases """ x.z = Counted() self.assertEqual(Counted.counter, 2) del x + support.gc_collect() self.assertEqual(Counted.counter, 0) class E(D): __slots__ = ['e'] @@ -984,6 +1002,7 @@ order (MRO) for bases """ x.e = Counted() self.assertEqual(Counted.counter, 3) del x + support.gc_collect() self.assertEqual(Counted.counter, 0) # Test cyclical leaks [SF bug 519621] @@ -994,21 +1013,22 @@ order (MRO) for bases """ s.a = [Counted(), s] self.assertEqual(Counted.counter, 1) s = None - import gc - gc.collect() + support.gc_collect() self.assertEqual(Counted.counter, 0) # Test lookup leaks [SF bug 572567] import sys,gc - class G(object): - def __eq__(self, other): - return 1 - g = G() - orig_objects = len(gc.get_objects()) - for i in range(10): - g==g - new_objects = len(gc.get_objects()) - self.assertEqual(orig_objects, new_objects) + if hasattr(gc, 'get_objects'): + class G(object): + def __cmp__(self, other): + return 0 + g = G() + orig_objects = len(gc.get_objects()) + for i in range(10): + g==g + new_objects = len(gc.get_objects()) + self.assertEqual(orig_objects, new_objects) + class H(object): __slots__ = ['a', 'b'] def __init__(self): @@ -1262,6 +1282,7 @@ order (MRO) for bases """ else: self.fail("classmethod shouldn't accept keyword args") + @support.impl_detail("the module 'xxsubtype' is internal") def test_classmethods_in_c(self): # Testing C-based class methods... import xxsubtype as spam @@ -1293,6 +1314,7 @@ order (MRO) for bases """ self.assertEqual(d.foo(1), (d, 1)) self.assertEqual(D.foo(d, 1), (d, 1)) + @support.impl_detail("the module 'xxsubtype' is internal") def test_staticmethods_in_c(self): # Testing C-based static methods... import xxsubtype as spam @@ -1410,6 +1432,14 @@ order (MRO) for bases """ return [self, dict, object] class X(object, metaclass=_metaclass): pass + # In CPython, the class creation above already raises + # TypeError, as a protection against the fact that + # instances of X would segfault it. In other Python + # implementations it would be ok to let the class X + # be created, but instead get a clean TypeError on the + # __setitem__ below. + x = object.__new__(X) + x[5] = 6 except TypeError: pass else: @@ -1614,6 +1644,7 @@ order (MRO) for bases """ r = weakref.ref(c) self.assertEqual(r(), c) del c + support.gc_collect() self.assertEqual(r(), None) del r class NoWeak(object): @@ -1631,6 +1662,7 @@ order (MRO) for bases """ r = weakref.ref(yes) self.assertEqual(r(), yes) del yes + support.gc_collect() self.assertEqual(r(), None) del r @@ -1936,7 +1968,10 @@ order (MRO) for bases """ # Two essentially featureless objects, just inheriting stuff from # object. - self.assertEqual(dir(None), dir(Ellipsis)) + self.assertEqual(dir(NotImplemented), dir(Ellipsis)) + if support.check_impl_detail(): + # None differs in PyPy: it has a __nonzero__ + self.assertEqual(dir(None), dir(Ellipsis)) # Nasty test case for proxied objects class Wrapper(object): @@ -2652,7 +2687,7 @@ order (MRO) for bases """ self.fail("shouldn't allow %r.__class__ = %r" % (x, C)) try: delattr(x, "__class__") - except TypeError: + except (TypeError, AttributeError): pass else: self.fail("shouldn't allow del %r.__class__" % x) @@ -2780,6 +2815,16 @@ order (MRO) for bases """ mod.__dict__["spam"] = "eggs" # Exception's __dict__ can be replaced, but not deleted + # (at least not any more than regular exception's __dict__ can + # be deleted; on CPython it is not the case, whereas on PyPy they + # can, just like any other new-style instance's __dict__.) + def can_delete_dict(e): + try: + del e.__dict__ + except (TypeError, AttributeError): + return False + else: + return True class Exception1(Exception, Base): pass class Exception2(Base, Exception): @@ -2788,12 +2833,7 @@ order (MRO) for bases """ e = ExceptionType() e.__dict__ = {"a": 1} self.assertEqual(e.a, 1) - try: - del e.__dict__ - except (TypeError, AttributeError): - pass - else: - self.fail("%r's __dict__ can be deleted" % e) + self.assertEqual(can_delete_dict(e), can_delete_dict(ValueError())) def test_pickles(self): # Testing pickling and copying new-style classes and objects... @@ -3070,7 +3110,7 @@ order (MRO) for bases """ class B(A): pass del B - gc.collect() + support.gc_collect() A.__setitem__ = lambda *a: None # crash def test_buffer_inheritance(self): @@ -3154,6 +3194,7 @@ order (MRO) for bases """ c = C() self.assertEqual(log, []) del c + support.gc_collect() self.assertEqual(log, [1]) class D(object): pass @@ -3249,7 +3290,7 @@ order (MRO) for bases """ self.assertEqual(hasattr(m, "__name__"), 0) self.assertEqual(hasattr(m, "__file__"), 0) self.assertEqual(hasattr(m, "foo"), 0) - self.assertEqual(m.__dict__, None) + self.assertFalse(m.__dict__) # None or {} are both reasonable answers m.foo = 1 self.assertEqual(m.__dict__, {"foo": 1}) @@ -3384,17 +3425,23 @@ order (MRO) for bases """ c = C() c.attr = 42 - # The most interesting thing here is whether this blows up, due to flawed - # GC tracking logic in typeobject.c's call_finalizer() (a 2.2.1 bug). + # The most interesting thing here is whether this blows up, due to + # flawed GC tracking logic in typeobject.c's call_finalizer() (a 2.2.1 + # bug). del c # If that didn't blow up, it's also interesting to see whether clearing - # the last container slot works: that will attempt to delete c again, - # which will cause c to get appended back to the container again "during" - # the del. - del C.container[-1] + # the last container slot works: that will attempt to delete c again, + # which will cause c to get appended back to the container again + # "during" the del. (On non-CPython implementations, however, __del__ + # is typically not called again.) + support.gc_collect() self.assertEqual(len(C.container), 1) - self.assertEqual(C.container[-1].attr, 42) + del C.container[-1] + if support.check_impl_detail(): + support.gc_collect() + self.assertEqual(len(C.container), 1) + self.assertEqual(C.container[-1].attr, 42) # Make c mortal again, so that the test framework with -l doesn't report # it as a leak. @@ -3420,7 +3467,8 @@ order (MRO) for bases """ pass class C(A,B) : __slots__=() - self.assertEqual(C.__basicsize__, B.__basicsize__) + if support.check_impl_detail(): + self.assertEqual(C.__basicsize__, B.__basicsize__) self.assert_(hasattr(C, '__dict__')) self.assert_(hasattr(C, '__weakref__')) C().x = 2 @@ -3503,7 +3551,7 @@ order (MRO) for bases """ try: del D.__bases__ - except TypeError: + except (TypeError, AttributeError): pass else: self.fail("shouldn't be able to delete .__bases__") @@ -3681,6 +3729,7 @@ order (MRO) for bases """ self.assertEqual(E() // C(), "C.__floordiv__") self.assertEqual(C() // E(), "C.__floordiv__") # This one would fail + @support.impl_detail("testing an internal kind of method object") def test_meth_class_get(self): # Testing __get__ method of METH_CLASS C methods... # Full coverage of descrobject.c::classmethod_get() @@ -3866,7 +3915,7 @@ order (MRO) for bases """ self.assertEqual(c.attr, 1) # this makes a crash more likely: - import gc; gc.collect() + support.gc_collect() self.assertEqual(hasattr(c, 'attr'), False) def test_init(self): @@ -3893,8 +3942,14 @@ order (MRO) for bases """ self.assert_(l.__add__ != [5].__add__) self.assert_(l.__add__ != l.__mul__) self.assert_(l.__add__.__name__ == '__add__') - self.assert_(l.__add__.__self__ is l) - self.assert_(l.__add__.__objclass__ is list) + if hasattr(l.__add__, '__self__'): + # CPython + self.assert_(l.__add__.__self__ is l) + self.assert_(l.__add__.__objclass__ is list) + else: + # Python implementations where [].__add__ is a normal bound method + self.assert_(l.__add__.im_self is l) + self.assert_(l.__add__.im_class is list) self.assertEqual(l.__add__.__doc__, list.__add__.__doc__) try: hash(l.__add__) diff --git a/Lib/test/test_epoll.py b/Lib/test/test_epoll.py index b1ca3226698..b596052bb21 100644 --- a/Lib/test/test_epoll.py +++ b/Lib/test/test_epoll.py @@ -31,13 +31,13 @@ import unittest from test import support if not hasattr(select, "epoll"): - raise support.TestSkipped("test works only on Linux 2.6") + raise unittest.SkipTest("test works only on Linux 2.6") try: select.epoll() except IOError as e: if e.errno == errno.ENOSYS: - raise support.TestSkipped("kernel doesn't support epoll()") + raise unittest.SkipTest("kernel doesn't support epoll()") class TestEPoll(unittest.TestCase): diff --git a/Lib/test/test_fork1.py b/Lib/test/test_fork1.py index e6d9eed2370..057c58966db 100644 --- a/Lib/test/test_fork1.py +++ b/Lib/test/test_fork1.py @@ -4,12 +4,12 @@ import os import time from test.fork_wait import ForkWait -from test.support import TestSkipped, run_unittest, reap_children +from test.support import run_unittest, reap_children try: os.fork except AttributeError: - raise TestSkipped("os.fork not defined -- skipping test_fork1") + raise unittest.SkipTest("os.fork not defined -- skipping test_fork1") class ForkTest(ForkWait): def wait_impl(self, cpid): diff --git a/Lib/test/test_ioctl.py b/Lib/test/test_ioctl.py index 537579a594f..f6508c25d23 100644 --- a/Lib/test/test_ioctl.py +++ b/Lib/test/test_ioctl.py @@ -1,18 +1,18 @@ import unittest -from test.support import TestSkipped, run_unittest +from test.support import run_unittest import os, struct try: import fcntl, termios except ImportError: - raise TestSkipped("No fcntl or termios module") + raise unittest.SkipTest("No fcntl or termios module") if not hasattr(termios,'TIOCGPGRP'): - raise TestSkipped("termios module doesn't have TIOCGPGRP") + raise unittest.SkipTest("termios module doesn't have TIOCGPGRP") try: tty = open("/dev/tty", "r") tty.close() except IOError: - raise TestSkipped("Unable to open /dev/tty") + raise unittest.SkipTest("Unable to open /dev/tty") try: import pty @@ -41,7 +41,7 @@ class IoctlTests(unittest.TestCase): def test_ioctl_signed_unsigned_code_param(self): if not pty: - raise TestSkipped('pty module required') + raise unittest.SkipTest('pty module required') mfd, sfd = pty.openpty() try: if termios.TIOCSWINSZ < 0: diff --git a/Lib/test/test_kqueue.py b/Lib/test/test_kqueue.py index eb4865ac78b..42ef958060d 100644 --- a/Lib/test/test_kqueue.py +++ b/Lib/test/test_kqueue.py @@ -10,7 +10,7 @@ import unittest from test import support if not hasattr(select, "kqueue"): - raise support.TestSkipped("test works only on BSD") + raise unittest.SkipTest("test works only on BSD") class TestKQueue(unittest.TestCase): def test_create_queue(self): diff --git a/Lib/test/test_largefile.py b/Lib/test/test_largefile.py index d9326593a3f..1e868e059dc 100644 --- a/Lib/test/test_largefile.py +++ b/Lib/test/test_largefile.py @@ -6,7 +6,7 @@ import stat import sys import unittest from test.support import run_unittest, TESTFN, verbose, requires, \ - TestSkipped, unlink + unlink import io # C implementation of io import _pyio as pyio # Python implementation of io @@ -106,7 +106,7 @@ class LargeFileTest(unittest.TestCase): # this is already decided before start running the test suite # but we do it anyway for extra protection if not hasattr(f, 'truncate'): - raise TestSkipped("open().truncate() not available on this system") + raise unittest.SkipTest("open().truncate() not available on this system") f.seek(0, 2) # else we've lost track of the true size self.assertEqual(f.tell(), size+1) @@ -165,7 +165,7 @@ def test_main(): except (IOError, OverflowError): f.close() unlink(TESTFN) - raise TestSkipped("filesystem does not have largefile support") + raise unittest.SkipTest("filesystem does not have largefile support") else: f.close() suite = unittest.TestSuite() diff --git a/Lib/test/test_locale.py b/Lib/test/test_locale.py index 7fc637278d0..c77dc5522a4 100644 --- a/Lib/test/test_locale.py +++ b/Lib/test/test_locale.py @@ -1,4 +1,4 @@ -from test.support import run_unittest, TestSkipped, verbose +from test.support import run_unittest, verbose import unittest import locale import sys @@ -9,7 +9,7 @@ enUS_locale = None def get_enUS_locale(): global enUS_locale if sys.platform == 'darwin': - raise TestSkipped("Locale support on MacOSX is minimal") + raise unittest.SkipTest("Locale support on MacOSX is minimal") if sys.platform.startswith("win"): tlocs = ("En", "English") else: @@ -22,7 +22,7 @@ def get_enUS_locale(): continue break else: - raise TestSkipped( + raise unittest.SkipTest( "Test locale not supported (tried %s)" % (', '.join(tlocs))) enUS_locale = tloc locale.setlocale(locale.LC_NUMERIC, oldlocale) @@ -318,10 +318,10 @@ def test_main(): TestCNumberFormatting, TestFrFRNumberFormatting, ] - # TestSkipped can't be raised inside unittests, handle it manually instead + # SkipTest can't be raised inside unittests, handle it manually instead try: get_enUS_locale() - except TestSkipped as e: + except unittest.SkipTest as e: if verbose: print("Some tests will be disabled: %s" % e) else: diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py index c4c568f8b6e..59dca5069b6 100644 --- a/Lib/test/test_minidom.py +++ b/Lib/test/test_minidom.py @@ -3,7 +3,7 @@ import os import sys import pickle -from test.support import verbose, run_unittest, TestSkipped +from test.support import verbose, run_unittest import unittest import xml.dom diff --git a/Lib/test/test_multiprocessing.py b/Lib/test/test_multiprocessing.py index 3681c60d50d..0f91c97c606 100644 --- a/Lib/test/test_multiprocessing.py +++ b/Lib/test/test_multiprocessing.py @@ -23,8 +23,7 @@ import logging try: import multiprocessing.synchronize except ImportError as e: - from test.test_support import TestSkipped - raise TestSkipped(e) + raise unittest.SkipTest(e) import multiprocessing.dummy import multiprocessing.connection @@ -1814,7 +1813,7 @@ def test_main(run=None): lock = multiprocessing.RLock() except OSError: from test.support import TestSkipped - raise TestSkipped("OSError raises on RLock creation, see issue 3111!") + raise unittest.SkipTest("OSError raises on RLock creation, see issue 3111!") if run is None: from test.support import run_unittest as run diff --git a/Lib/test/test_nis.py b/Lib/test/test_nis.py index 1c17a4ee3b9..b4af95e3d88 100644 --- a/Lib/test/test_nis.py +++ b/Lib/test/test_nis.py @@ -2,7 +2,7 @@ from test import support import unittest import nis -raise support.TestSkipped("test_nis hangs on Solaris") +raise unittest.SkipTest("test_nis hangs on Solaris") class NisTests(unittest.TestCase): def test_maps(self): @@ -12,7 +12,7 @@ class NisTests(unittest.TestCase): # NIS is probably not active, so this test isn't useful if support.verbose: print("Test Skipped:", msg) - # Can't raise TestSkipped as regrtest only recognizes the exception + # Can't raise SkipTest as regrtest only recognizes the exception # import time. return try: diff --git a/Lib/test/test_openpty.py b/Lib/test/test_openpty.py index 9272c854950..e8175ff094d 100644 --- a/Lib/test/test_openpty.py +++ b/Lib/test/test_openpty.py @@ -1,10 +1,10 @@ # Test to see if openpty works. (But don't worry if it isn't available.) import os, unittest -from test.support import run_unittest, TestSkipped +from test.support import run_unittest if not hasattr(os, "openpty"): - raise TestSkipped("No openpty() available.") + raise unittest.SkipTest("No openpty() available.") class OpenptyTest(unittest.TestCase): diff --git a/Lib/test/test_ossaudiodev.py b/Lib/test/test_ossaudiodev.py index 0e9ba45dfac..e49cf2acb91 100644 --- a/Lib/test/test_ossaudiodev.py +++ b/Lib/test/test_ossaudiodev.py @@ -1,7 +1,7 @@ from test import support support.requires('audio') -from test.support import findfile, TestSkipped +from test.support import findfile import errno import ossaudiodev @@ -46,7 +46,7 @@ class OSSAudioDevTests(unittest.TestCase): except IOError as msg: if msg.args[0] in (errno.EACCES, errno.ENOENT, errno.ENODEV, errno.EBUSY): - raise TestSkipped(msg) + raise unittest.SkipTest(msg) raise # at least check that these methods can be invoked @@ -165,7 +165,7 @@ def test_main(): except (ossaudiodev.error, IOError) as msg: if msg.args[0] in (errno.EACCES, errno.ENOENT, errno.ENODEV, errno.EBUSY): - raise TestSkipped(msg) + raise unittest.SkipTest(msg) raise dsp.close() support.run_unittest(__name__) diff --git a/Lib/test/test_pep277.py b/Lib/test/test_pep277.py index eac51384949..e18f6024699 100644 --- a/Lib/test/test_pep277.py +++ b/Lib/test/test_pep277.py @@ -3,7 +3,7 @@ import sys, os, unittest from test import support if not os.path.supports_unicode_filenames: - raise support.TestSkipped("test works only on NT+") + raise unittest.SkipTest("test works only on NT+") filenames = [ 'abc', diff --git a/Lib/test/test_pipes.py b/Lib/test/test_pipes.py index d55f3524f67..da6af5c96b6 100644 --- a/Lib/test/test_pipes.py +++ b/Lib/test/test_pipes.py @@ -2,10 +2,10 @@ import pipes import os import string import unittest -from test.support import TESTFN, run_unittest, unlink, TestSkipped +from test.support import TESTFN, run_unittest, unlink if os.name != 'posix': - raise TestSkipped('pipes module only works on posix') + raise unittest.SkipTest('pipes module only works on posix') TESTFN2 = TESTFN + "2" diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py index a032df1bde8..9bb5bddfc6f 100644 --- a/Lib/test/test_platform.py +++ b/Lib/test/test_platform.py @@ -48,25 +48,73 @@ class PlatformTest(unittest.TestCase): def test_processor(self): res = platform.processor() - def test_python_implementation(self): - res = platform.python_implementation() + def setUp(self): + self.save_version = sys.version + self.save_subversion = sys.subversion + self.save_platform = sys.platform - def test_python_version(self): - res1 = platform.python_version() - res2 = platform.python_version_tuple() - self.assertEqual(res1, ".".join(res2)) + def tearDown(self): + sys.version = self.save_version + sys.subversion = self.save_subversion + sys.platform = self.save_platform - def test_python_branch(self): - res = platform.python_branch() + def test_sys_version(self): + # Old test. + for input, output in ( + ('2.4.3 (#1, Jun 21 2006, 13:54:21) \n[GCC 3.3.4 (pre 3.3.5 20040809)]', + ('CPython', '2.4.3', '', '', '1', 'Jun 21 2006 13:54:21', 'GCC 3.3.4 (pre 3.3.5 20040809)')), + ('IronPython 1.0.60816 on .NET 2.0.50727.42', + ('IronPython', '1.0.60816', '', '', '', '', '.NET 2.0.50727.42')), + ('IronPython 1.0 (1.0.61005.1977) on .NET 2.0.50727.42', + ('IronPython', '1.0.0', '', '', '', '', '.NET 2.0.50727.42')), + ): + # branch and revision are not "parsed", but fetched + # from sys.subversion. Ignore them + (name, version, branch, revision, buildno, builddate, compiler) \ + = platform._sys_version(input) + self.assertEqual( + (name, version, '', '', buildno, builddate, compiler), output) - def test_python_revision(self): - res = platform.python_revision() - - def test_python_build(self): - res = platform.python_build() - - def test_python_compiler(self): - res = platform.python_compiler() + # Tests for python_implementation(), python_version(), python_branch(), + # python_revision(), python_build(), and python_compiler(). + sys_versions = { + ("2.6.1 (r261:67515, Dec 6 2008, 15:26:00) \n[GCC 4.0.1 (Apple Computer, Inc. build 5370)]", + ('CPython', 'tags/r261', '67515'), self.save_platform) + : + ("CPython", "2.6.1", "tags/r261", "67515", + ('r261:67515', 'Dec 6 2008 15:26:00'), + 'GCC 4.0.1 (Apple Computer, Inc. build 5370)'), + ("IronPython 2.0 (2.0.0.0) on .NET 2.0.50727.3053", None, "cli") + : + ("IronPython", "2.0.0", "", "", ("", ""), + ".NET 2.0.50727.3053"), + ("2.5 (trunk:6107, Mar 26 2009, 13:02:18) \n[Java HotSpot(TM) Client VM (\"Apple Computer, Inc.\")]", + ('Jython', 'trunk', '6107'), "java1.5.0_16") + : + ("Jython", "2.5.0", "trunk", "6107", + ('trunk:6107', 'Mar 26 2009'), "java1.5.0_16"), + ("2.5.2 (63378, Mar 26 2009, 18:03:29)\n[PyPy 1.0.0]", + ('PyPy', 'trunk', '63378'), self.save_platform) + : + ("PyPy", "2.5.2", "trunk", "63378", ('63378', 'Mar 26 2009'), + "") + } + for (version_tag, subversion, sys_platform), info in \ + sys_versions.items(): + sys.version = version_tag + if subversion is None: + if hasattr(sys, "subversion"): + del sys.subversion + else: + sys.subversion = subversion + if sys_platform is not None: + sys.platform = sys_platform + self.assertEqual(platform.python_implementation(), info[0]) + self.assertEqual(platform.python_version(), info[1]) + self.assertEqual(platform.python_branch(), info[2]) + self.assertEqual(platform.python_revision(), info[3]) + self.assertEqual(platform.python_build(), info[4]) + self.assertEqual(platform.python_compiler(), info[5]) def test_system_alias(self): res = platform.system_alias( @@ -140,23 +188,6 @@ class PlatformTest(unittest.TestCase): ): self.assertEqual(platform._parse_release_file(input), output) - def test_sys_version(self): - - platform._sys_version_cache.clear() - for input, output in ( - ('2.4.3 (#1, Jun 21 2006, 13:54:21) \n[GCC 3.3.4 (pre 3.3.5 20040809)]', - ('CPython', '2.4.3', '', '', '1', 'Jun 21 2006 13:54:21', 'GCC 3.3.4 (pre 3.3.5 20040809)')), - ('IronPython 1.0.60816 on .NET 2.0.50727.42', - ('IronPython', '1.0.60816', '', '', '', '', '.NET 2.0.50727.42')), - ('IronPython 1.0 (1.0.61005.1977) on .NET 2.0.50727.42', - ('IronPython', '1.0.0', '', '', '', '', '.NET 2.0.50727.42')), - ): - # branch and revision are not "parsed", but fetched - # from sys.subversion. Ignore them - (name, version, branch, revision, buildno, builddate, compiler) \ - = platform._sys_version(input) - self.assertEqual( - (name, version, '', '', buildno, builddate, compiler), output) def test_main(): support.run_unittest( diff --git a/Lib/test/test_poll.py b/Lib/test/test_poll.py index c346ba005f2..7ab3b84a97d 100644 --- a/Lib/test/test_poll.py +++ b/Lib/test/test_poll.py @@ -1,12 +1,12 @@ # Test case for the os.poll() function import os, select, random, unittest -from test.support import TestSkipped, TESTFN, run_unittest +from test.support import TESTFN, run_unittest try: select.poll except AttributeError: - raise TestSkipped("select.poll not defined -- skipping test_poll") + raise unittest.SkipTest("select.poll not defined -- skipping test_poll") def find_ready_matching(ready, flag): diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 45decb7a085..2a0a876846f 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -5,7 +5,7 @@ from test import support try: import posix except ImportError: - raise support.TestSkipped("posix is not available") + raise unittest.SkipTest("posix is not available") import time import os @@ -225,17 +225,17 @@ class PosixTester(unittest.TestCase): os.mkdir(base_path) os.chdir(base_path) except: -# Just returning nothing instead of the TestSkipped exception, +# Just returning nothing instead of the SkipTest exception, # because the test results in Error in that case. # Is that ok? -# raise support.TestSkipped, "cannot create directory for testing" +# raise unittest.SkipTest("cannot create directory for testing") return def _create_and_do_getcwd(dirname, current_path_length = 0): try: os.mkdir(dirname) except: - raise support.TestSkipped("mkdir cannot create directory sufficiently deep for getcwd test") + raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test") os.chdir(dirname) try: diff --git a/Lib/test/test_pty.py b/Lib/test/test_pty.py index ec52f9ffbc6..3be7c97b6e6 100644 --- a/Lib/test/test_pty.py +++ b/Lib/test/test_pty.py @@ -4,7 +4,7 @@ import pty import os import sys import signal -from test.support import verbose, TestSkipped, run_unittest +from test.support import verbose, run_unittest import unittest TEST_STRING_1 = b"I wish to buy a fish license.\n" @@ -69,7 +69,7 @@ class PtyTest(unittest.TestCase): debug("Got slave_fd '%d'" % slave_fd) except OSError: # " An optional feature could not be imported " ... ? - raise TestSkipped("Pseudo-terminals (seemingly) not functional.") + raise unittest.SkipTest("Pseudo-terminals (seemingly) not functional.") self.assertTrue(os.isatty(slave_fd), 'slave_fd is not a tty') diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py index b8ac2ccc11c..570526cfec7 100644 --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -10,7 +10,7 @@ import traceback import sys, os, time, errno if sys.platform[:3] in ('win', 'os2') or sys.platform == 'riscos': - raise support.TestSkipped("Can't test signal on %s" % \ + raise unittest.SkipTest("Can't test signal on %s" % \ sys.platform) diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py index 8a61e211289..1bf143a06dd 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -5,7 +5,7 @@ executing have not been removed. """ import unittest -from test.support import TestSkipped, run_unittest, TESTFN +from test.support import run_unittest, TESTFN import builtins import os import sys @@ -17,7 +17,7 @@ import subprocess if "site" in sys.modules: import site else: - raise TestSkipped("importation of site.py suppressed") + raise unittest.SkipTest("importation of site.py suppressed") if not os.path.isdir(site.USER_SITE): # need to add user site directory for tests diff --git a/Lib/test/test_socketserver.py b/Lib/test/test_socketserver.py index 4ffea57e996..43ce55c37ab 100644 --- a/Lib/test/test_socketserver.py +++ b/Lib/test/test_socketserver.py @@ -16,7 +16,7 @@ import unittest import socketserver import test.support -from test.support import reap_children, verbose, TestSkipped +from test.support import reap_children, verbose from test.support import TESTFN as TEST_FILE test.support.requires("network") @@ -247,7 +247,7 @@ class SocketServerTest(unittest.TestCase): def test_main(): if imp.lock_held(): # If the import lock is held, the threads will hang - raise TestSkipped("can't run when import lock is held") + raise unittest.SkipTest("can't run when import lock is held") test.support.run_unittest(SocketServerTest) diff --git a/Lib/test/test_sqlite.py b/Lib/test/test_sqlite.py index b8a9acff785..611b30a99a5 100644 --- a/Lib/test/test_sqlite.py +++ b/Lib/test/test_sqlite.py @@ -1,9 +1,10 @@ -from test.support import run_unittest, TestSkipped +import unittest +from test.support import run_unittest try: import _sqlite3 except ImportError: - raise TestSkipped('no sqlite available') + raise unittest.SkipTest('no sqlite available') from sqlite3.test import (dbapi, types, userfunctions, factory, transactions, hooks, regression, dump) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 9d59a26cc4a..0be5652f88c 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -1161,7 +1161,7 @@ else: def test_main(verbose=False): if skip_expected: - raise support.TestSkipped("No SSL support") + raise unittest.SkipTest("No SSL support") global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py index 0ef0925ee0e..27a2183b4bd 100644 --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -259,7 +259,7 @@ class test__mkstemp_inner(TC): def test_file_mode(self): # _mkstemp_inner creates files with the proper mode if not has_stat: - return # ugh, can't use TestSkipped. + return # ugh, can't use SkipTest. file = self.do_create() mode = stat.S_IMODE(os.stat(file.name).st_mode) @@ -274,7 +274,7 @@ class test__mkstemp_inner(TC): def test_noinherit(self): # _mkstemp_inner file handles are not inherited by child processes if not has_spawnl: - return # ugh, can't use TestSkipped. + return # ugh, can't use SkipTest. if support.verbose: v="v" @@ -312,7 +312,7 @@ class test__mkstemp_inner(TC): def test_textmode(self): # _mkstemp_inner can create files in text mode if not has_textmode: - return # ugh, can't use TestSkipped. + return # ugh, can't use SkipTest. self.do_create(bin=0).write(b"blat\n") # XXX should test that the file really is a text file @@ -476,7 +476,7 @@ class test_mkdtemp(TC): def test_mode(self): # mkdtemp creates directories with the proper mode if not has_stat: - return # ugh, can't use TestSkipped. + return # ugh, can't use SkipTest. dir = self.do_create() try: diff --git a/Lib/test/test_threaded_import.py b/Lib/test/test_threaded_import.py index 67d1505b965..af9e89dd3a8 100644 --- a/Lib/test/test_threaded_import.py +++ b/Lib/test/test_threaded_import.py @@ -6,7 +6,7 @@ # randrange, and then Python hangs. import _thread as thread -from test.support import verbose, TestSkipped, TestFailed +from test.support import verbose, TestFailed critical_section = thread.allocate_lock() done = thread.allocate_lock() @@ -56,7 +56,7 @@ def test_main(): # magic name! see above import imp if imp.lock_held(): # This triggers on, e.g., from test import autotest. - raise TestSkipped("can't run when import lock is held") + raise unittest.SkipTest("can't run when import lock is held") done.acquire() for N in (20, 50) * 3: diff --git a/Lib/test/test_threadsignals.py b/Lib/test/test_threadsignals.py index 14bd3b7f409..7959e917eb3 100644 --- a/Lib/test/test_threadsignals.py +++ b/Lib/test/test_threadsignals.py @@ -5,10 +5,10 @@ import _thread as thread import signal import os import sys -from test.support import run_unittest, TestSkipped +from test.support import run_unittest -if sys.platform[:3] in ('win', 'os2'): - raise TestSkipped("Can't test signal on %s" % sys.platform) +if sys.platform[:3] in ('win', 'os2') or sys.platform=='riscos': + raise unittest.SkipTest("Can't test signal on %s" % sys.platform) process_pid = os.getpid() signalled_all=thread.allocate_lock() diff --git a/Lib/test/test_tk.py b/Lib/test/test_tk.py index 8b21a0fc273..20b3fb59e32 100644 --- a/Lib/test/test_tk.py +++ b/Lib/test/test_tk.py @@ -1,12 +1,13 @@ import tkinter from tkinter.test import runtktests from test import support +import unittest try: tkinter.Button() except tkinter.TclError as msg: # assuming tk is not available - raise support.TestSkipped("tk not available: %s" % msg) + raise unittest.SkipTest("tk not available: %s" % msg) def test_main(enable_gui=False): if enable_gui: diff --git a/Lib/test/test_ttk_guionly.py b/Lib/test/test_ttk_guionly.py index bff490af10d..4a9a30cecab 100644 --- a/Lib/test/test_ttk_guionly.py +++ b/Lib/test/test_ttk_guionly.py @@ -2,6 +2,7 @@ import os import sys from tkinter import ttk from tkinter.test import runtktests +import unittest from _tkinter import TclError from test import support @@ -9,7 +10,7 @@ try: ttk.Button() except TclError as msg: # assuming ttk is not available - raise support.TestSkipped("ttk not available: %s" % msg) + raise unittest.SkipTest("ttk not available: %s" % msg) def test_main(enable_gui=False): if enable_gui: diff --git a/Lib/test/test_unicode_file.py b/Lib/test/test_unicode_file.py index b9d9624a85d..fd561f1cc09 100644 --- a/Lib/test/test_unicode_file.py +++ b/Lib/test/test_unicode_file.py @@ -5,14 +5,14 @@ import os, glob, time, shutil import unicodedata import unittest -from test.support import run_unittest, TestSkipped, TESTFN_UNICODE, rmtree +from test.support import run_unittest, TESTFN_UNICODE, rmtree from test.support import TESTFN_ENCODING, TESTFN_UNICODE_UNENCODEABLE try: TESTFN_UNICODE.encode(TESTFN_ENCODING) except (UnicodeError, TypeError): # Either the file system encoding is None, or the file name # cannot be encoded in the file system encoding. - raise TestSkipped("No Unicode filesystem semantics on this platform") + raise unittest.SkipTest("No Unicode filesystem semantics on this platform.") def remove_if_exists(filename): if os.path.exists(filename): diff --git a/Lib/test/test_unittest.py b/Lib/test/test_unittest.py index 9b8b00bcb72..b7272f150cc 100644 --- a/Lib/test/test_unittest.py +++ b/Lib/test/test_unittest.py @@ -2304,7 +2304,7 @@ class Test_TestSkipping(TestCase): def test_skipping(self): class Foo(unittest.TestCase): def test_skip_me(self): - self.skip("skip") + self.skipTest("skip") events = [] result = LoggingResult(events) test = Foo("test_skip_me") @@ -2315,7 +2315,7 @@ class Test_TestSkipping(TestCase): # Try letting setUp skip the test now. class Foo(unittest.TestCase): def setUp(self): - self.skip("testing") + self.skipTest("testing") def test_nothing(self): pass events = [] result = LoggingResult(events) diff --git a/Lib/test/test_univnewlines.py b/Lib/test/test_univnewlines.py index a6b99091ff6..39f55198b25 100644 --- a/Lib/test/test_univnewlines.py +++ b/Lib/test/test_univnewlines.py @@ -7,8 +7,8 @@ import sys from test import support if not hasattr(sys.stdin, 'newlines'): - raise support.TestSkipped( - "This Python does not have universal newline support") + raise unittest.SkipTest( + "This Python does not have universal newline support") FATX = 'x' * (2**14) diff --git a/Lib/test/test_wait3.py b/Lib/test/test_wait3.py index 4cca441853a..786e60b3272 100644 --- a/Lib/test/test_wait3.py +++ b/Lib/test/test_wait3.py @@ -3,18 +3,19 @@ import os import time +import unittest from test.fork_wait import ForkWait -from test.support import TestSkipped, run_unittest, reap_children +from test.support import run_unittest, reap_children try: os.fork except AttributeError: - raise TestSkipped("os.fork not defined -- skipping test_wait3") + raise unittest.SkipTest("os.fork not defined -- skipping test_wait3") try: os.wait3 except AttributeError: - raise TestSkipped("os.wait3 not defined -- skipping test_wait3") + raise unittest.SkipTest("os.wait3 not defined -- skipping test_wait3") class Wait3Test(ForkWait): def wait_impl(self, cpid): diff --git a/Lib/test/test_wait4.py b/Lib/test/test_wait4.py index 192fd940415..8c6e4a317fa 100644 --- a/Lib/test/test_wait4.py +++ b/Lib/test/test_wait4.py @@ -4,17 +4,17 @@ import os import time from test.fork_wait import ForkWait -from test.support import TestSkipped, run_unittest, reap_children +from test.support import run_unittest, reap_children try: os.fork except AttributeError: - raise TestSkipped("os.fork not defined -- skipping test_wait4") + raise unittest.SkipTest("os.fork not defined -- skipping test_wait4") try: os.wait4 except AttributeError: - raise TestSkipped("os.wait4 not defined -- skipping test_wait4") + raise unittest.SkipTest("os.wait4 not defined -- skipping test_wait4") class Wait4Test(ForkWait): def wait_impl(self, cpid): diff --git a/Lib/traceback.py b/Lib/traceback.py index b028db07173..cb913eebae7 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -274,6 +274,8 @@ def format_exc(limit=None, chain=True): def print_last(limit=None, file=None, chain=True): """This is a shorthand for 'print_exception(sys.last_type, sys.last_value, sys.last_traceback, limit, file)'.""" + if not hasattr(sys, "last_type"): + raise ValueError("no last exception") if file is None: file = sys.stderr print_exception(sys.last_type, sys.last_value, sys.last_traceback, diff --git a/Lib/unittest.py b/Lib/unittest.py index 13cbfd349c0..ade806c97ee 100644 --- a/Lib/unittest.py +++ b/Lib/unittest.py @@ -373,14 +373,14 @@ class TestCase(object): result.addSkip(self, str(e)) return except Exception: - result.addError(self, self._exc_info()) + result.addError(self, sys.exc_info()) return success = False try: testMethod() except self.failureException: - result.addFailure(self, self._exc_info()) + result.addFailure(self, sys.exc_info()) except _ExpectedFailure as e: result.addExpectedFailure(self, e.exc_info) except _UnexpectedSuccess: @@ -388,14 +388,14 @@ class TestCase(object): except SkipTest as e: result.addSkip(self, str(e)) except Exception: - result.addError(self, self._exc_info()) + result.addError(self, sys.exc_info()) else: success = True try: self.tearDown() except Exception: - result.addError(self, self._exc_info()) + result.addError(self, sys.exc_info()) success = False if success: result.addSuccess(self) @@ -411,14 +411,7 @@ class TestCase(object): getattr(self, self._testMethodName)() self.tearDown() - def _exc_info(self): - """Return a version of sys.exc_info() with the traceback frame - minimised; usually the top level of the traceback frame is not - needed. - """ - return sys.exc_info() - - def skip(self, reason): + def skipTest(self, reason): """Skip this test.""" raise SkipTest(reason) @@ -830,7 +823,8 @@ class _WritelnDecorator(object): return getattr(self.stream,attr) def writeln(self, arg=None): - if arg: self.write(arg) + if arg: + self.write(arg) self.write('\n') # text-mode streams translate to \r\n if needed @@ -899,7 +893,7 @@ class _TextTestResult(TestResult): if self.showAll: self.stream.writeln("expected failure") elif self.dots: - self.stream.write(".") + self.stream.write("x") self.stream.flush() def addUnexpectedSuccess(self, test): @@ -907,7 +901,7 @@ class _TextTestResult(TestResult): if self.showAll: self.stream.writeln("unexpected success") elif self.dots: - self.stream.write(".") + self.stream.write("u") self.stream.flush() def printErrors(self): @@ -964,7 +958,7 @@ class TextTestRunner(object): if errored: infos.append("errors=%d" % errored) else: - self.stream.writeln("OK") + self.stream.write("OK") if skipped: infos.append("skipped=%d" % skipped) if expectedFails: @@ -973,6 +967,8 @@ class TextTestRunner(object): infos.append("unexpected successes=%d" % unexpectedSuccesses) if infos: self.stream.writeln(" (%s)" % (", ".join(infos),)) + else: + self.stream.write("\n") return result