diff options
author | Benjamin Peterson <benjamin@python.org> | 2012-09-29 18:14:19 (GMT) |
---|---|---|
committer | Benjamin Peterson <benjamin@python.org> | 2012-09-29 18:14:19 (GMT) |
commit | 14fb44e1bab9db128770f1d91d244916a669e7c3 (patch) | |
tree | 278d9ccc8f819b05f8114c3154087c70b88ed69c /Lib/test | |
parent | 1764c80925795b6f059e961c5a352c5ece5a7fff (diff) | |
parent | 99a247fd01c1cd780c0c3ee1116657627f1ee744 (diff) | |
download | cpython-14fb44e1bab9db128770f1d91d244916a669e7c3.zip cpython-14fb44e1bab9db128770f1d91d244916a669e7c3.tar.gz cpython-14fb44e1bab9db128770f1d91d244916a669e7c3.tar.bz2 |
merge mostly from default
Diffstat (limited to 'Lib/test')
34 files changed, 740 insertions, 82 deletions
diff --git a/Lib/test/sample_doctest_no_docstrings.py b/Lib/test/sample_doctest_no_docstrings.py new file mode 100644 index 0000000..e4201ed --- /dev/null +++ b/Lib/test/sample_doctest_no_docstrings.py @@ -0,0 +1,12 @@ +# This is a sample module used for testing doctest. +# +# This module is for testing how doctest handles a module with no +# docstrings. + + +class Foo(object): + + # A class with no docstring. + + def __init__(self): + pass diff --git a/Lib/test/sample_doctest_no_doctests.py b/Lib/test/sample_doctest_no_doctests.py new file mode 100644 index 0000000..7daa572 --- /dev/null +++ b/Lib/test/sample_doctest_no_doctests.py @@ -0,0 +1,15 @@ +"""This is a sample module used for testing doctest. + +This module is for testing how doctest handles a module with docstrings +but no doctest examples. + +""" + + +class Foo(object): + """A docstring with no doctest examples. + + """ + + def __init__(self): + pass diff --git a/Lib/test/string_tests.py b/Lib/test/string_tests.py index 8da3e77..e4688d0 100644 --- a/Lib/test/string_tests.py +++ b/Lib/test/string_tests.py @@ -1206,6 +1206,9 @@ class MixinStrUnicodeUserStringTest: self.checkraises(ValueError, '%%%df' % (2**64), '__mod__', (3.2)) self.checkraises(ValueError, '%%.%df' % (2**64), '__mod__', (3.2)) + class X(object): pass + self.checkraises(TypeError, 'abc', '__mod__', X()) + def test_floatformatting(self): # float formatting for prec in range(100): diff --git a/Lib/test/support.py b/Lib/test/support.py index 35ae76f..014bcf5 100644 --- a/Lib/test/support.py +++ b/Lib/test/support.py @@ -680,7 +680,7 @@ def temp_cwd(name='tempcwd', quiet=False, path=None): except OSError: if not quiet: raise - warnings.warn('tests may fail, unable to change the CWD to ' + name, + warnings.warn('tests may fail, unable to change the CWD to ' + path, RuntimeWarning, stacklevel=3) try: yield os.getcwd() diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 2e6584f..c06c940 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -1463,6 +1463,22 @@ class TestFileTypeR(TempDirMixin, ParserTestCase): ('readonly', NS(x=None, spam=RFile('readonly'))), ] +class TestFileTypeDefaults(TempDirMixin, ParserTestCase): + """Test that a file is not created unless the default is needed""" + def setUp(self): + super(TestFileTypeDefaults, self).setUp() + file = open(os.path.join(self.temp_dir, 'good'), 'w') + file.write('good') + file.close() + + argument_signatures = [ + Sig('-c', type=argparse.FileType('r'), default='no-file.txt'), + ] + # should provoke no such file error + failures = [''] + # should not provoke error because default file is created + successes = [('-c good', NS(c=RFile('good')))] + class TestFileTypeRB(TempDirMixin, ParserTestCase): """Test the FileType option/argument type for reading files""" @@ -4559,6 +4575,71 @@ class TestMessageContentError(TestCase): self.assertNotIn(msg, 'optional_positional') +# ================================================ +# Check that the type function is called only once +# ================================================ + +class TestTypeFunctionCallOnlyOnce(TestCase): + + def test_type_function_call_only_once(self): + def spam(string_to_convert): + self.assertEqual(string_to_convert, 'spam!') + return 'foo_converted' + + parser = argparse.ArgumentParser() + parser.add_argument('--foo', type=spam, default='bar') + args = parser.parse_args('--foo spam!'.split()) + self.assertEqual(NS(foo='foo_converted'), args) + +# ================================================================== +# Check semantics regarding the default argument and type conversion +# ================================================================== + +class TestTypeFunctionCalledOnDefault(TestCase): + + def test_type_function_call_with_non_string_default(self): + def spam(int_to_convert): + self.assertEqual(int_to_convert, 0) + return 'foo_converted' + + parser = argparse.ArgumentParser() + parser.add_argument('--foo', type=spam, default=0) + args = parser.parse_args([]) + # foo should *not* be converted because its default is not a string. + self.assertEqual(NS(foo=0), args) + + def test_type_function_call_with_string_default(self): + def spam(int_to_convert): + return 'foo_converted' + + parser = argparse.ArgumentParser() + parser.add_argument('--foo', type=spam, default='0') + args = parser.parse_args([]) + # foo is converted because its default is a string. + self.assertEqual(NS(foo='foo_converted'), args) + + def test_no_double_type_conversion_of_default(self): + def extend(str_to_convert): + return str_to_convert + '*' + + parser = argparse.ArgumentParser() + parser.add_argument('--test', type=extend, default='*') + args = parser.parse_args([]) + # The test argument will be two stars, one coming from the default + # value and one coming from the type conversion being called exactly + # once. + self.assertEqual(NS(test='**'), args) + + def test_issue_15906(self): + # Issue #15906: When action='append', type=str, default=[] are + # providing, the dest value was the string representation "[]" when it + # should have been an empty list. + parser = argparse.ArgumentParser() + parser.add_argument('--test', dest='test', type=str, + default=[], action='append') + args = parser.parse_args([]) + self.assertEqual(args.test, []) + # ====================== # parse_known_args tests # ====================== diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index aa08166..a8853c7 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -407,6 +407,14 @@ class ASTHelpers_Test(unittest.TestCase): b = compile('foo(1 + 1)', '<unknown>', 'exec', ast.PyCF_ONLY_AST) self.assertEqual(ast.dump(a), ast.dump(b)) + def test_parse_in_error(self): + try: + 1/0 + except Exception: + with self.assertRaises(SyntaxError) as e: + ast.literal_eval(r"'\U'") + self.assertIsNotNone(e.exception.__context__) + def test_dump(self): node = ast.parse('spam(eggs, "and cheese")') self.assertEqual(ast.dump(node), diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index e0f6399..e594e01 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -6,6 +6,7 @@ from test.script_helper import assert_python_ok import time import locale import sys +import datetime result_2004_01_text = """ January 2004 @@ -464,6 +465,11 @@ class CalendarTestCase(unittest.TestCase): new_october = calendar.TextCalendar().formatmonthname(2010, 10, 10) self.assertEqual(old_october, new_october) + def test_itermonthdates(self): + # ensure itermonthdates doesn't overflow after datetime.MAXYEAR + # see #15421 + list(calendar.Calendar().itermonthdates(datetime.MAXYEAR, 12)) + class MonthCalendarTestCase(unittest.TestCase): def setUp(self): diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index 59179c4..4e808ec 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -1693,6 +1693,15 @@ class CharmapTest(unittest.TestCase): ) self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "strict", "\U0010FFFFbc"), + ("\U0010FFFFbc", 3) + ) + + self.assertRaises(UnicodeDecodeError, + codecs.charmap_decode, b"\x00\x01\x02", "strict", "ab" + ) + + self.assertEqual( codecs.charmap_decode(b"\x00\x01\x02", "replace", "ab"), ("ab\ufffd", 3) ) @@ -1718,6 +1727,113 @@ class CharmapTest(unittest.TestCase): ("", len(allbytes)) ) + def test_decode_with_int2str_map(self): + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "strict", + {0: 'a', 1: 'b', 2: 'c'}), + ("abc", 3) + ) + + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "strict", + {0: 'Aa', 1: 'Bb', 2: 'Cc'}), + ("AaBbCc", 3) + ) + + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "strict", + {0: '\U0010FFFF', 1: 'b', 2: 'c'}), + ("\U0010FFFFbc", 3) + ) + + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "strict", + {0: 'a', 1: 'b', 2: ''}), + ("ab", 3) + ) + + self.assertRaises(UnicodeDecodeError, + codecs.charmap_decode, b"\x00\x01\x02", "strict", + {0: 'a', 1: 'b'} + ) + + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "replace", + {0: 'a', 1: 'b'}), + ("ab\ufffd", 3) + ) + + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "replace", + {0: 'a', 1: 'b', 2: None}), + ("ab\ufffd", 3) + ) + + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "ignore", + {0: 'a', 1: 'b'}), + ("ab", 3) + ) + + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "ignore", + {0: 'a', 1: 'b', 2: None}), + ("ab", 3) + ) + + allbytes = bytes(range(256)) + self.assertEqual( + codecs.charmap_decode(allbytes, "ignore", {}), + ("", len(allbytes)) + ) + + def test_decode_with_int2int_map(self): + a = ord('a') + b = ord('b') + c = ord('c') + + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "strict", + {0: a, 1: b, 2: c}), + ("abc", 3) + ) + + # Issue #15379 + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "strict", + {0: 0x10FFFF, 1: b, 2: c}), + ("\U0010FFFFbc", 3) + ) + + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "strict", + {0: sys.maxunicode, 1: b, 2: c}), + (chr(sys.maxunicode) + "bc", 3) + ) + + self.assertRaises(TypeError, + codecs.charmap_decode, b"\x00\x01\x02", "strict", + {0: sys.maxunicode + 1, 1: b, 2: c} + ) + + self.assertRaises(UnicodeDecodeError, + codecs.charmap_decode, b"\x00\x01\x02", "strict", + {0: a, 1: b}, + ) + + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "replace", + {0: a, 1: b}), + ("ab\ufffd", 3) + ) + + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "ignore", + {0: a, 1: b}), + ("ab", 3) + ) + + class WithStmtTest(unittest.TestCase): def test_encodedfile(self): f = io.BytesIO(b"\xc3\xbc") diff --git a/Lib/test/test_compileall.py b/Lib/test/test_compileall.py index 6ec105c..ba9fe46 100644 --- a/Lib/test/test_compileall.py +++ b/Lib/test/test_compileall.py @@ -134,15 +134,21 @@ class EncodingTest(unittest.TestCase): class CommandLineTests(unittest.TestCase): """Test compileall's CLI.""" + def _get_run_args(self, args): + interp_args = ['-S'] + if sys.flags.optimize: + interp_args.append({1 : '-O', 2 : '-OO'}[sys.flags.optimize]) + return interp_args + ['-m', 'compileall'] + list(args) + def assertRunOK(self, *args, **env_vars): rc, out, err = script_helper.assert_python_ok( - '-S', '-m', 'compileall', *args, **env_vars) + *self._get_run_args(args), **env_vars) self.assertEqual(b'', err) return out def assertRunNotOK(self, *args, **env_vars): rc, out, err = script_helper.assert_python_failure( - '-S', '-m', 'compileall', *args, **env_vars) + *self._get_run_args(args), **env_vars) return rc, out, err def assertCompiled(self, fn): @@ -198,7 +204,9 @@ class CommandLineTests(unittest.TestCase): self.assertRunOK('-b', '-q', self.pkgdir) # Verify the __pycache__ directory contents. self.assertFalse(os.path.exists(self.pkgdir_cachedir)) - expected = sorted(['__init__.py', '__init__.pyc', 'bar.py', 'bar.pyc']) + opt = 'c' if __debug__ else 'o' + expected = sorted(['__init__.py', '__init__.py' + opt, 'bar.py', + 'bar.py' + opt]) self.assertEqual(sorted(os.listdir(self.pkgdir)), expected) def test_multiple_runs(self): @@ -326,7 +334,7 @@ class CommandLineTests(unittest.TestCase): f2 = script_helper.make_script(self.pkgdir, 'f2', '') f3 = script_helper.make_script(self.pkgdir, 'f3', '') f4 = script_helper.make_script(self.pkgdir, 'f4', '') - p = script_helper.spawn_python('-m', 'compileall', '-i', '-') + p = script_helper.spawn_python(*(self._get_run_args(()) + ['-i', '-'])) p.stdin.write((f3+os.linesep).encode('ascii')) script_helper.kill_python(p) self.assertNotCompiled(f1) diff --git a/Lib/test/test_csv.py b/Lib/test/test_csv.py index 8ca1e62..55796a2 100644 --- a/Lib/test/test_csv.py +++ b/Lib/test/test_csv.py @@ -225,6 +225,15 @@ class Test_Csv(unittest.TestCase): self.assertRaises(csv.Error, self._read_test, ['a,b\nc,d'], []) self.assertRaises(csv.Error, self._read_test, ['a,b\r\nc,d'], []) + def test_read_eof(self): + self._read_test(['a,"'], [['a', '']]) + self._read_test(['"a'], [['a']]) + self._read_test(['^'], [['\n']], escapechar='^') + self.assertRaises(csv.Error, self._read_test, ['a,"'], [], strict=True) + self.assertRaises(csv.Error, self._read_test, ['"a'], [], strict=True) + self.assertRaises(csv.Error, self._read_test, + ['^'], [], escapechar='^', strict=True) + def test_read_escape(self): self._read_test(['a,\\b,c'], [['a', 'b', 'c']], escapechar='\\') self._read_test(['a,b\\,c'], [['a', 'b,c']], escapechar='\\') diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 3ca5927..ec5db9f 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -34,7 +34,8 @@ import numbers import locale from test.support import (run_unittest, run_doctest, is_resource_enabled, requires_IEEE_754) -from test.support import check_warnings, import_fresh_module, TestFailed +from test.support import (check_warnings, import_fresh_module, TestFailed, + run_with_locale) import random import time import warnings @@ -1136,18 +1137,19 @@ class FormatTest(unittest.TestCase): self.assertEqual(get_fmt(Decimal('-1.5'), dotsep_wide, '020n'), '-0\u00b4000\u00b4000\u00b4000\u00b4001\u00bf5') + @run_with_locale('LC_ALL', 'ps_AF') def test_wide_char_separator_decimal_point(self): # locale with wide char separator and decimal point + import locale Decimal = self.decimal.Decimal - try: - locale.setlocale(locale.LC_ALL, 'ps_AF') - except locale.Error: + decimal_point = locale.localeconv()['decimal_point'] + thousands_sep = locale.localeconv()['thousands_sep'] + if decimal_point != '\u066b' or thousands_sep != '\u066c': return self.assertEqual(format(Decimal('100000000.123'), 'n'), '100\u066c000\u066c000\u066b123') - locale.resetlocale() class CFormatTest(FormatTest): decimal = C diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py index 44b9554..8f8c7c7 100644 --- a/Lib/test/test_doctest.py +++ b/Lib/test/test_doctest.py @@ -1986,6 +1986,31 @@ def test_DocTestSuite(): >>> suite.run(unittest.TestResult()) <unittest.result.TestResult run=9 errors=0 failures=4> + The module need not contain any doctest examples: + + >>> suite = doctest.DocTestSuite('test.sample_doctest_no_doctests') + >>> suite.run(unittest.TestResult()) + <unittest.result.TestResult run=0 errors=0 failures=0> + + However, if DocTestSuite finds no docstrings, it raises an error: + + >>> try: + ... doctest.DocTestSuite('test.sample_doctest_no_docstrings') + ... except ValueError as e: + ... error = e + + >>> print(error.args[1]) + has no docstrings + + You can prevent this error by passing a DocTestFinder instance with + the `exclude_empty` keyword argument set to False: + + >>> finder = doctest.DocTestFinder(exclude_empty=False) + >>> suite = doctest.DocTestSuite('test.sample_doctest_no_docstrings', + ... test_finder=finder) + >>> suite.run(unittest.TestResult()) + <unittest.result.TestResult run=0 errors=0 failures=0> + We can use the current module: >>> suite = test.sample_doctest.test_suite() diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py index 27fccd6..a872e68 100644 --- a/Lib/test/test_gdb.py +++ b/Lib/test/test_gdb.py @@ -154,6 +154,11 @@ class DebuggerTests(unittest.TestCase): err = err.replace("warning: Cannot initialize thread debugging" " library: Debugger service failed\n", '') + err = err.replace('warning: Could not load shared library symbols for ' + 'linux-vdso.so.1.\n' + 'Do you need "set solib-search-path" or ' + '"set sysroot"?\n', + '') # Ensure no unexpected error messages: self.assertEqual(err, '') diff --git a/Lib/test/test_import.py b/Lib/test/test_import.py index 19863b9..0746411 100644 --- a/Lib/test/test_import.py +++ b/Lib/test/test_import.py @@ -591,7 +591,7 @@ class PycacheTests(unittest.TestCase): self.assertTrue(os.path.exists('__pycache__')) self.assertTrue(os.path.exists(os.path.join( '__pycache__', '{}.{}.py{}'.format( - TESTFN, self.tag, __debug__ and 'c' or 'o')))) + TESTFN, self.tag, 'c' if __debug__ else 'o')))) @unittest.skipUnless(os.name == 'posix', "test meaningful only on posix systems") diff --git a/Lib/test/test_importlib/test_locks.py b/Lib/test/test_importlib/test_locks.py index d36b71e..c373b11 100644 --- a/Lib/test/test_importlib/test_locks.py +++ b/Lib/test/test_importlib/test_locks.py @@ -1,4 +1,5 @@ from importlib import _bootstrap +import sys import time import unittest import weakref @@ -41,6 +42,17 @@ else: @unittest.skipUnless(threading, "threads needed for this test") class DeadlockAvoidanceTests(unittest.TestCase): + def setUp(self): + try: + self.old_switchinterval = sys.getswitchinterval() + sys.setswitchinterval(0.000001) + except AttributeError: + self.old_switchinterval = None + + def tearDown(self): + if self.old_switchinterval is not None: + sys.setswitchinterval(self.old_switchinterval) + def run_deadlock_avoidance_test(self, create_deadlock): NLOCKS = 10 locks = [LockType(str(i)) for i in range(NLOCKS)] @@ -75,10 +87,12 @@ class DeadlockAvoidanceTests(unittest.TestCase): def test_deadlock(self): results = self.run_deadlock_avoidance_test(True) - # One of the threads detected a potential deadlock on its second - # acquire() call. - self.assertEqual(results.count((True, False)), 1) - self.assertEqual(results.count((True, True)), len(results) - 1) + # At least one of the threads detected a potential deadlock on its + # second acquire() call. It may be several of them, because the + # deadlock avoidance mechanism is conservative. + nb_deadlocks = results.count((True, False)) + self.assertGreaterEqual(nb_deadlocks, 1) + self.assertEqual(results.count((True, True)), len(results) - nb_deadlocks) def test_no_deadlock(self): results = self.run_deadlock_avoidance_test(False) diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py index 437e323..227759f 100644 --- a/Lib/test/test_int.py +++ b/Lib/test/test_int.py @@ -305,6 +305,18 @@ class IntTestCases(unittest.TestCase): self.fail("Failed to raise TypeError with %s" % ((base, trunc_result_base),)) + # Regression test for bugs.python.org/issue16060. + class BadInt(trunc_result_base): + def __int__(self): + return 42.0 + + class TruncReturnsBadInt(base): + def __trunc__(self): + return BadInt() + + with self.assertRaises(TypeError): + int(TruncReturnsBadInt()) + def test_error_message(self): testlist = ('\xbd', '123\xbd', ' 123 456 ') for s in testlist: diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 5735350..d5eec7c 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -2887,6 +2887,11 @@ class MiscIOTest(unittest.TestCase): with self.open(support.TESTFN, 'rb') as f: self.assertEqual(b"spam", f.read()) + def test_open_allargs(self): + # there used to be a buffer overflow in the parser for rawmode + self.assertRaises(ValueError, self.open, support.TESTFN, 'rwax+') + + class CMiscIOTest(MiscIOTest): io = io diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py index 5515357..6b1e933 100644 --- a/Lib/test/test_mailbox.py +++ b/Lib/test/test_mailbox.py @@ -53,7 +53,7 @@ class TestMailbox(TestBase): maxDiff = None _factory = None # Overridden by subclasses to reuse tests - _template = 'From: foo\n\n%s' + _template = 'From: foo\n\n%s\n' def setUp(self): self._path = support.TESTFN @@ -232,7 +232,7 @@ class TestMailbox(TestBase): key0 = self._box.add(self._template % 0) msg = self._box.get(key0) self.assertEqual(msg['from'], 'foo') - self.assertEqual(msg.get_payload(), '0') + self.assertEqual(msg.get_payload(), '0\n') self.assertIs(self._box.get('foo'), None) self.assertIs(self._box.get('foo', False), False) self._box.close() @@ -240,14 +240,14 @@ class TestMailbox(TestBase): key1 = self._box.add(self._template % 1) msg = self._box.get(key1) self.assertEqual(msg['from'], 'foo') - self.assertEqual(msg.get_payload(), '1') + self.assertEqual(msg.get_payload(), '1\n') def test_getitem(self): # Retrieve message using __getitem__() key0 = self._box.add(self._template % 0) msg = self._box[key0] self.assertEqual(msg['from'], 'foo') - self.assertEqual(msg.get_payload(), '0') + self.assertEqual(msg.get_payload(), '0\n') self.assertRaises(KeyError, lambda: self._box['foo']) self._box.discard(key0) self.assertRaises(KeyError, lambda: self._box[key0]) @@ -259,7 +259,7 @@ class TestMailbox(TestBase): msg0 = self._box.get_message(key0) self.assertIsInstance(msg0, mailbox.Message) self.assertEqual(msg0['from'], 'foo') - self.assertEqual(msg0.get_payload(), '0') + self.assertEqual(msg0.get_payload(), '0\n') self._check_sample(self._box.get_message(key1)) def test_get_bytes(self): @@ -432,15 +432,15 @@ class TestMailbox(TestBase): self.assertIn(key0, self._box) key1 = self._box.add(self._template % 1) self.assertIn(key1, self._box) - self.assertEqual(self._box.pop(key0).get_payload(), '0') + self.assertEqual(self._box.pop(key0).get_payload(), '0\n') self.assertNotIn(key0, self._box) self.assertIn(key1, self._box) key2 = self._box.add(self._template % 2) self.assertIn(key2, self._box) - self.assertEqual(self._box.pop(key2).get_payload(), '2') + self.assertEqual(self._box.pop(key2).get_payload(), '2\n') self.assertNotIn(key2, self._box) self.assertIn(key1, self._box) - self.assertEqual(self._box.pop(key1).get_payload(), '1') + self.assertEqual(self._box.pop(key1).get_payload(), '1\n') self.assertNotIn(key1, self._box) self.assertEqual(len(self._box), 0) @@ -635,7 +635,7 @@ class TestMaildir(TestMailbox, unittest.TestCase): msg_returned = self._box.get_message(key) self.assertEqual(msg_returned.get_subdir(), 'new') self.assertEqual(msg_returned.get_flags(), '') - self.assertEqual(msg_returned.get_payload(), '1') + self.assertEqual(msg_returned.get_payload(), '1\n') msg2 = mailbox.MaildirMessage(self._template % 2) msg2.set_info('2,S') self._box[key] = msg2 @@ -643,7 +643,7 @@ class TestMaildir(TestMailbox, unittest.TestCase): msg_returned = self._box.get_message(key) self.assertEqual(msg_returned.get_subdir(), 'new') self.assertEqual(msg_returned.get_flags(), 'S') - self.assertEqual(msg_returned.get_payload(), '3') + self.assertEqual(msg_returned.get_payload(), '3\n') def test_consistent_factory(self): # Add a message. @@ -763,13 +763,13 @@ class TestMaildir(TestMailbox, unittest.TestCase): self.assertIsNot(match, None, "Invalid file name: '%s'" % tail) groups = match.groups() if previous_groups is not None: - self.assertTrue(int(groups[0] >= previous_groups[0]), + self.assertGreaterEqual(int(groups[0]), int(previous_groups[0]), "Non-monotonic seconds: '%s' before '%s'" % (previous_groups[0], groups[0])) - self.assertTrue(int(groups[1] >= previous_groups[1]) or - groups[0] != groups[1], - "Non-monotonic milliseconds: '%s' before '%s'" % - (previous_groups[1], groups[1])) + if int(groups[0]) == int(previous_groups[0]): + self.assertGreaterEqual(int(groups[1]), int(previous_groups[1]), + "Non-monotonic milliseconds: '%s' before '%s'" % + (previous_groups[1], groups[1])) self.assertEqual(int(groups[2]), pid, "Process ID mismatch: '%s' should be '%s'" % (groups[2], pid)) @@ -996,20 +996,20 @@ class _TestMboxMMDF(_TestSingleFile): def test_add_from_string(self): # Add a string starting with 'From ' to the mailbox - key = self._box.add('From foo@bar blah\nFrom: foo\n\n0') + key = self._box.add('From foo@bar blah\nFrom: foo\n\n0\n') self.assertEqual(self._box[key].get_from(), 'foo@bar blah') - self.assertEqual(self._box[key].get_payload(), '0') + self.assertEqual(self._box[key].get_payload(), '0\n') def test_add_from_bytes(self): # Add a byte string starting with 'From ' to the mailbox - key = self._box.add(b'From foo@bar blah\nFrom: foo\n\n0') + key = self._box.add(b'From foo@bar blah\nFrom: foo\n\n0\n') self.assertEqual(self._box[key].get_from(), 'foo@bar blah') - self.assertEqual(self._box[key].get_payload(), '0') + self.assertEqual(self._box[key].get_payload(), '0\n') def test_add_mbox_or_mmdf_message(self): # Add an mboxMessage or MMDFMessage for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage): - msg = class_('From foo@bar blah\nFrom: foo\n\n0') + msg = class_('From foo@bar blah\nFrom: foo\n\n0\n') key = self._box.add(msg) def test_open_close_open(self): @@ -1116,6 +1116,29 @@ class TestMbox(_TestMboxMMDF, unittest.TestCase): perms = st.st_mode self.assertFalse((perms & 0o111)) # Execute bits should all be off. + def test_terminating_newline(self): + message = email.message.Message() + message['From'] = 'john@example.com' + message.set_payload('No newline at the end') + i = self._box.add(message) + + # A newline should have been appended to the payload + message = self._box.get(i) + self.assertEqual(message.get_payload(), 'No newline at the end\n') + + def test_message_separator(self): + # Check there's always a single blank line after each message + self._box.add('From: foo\n\n0') # No newline at the end + with open(self._path) as f: + data = f.read() + self.assertEqual(data[-3:], '0\n\n') + + self._box.add('From: foo\n\n0\n') # Newline at the end + with open(self._path) as f: + data = f.read() + self.assertEqual(data[-3:], '0\n\n') + + class TestMMDF(_TestMboxMMDF, unittest.TestCase): _factory = lambda self, path, factory=None: mailbox.MMDF(path, factory) diff --git a/Lib/test/test_memoryio.py b/Lib/test/test_memoryio.py index 04ec8e7..e5db945 100644 --- a/Lib/test/test_memoryio.py +++ b/Lib/test/test_memoryio.py @@ -318,9 +318,9 @@ class MemoryTestMixin: self.assertEqual(memio.isatty(), False) self.assertEqual(memio.closed, False) memio.close() - self.assertEqual(memio.writable(), True) - self.assertEqual(memio.readable(), True) - self.assertEqual(memio.seekable(), True) + self.assertRaises(ValueError, memio.writable) + self.assertRaises(ValueError, memio.readable) + self.assertRaises(ValueError, memio.seekable) self.assertRaises(ValueError, memio.isatty) self.assertEqual(memio.closed, True) @@ -665,7 +665,6 @@ class CBytesIOTest(PyBytesIOTest): check(io.BytesIO(b'a'), basesize + 1 + 1 ) check(io.BytesIO(b'a' * 1000), basesize + 1000 + 1 ) - class CStringIOTest(PyStringIOTest): ioclass = io.StringIO UnsupportedOperation = io.UnsupportedOperation diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py index 2230028..a3de398 100644 --- a/Lib/test/test_mmap.py +++ b/Lib/test/test_mmap.py @@ -488,6 +488,15 @@ class MmapTests(unittest.TestCase): f.flush () return mmap.mmap (f.fileno(), 0) + def test_empty_file (self): + f = open (TESTFN, 'w+b') + f.close() + with open(TESTFN, "rb") as f : + self.assertRaisesRegex(ValueError, + "cannot mmap an empty file", + mmap.mmap, f.fileno(), 0, + access=mmap.ACCESS_READ) + def test_offset (self): f = open (TESTFN, 'w+b') diff --git a/Lib/test/test_multiprocessing.py b/Lib/test/test_multiprocessing.py index b70783a..e313dd6 100644 --- a/Lib/test/test_multiprocessing.py +++ b/Lib/test/test_multiprocessing.py @@ -1727,7 +1727,8 @@ class _TestPool(BaseTestCase): with multiprocessing.Pool(2) as p: r = p.map_async(sqr, L) self.assertEqual(r.get(), expected) - self.assertRaises(AssertionError, p.map_async, sqr, L) + print(p._state) + self.assertRaises(ValueError, p.map_async, sqr, L) def raising(): raise KeyError("key") diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 6219eff..7d6b377 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -514,23 +514,23 @@ class EnvironTests(mapping_tests.BasicTestMappingProtocol): return os.environ # Bug 1110478 + @unittest.skipUnless(os.path.exists('/bin/sh'), 'requires /bin/sh') def test_update2(self): os.environ.clear() - if os.path.exists("/bin/sh"): - os.environ.update(HELLO="World") - with os.popen("/bin/sh -c 'echo $HELLO'") as popen: - value = popen.read().strip() - self.assertEqual(value, "World") + os.environ.update(HELLO="World") + with os.popen("/bin/sh -c 'echo $HELLO'") as popen: + value = popen.read().strip() + self.assertEqual(value, "World") + @unittest.skipUnless(os.path.exists('/bin/sh'), 'requires /bin/sh') def test_os_popen_iter(self): - if os.path.exists("/bin/sh"): - with os.popen( - "/bin/sh -c 'echo \"line1\nline2\nline3\"'") as popen: - it = iter(popen) - self.assertEqual(next(it), "line1\n") - self.assertEqual(next(it), "line2\n") - self.assertEqual(next(it), "line3\n") - self.assertRaises(StopIteration, next, it) + with os.popen( + "/bin/sh -c 'echo \"line1\nline2\nline3\"'") as popen: + it = iter(popen) + self.assertEqual(next(it), "line1\n") + self.assertEqual(next(it), "line2\n") + self.assertEqual(next(it), "line3\n") + self.assertRaises(StopIteration, next, it) # Verify environ keys and values from the OS are of the # correct str type. diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py index 27eecb8..117bda0 100644 --- a/Lib/test/test_pyexpat.py +++ b/Lib/test/test_pyexpat.py @@ -641,6 +641,16 @@ class ForeignDTDTests(unittest.TestCase): parser.Parse("<?xml version='1.0'?><element/>") self.assertEqual(handler_call_args, [(None, None)]) + # test UseForeignDTD() is equal to UseForeignDTD(True) + handler_call_args[:] = [] + + parser = expat.ParserCreate() + parser.UseForeignDTD() + parser.SetParamEntityParsing(expat.XML_PARAM_ENTITY_PARSING_ALWAYS) + parser.ExternalEntityRefHandler = resolve_entity + parser.Parse("<?xml version='1.0'?><element/>") + self.assertEqual(handler_call_args, [(None, None)]) + def test_ignore_use_foreign_dtd(self): """ If UseForeignDTD is passed True and a document with an external diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 7716d33..d7c9a31 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -1245,6 +1245,17 @@ class GeneralModuleTests(unittest.TestCase): fp.close() self.assertEqual(repr(fp), "<_io.BufferedReader name=-1>") + def test_unusable_closed_socketio(self): + with socket.socket() as sock: + fp = sock.makefile("rb", buffering=0) + self.assertTrue(fp.readable()) + self.assertFalse(fp.writable()) + self.assertFalse(fp.seekable()) + fp.close() + self.assertRaises(ValueError, fp.readable) + self.assertRaises(ValueError, fp.writable) + self.assertRaises(ValueError, fp.seekable) + def test_pickle(self): sock = socket.socket() with sock: diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 51762cf..4ce98b6 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -125,12 +125,8 @@ class BasicSocketTests(unittest.TestCase): else: self.assertRaises(ssl.SSLError, ssl.RAND_bytes, 16) - try: - ssl.RAND_egd(1) - except TypeError: - pass - else: - print("didn't raise TypeError") + self.assertRaises(TypeError, ssl.RAND_egd, 1) + self.assertRaises(TypeError, ssl.RAND_egd, 'foo', 1) ssl.RAND_add("this is a random string", 75.0) def test_parse_cert(self): diff --git a/Lib/test/test_startfile.py b/Lib/test/test_startfile.py index dd505bf..ae9aeb9 100644 --- a/Lib/test/test_startfile.py +++ b/Lib/test/test_startfile.py @@ -10,8 +10,8 @@ import unittest from test import support import os +import sys from os import path -from time import sleep startfile = support.get_attribute(os, 'startfile') @@ -21,13 +21,12 @@ class TestCase(unittest.TestCase): self.assertRaises(OSError, startfile, "nonexisting.vbs") def test_empty(self): - empty = path.join(path.dirname(__file__), "empty.vbs") - startfile(empty) - startfile(empty, "open") - # Give the child process some time to exit before we finish. - # Otherwise the cleanup code will not be able to delete the cwd, - # because it is still in use. - sleep(0.1) + # Switch to an existing, but safe, working directory to let the + # cleanup code do its thing without permission errors. + with support.temp_cwd(path=path.dirname(sys.executable)): + empty = path.join(path.dirname(__file__), "empty.vbs") + startfile(empty) + startfile(empty, "open") def test_main(): support.run_unittest(TestCase) diff --git a/Lib/test/test_super.py b/Lib/test/test_super.py index 32eb1c0..f6469cf 100644 --- a/Lib/test/test_super.py +++ b/Lib/test/test_super.py @@ -115,6 +115,21 @@ class TestSuper(unittest.TestCase): return __class__ self.assertIs(X.f(), X) + def test_obscure_super_errors(self): + def f(): + super() + self.assertRaises(RuntimeError, f) + def f(x): + del x + super() + self.assertRaises(RuntimeError, f, None) + class X: + def f(x): + nonlocal __class__ + del __class__ + super() + self.assertRaises(RuntimeError, X().f) + def test_main(): support.run_unittest(TestSuper) diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index 14fcdbf..f6ef5f6 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -95,6 +95,15 @@ class TestSupport(unittest.TestCase): self.assertFalse(os.path.exists(TESTFN)) self.assertTrue(os.path.basename(os.getcwd()), here) + def test_temp_cwd__chdir_warning(self): + """Check the warning message when os.chdir() fails.""" + path = TESTFN + '_does_not_exist' + with support.check_warnings() as recorder: + with support.temp_cwd(path=path, quiet=True): + pass + messages = [str(w.message) for w in recorder.warnings] + self.assertEqual(messages, ['tests may fail, unable to change the CWD to ' + path]) + def test_sortdict(self): self.assertEqual(support.sortdict({3:3, 2:2, 1:1}), "{1: 1, 2: 2, 3: 3}") diff --git a/Lib/test/test_textwrap.py b/Lib/test/test_textwrap.py index bb4a851..c86f5cf 100644 --- a/Lib/test/test_textwrap.py +++ b/Lib/test/test_textwrap.py @@ -22,7 +22,7 @@ class BaseTestCase(unittest.TestCase): result = [] for i in range(len(textin)): result.append(" %d: %r" % (i, textin[i])) - result = '\n'.join(result) + result = "\n".join(result) if result else " no lines" elif isinstance(textin, str): result = " %s\n" % repr(textin) return result @@ -66,6 +66,15 @@ class WrapTestCase(BaseTestCase): "I'm glad to hear it!"]) self.check_wrap(text, 80, [text]) + def test_empty_string(self): + # Check that wrapping the empty string returns an empty list. + self.check_wrap("", 6, []) + self.check_wrap("", 6, [], drop_whitespace=False) + + def test_empty_string_with_initial_indent(self): + # Check that the empty string is not indented. + self.check_wrap("", 6, [], initial_indent="++") + self.check_wrap("", 6, [], initial_indent="++", drop_whitespace=False) def test_whitespace(self): # Whitespace munging and end-of-sentence detection @@ -331,7 +340,32 @@ What a mess! ["blah", " ", "(ding", " ", "dong),", " ", "wubba"]) - def test_initial_whitespace(self): + def test_drop_whitespace_false(self): + # Check that drop_whitespace=False preserves whitespace. + # SF patch #1581073 + text = " This is a sentence with much whitespace." + self.check_wrap(text, 10, + [" This is a", " ", "sentence ", + "with ", "much white", "space."], + drop_whitespace=False) + + def test_drop_whitespace_false_whitespace_only(self): + # Check that drop_whitespace=False preserves a whitespace-only string. + self.check_wrap(" ", 6, [" "], drop_whitespace=False) + + def test_drop_whitespace_false_whitespace_only_with_indent(self): + # Check that a whitespace-only string gets indented (when + # drop_whitespace is False). + self.check_wrap(" ", 6, [" "], drop_whitespace=False, + initial_indent=" ") + + def test_drop_whitespace_whitespace_only(self): + # Check drop_whitespace on a whitespace-only string. + self.check_wrap(" ", 6, []) + + def test_drop_whitespace_leading_whitespace(self): + # Check that drop_whitespace does not drop leading whitespace (if + # followed by non-whitespace). # SF bug #622849 reported inconsistent handling of leading # whitespace; let's test that a bit, shall we? text = " This is a sentence with leading whitespace." @@ -340,13 +374,27 @@ What a mess! self.check_wrap(text, 30, [" This is a sentence with", "leading whitespace."]) - def test_no_drop_whitespace(self): - # SF patch #1581073 - text = " This is a sentence with much whitespace." - self.check_wrap(text, 10, - [" This is a", " ", "sentence ", - "with ", "much white", "space."], + def test_drop_whitespace_whitespace_line(self): + # Check that drop_whitespace skips the whole line if a non-leading + # line consists only of whitespace. + text = "abcd efgh" + # Include the result for drop_whitespace=False for comparison. + self.check_wrap(text, 6, ["abcd", " ", "efgh"], drop_whitespace=False) + self.check_wrap(text, 6, ["abcd", "efgh"]) + + def test_drop_whitespace_whitespace_only_with_indent(self): + # Check that initial_indent is not applied to a whitespace-only + # string. This checks a special case of the fact that dropping + # whitespace occurs before indenting. + self.check_wrap(" ", 6, [], initial_indent="++") + + def test_drop_whitespace_whitespace_indent(self): + # Check that drop_whitespace does not drop whitespace indents. + # This checks a special case of the fact that dropping whitespace + # occurs before indenting. + self.check_wrap("abcd efgh", 6, [" abcd", " efgh"], + initial_indent=" ", subsequent_indent=" ") def test_split(self): # Ensure that the standard _split() method works as advertised diff --git a/Lib/test/test_threaded_import.py b/Lib/test/test_threaded_import.py index cfc6842..4a5d7be 100644 --- a/Lib/test/test_threaded_import.py +++ b/Lib/test/test_threaded_import.py @@ -225,9 +225,11 @@ class ThreadedImportTests(unittest.TestCase): @reap_threads def test_main(): old_switchinterval = None + # Issue #15599: FreeBSD/KVM cannot handle gil_interval == 1. + new_switchinterval = 0.00001 if 'freebsd' in sys.platform else 0.00000001 try: old_switchinterval = sys.getswitchinterval() - sys.setswitchinterval(0.00000001) + sys.setswitchinterval(new_switchinterval) except AttributeError: pass try: diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index 31ebd9c..3f5ac98 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -791,7 +791,7 @@ class ClassCreationTests(unittest.TestCase): self.assertEqual(C.y, 1) self.assertEqual(C.z, 2) - def test_new_class_exec_body(self): + def test_new_class_metaclass_keywords(self): #Test that keywords are passed to the metaclass: def meta_func(name, bases, ns, **kw): return name, bases, ns, kw diff --git a/Lib/test/test_webbrowser.py b/Lib/test/test_webbrowser.py new file mode 100644 index 0000000..34b9364 --- /dev/null +++ b/Lib/test/test_webbrowser.py @@ -0,0 +1,192 @@ +import webbrowser +import unittest +import subprocess +from unittest import mock +from test import support + + +URL = 'http://www.example.com' +CMD_NAME = 'test' + + +class PopenMock(mock.MagicMock): + + def poll(self): + return 0 + + def wait(self, seconds=None): + return 0 + + +class CommandTestMixin: + + def _test(self, meth, *, args=[URL], kw={}, options, arguments): + """Given a web browser instance method name along with arguments and + keywords for same (which defaults to the single argument URL), creates + a browser instance from the class pointed to by self.browser, calls the + indicated instance method with the indicated arguments, and compares + the resulting options and arguments passed to Popen by the browser + instance against the 'options' and 'args' lists. Options are compared + in a position independent fashion, and the arguments are compared in + sequence order to whatever is left over after removing the options. + + """ + popen = PopenMock() + support.patch(self, subprocess, 'Popen', popen) + browser = self.browser_class(name=CMD_NAME) + getattr(browser, meth)(*args, **kw) + popen_args = subprocess.Popen.call_args[0][0] + self.assertEqual(popen_args[0], CMD_NAME) + popen_args.pop(0) + for option in options: + self.assertIn(option, popen_args) + popen_args.pop(popen_args.index(option)) + self.assertEqual(popen_args, arguments) + + +class GenericBrowserCommandTest(CommandTestMixin, unittest.TestCase): + + browser_class = webbrowser.GenericBrowser + + def test_open(self): + self._test('open', + options=[], + arguments=[URL]) + + +class BackgroundBrowserCommandTest(CommandTestMixin, unittest.TestCase): + + browser_class = webbrowser.BackgroundBrowser + + def test_open(self): + self._test('open', + options=[], + arguments=[URL]) + + +class ChromeCommandTest(CommandTestMixin, unittest.TestCase): + + browser_class = webbrowser.Chrome + + def test_open(self): + self._test('open', + options=[], + arguments=[URL]) + + def test_open_with_autoraise_false(self): + self._test('open', kw=dict(autoraise=False), + options=[], + arguments=[URL]) + + def test_open_new(self): + self._test('open_new', + options=['--new-window'], + arguments=[URL]) + + def test_open_new_tab(self): + self._test('open_new_tab', + options=[], + arguments=[URL]) + + +class MozillaCommandTest(CommandTestMixin, unittest.TestCase): + + browser_class = webbrowser.Mozilla + + def test_open(self): + self._test('open', + options=['-raise', '-remote'], + arguments=['openURL({})'.format(URL)]) + + def test_open_with_autoraise_false(self): + self._test('open', kw=dict(autoraise=False), + options=['-noraise', '-remote'], + arguments=['openURL({})'.format(URL)]) + + def test_open_new(self): + self._test('open_new', + options=['-raise', '-remote'], + arguments=['openURL({},new-window)'.format(URL)]) + + def test_open_new_tab(self): + self._test('open_new_tab', + options=['-raise', '-remote'], + arguments=['openURL({},new-tab)'.format(URL)]) + + +class GaleonCommandTest(CommandTestMixin, unittest.TestCase): + + browser_class = webbrowser.Galeon + + def test_open(self): + self._test('open', + options=['-n'], + arguments=[URL]) + + def test_open_with_autoraise_false(self): + self._test('open', kw=dict(autoraise=False), + options=['-noraise', '-n'], + arguments=[URL]) + + def test_open_new(self): + self._test('open_new', + options=['-w'], + arguments=[URL]) + + def test_open_new_tab(self): + self._test('open_new_tab', + options=['-w'], + arguments=[URL]) + + +class OperaCommandTest(CommandTestMixin, unittest.TestCase): + + browser_class = webbrowser.Opera + + def test_open(self): + self._test('open', + options=['-remote'], + arguments=['openURL({})'.format(URL)]) + + def test_open_with_autoraise_false(self): + self._test('open', kw=dict(autoraise=False), + options=['-remote', '-noraise'], + arguments=['openURL({})'.format(URL)]) + + def test_open_new(self): + self._test('open_new', + options=['-remote'], + arguments=['openURL({},new-window)'.format(URL)]) + + def test_open_new(self): + self._test('open_new_tab', + options=['-remote'], + arguments=['openURL({},new-page)'.format(URL)]) + + +class ELinksCommandTest(CommandTestMixin, unittest.TestCase): + + browser_class = webbrowser.Elinks + + def test_open(self): + self._test('open', options=['-remote'], + arguments=['openURL({})'.format(URL)]) + + def test_open_with_autoraise_false(self): + self._test('open', + options=['-remote'], + arguments=['openURL({})'.format(URL)]) + + def test_open_new(self): + self._test('open_new', + options=['-remote'], + arguments=['openURL({},new-window)'.format(URL)]) + + def test_open_new_tab(self): + self._test('open_new_tab', + options=['-remote'], + arguments=['openURL({},new-tab)'.format(URL)]) + + +if __name__=='__main__': + unittest.main() diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index da1ad09..97d64fc 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -1809,6 +1809,18 @@ class ElementTreeTest(unittest.TestCase): mye = MyElement('joe') self.assertEqual(mye.newmethod(), 'joe') + def test_html_empty_elems_serialization(self): + # issue 15970 + # from http://www.w3.org/TR/html401/index/elements.html + for element in ['AREA', 'BASE', 'BASEFONT', 'BR', 'COL', 'FRAME', 'HR', + 'IMG', 'INPUT', 'ISINDEX', 'LINK', 'META', 'PARAM']: + for elem in [element, element.lower()]: + expected = '<%s>' % elem + serialized = serialize(ET.XML('<%s />' % elem), method='html') + self.assertEqual(serialized, expected) + serialized = serialize(ET.XML('<%s></%s>' % (elem,elem)), + method='html') + self.assertEqual(serialized, expected) class ElementIterTest(unittest.TestCase): def _ilist(self, elem, tag=None): diff --git a/Lib/test/test_zipimport_support.py b/Lib/test/test_zipimport_support.py index 0c93a8c..f7f3398 100644 --- a/Lib/test/test_zipimport_support.py +++ b/Lib/test/test_zipimport_support.py @@ -29,7 +29,8 @@ verbose = test.support.verbose # test_cmd_line_script (covers the zipimport support in runpy) # Retrieve some helpers from other test cases -from test import test_doctest, sample_doctest +from test import (test_doctest, sample_doctest, sample_doctest_no_doctests, + sample_doctest_no_docstrings) def _run_object_doctest(obj, module): @@ -105,16 +106,26 @@ class ZipSupportTests(unittest.TestCase): "test_zipped_doctest") test_src = test_src.replace("test.sample_doctest", "sample_zipped_doctest") - sample_src = inspect.getsource(sample_doctest) - sample_src = sample_src.replace("test.test_doctest", - "test_zipped_doctest") + # The sample doctest files rewritten to include in the zipped version. + sample_sources = {} + for mod in [sample_doctest, sample_doctest_no_doctests, + sample_doctest_no_docstrings]: + src = inspect.getsource(mod) + src = src.replace("test.test_doctest", "test_zipped_doctest") + # Rewrite the module name so that, for example, + # "test.sample_doctest" becomes "sample_zipped_doctest". + mod_name = mod.__name__.split(".")[-1] + mod_name = mod_name.replace("sample_", "sample_zipped_") + sample_sources[mod_name] = src + with temp_dir() as d: script_name = make_script(d, 'test_zipped_doctest', test_src) zip_name, run_name = make_zip_script(d, 'test_zip', script_name) z = zipfile.ZipFile(zip_name, 'a') - z.writestr("sample_zipped_doctest.py", sample_src) + for mod_name, src in sample_sources.items(): + z.writestr(mod_name + ".py", src) z.close() if verbose: zip_file = zipfile.ZipFile(zip_name, 'r') |