diff options
author | Brett Cannon <brett@python.org> | 2011-03-17 18:16:38 (GMT) |
---|---|---|
committer | Brett Cannon <brett@python.org> | 2011-03-17 18:16:38 (GMT) |
commit | eb8cee83833830630f9d7388bd09d1fcb638b1a2 (patch) | |
tree | 651105352b4f7b17a4e747886562546082e9aaee /Lib/test | |
parent | ecc2db515202456a67e9702ed94ce19fe5b4711f (diff) | |
parent | e9ff2ef20488eb3d1e8bba04516939585f35a148 (diff) | |
download | cpython-eb8cee83833830630f9d7388bd09d1fcb638b1a2.zip cpython-eb8cee83833830630f9d7388bd09d1fcb638b1a2.tar.gz cpython-eb8cee83833830630f9d7388bd09d1fcb638b1a2.tar.bz2 |
merge
Diffstat (limited to 'Lib/test')
38 files changed, 612 insertions, 78 deletions
diff --git a/Lib/test/crashers/README b/Lib/test/crashers/README index 2a73e1b..0259a06 100644 --- a/Lib/test/crashers/README +++ b/Lib/test/crashers/README @@ -14,3 +14,7 @@ note if the cause is system or environment dependent and what the variables are. Once the crash is fixed, the test case should be moved into an appropriate test (even if it was originally from the test suite). This ensures the regression doesn't happen again. And if it does, it should be easier to track down. + +Also see Lib/test_crashers.py which exercises the crashers in this directory. +In particular, make sure to add any new infinite loop crashers to the black +list so it doesn't try to run them. diff --git a/Lib/test/crashers/compiler_recursion.py b/Lib/test/crashers/compiler_recursion.py index 8fd93fc..c00cd6e 100644 --- a/Lib/test/crashers/compiler_recursion.py +++ b/Lib/test/crashers/compiler_recursion.py @@ -9,5 +9,5 @@ Recorded on the tracker as http://bugs.python.org/issue11383 # e.g. '1*'*10**5+'1' will die in compiler_visit_expr # The exact limit to destroy the stack will vary by platform -# but 100k should do the trick most places -compile('()'*10**5, '?', 'exec') +# but 1M should do the trick most places +compile('()'*10**6, '?', 'exec') diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index 4b5c890..e9ceee6 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -3414,7 +3414,7 @@ class TestTimezoneConversions(unittest.TestCase): self.assertEqual(dt, there_and_back) # Because we have a redundant spelling when DST begins, there is - # (unforunately) an hour when DST ends that can't be spelled at all in + # (unfortunately) an hour when DST ends that can't be spelled at all in # local time. When DST ends, the clock jumps from 1:59 back to 1:00 # again. The hour 1:MM DST has no spelling then: 1:MM is taken to be # standard time. 1:MM DST == 0:MM EST, but 0:MM is taken to be diff --git a/Lib/test/pyclbr_input.py b/Lib/test/pyclbr_input.py index 8efc9de..19ccd62 100644 --- a/Lib/test/pyclbr_input.py +++ b/Lib/test/pyclbr_input.py @@ -19,7 +19,7 @@ class C (B): # XXX: This causes test_pyclbr.py to fail, but only because the # introspection-based is_method() code in the test can't - # distinguish between this and a geniune method function like m(). + # distinguish between this and a genuine method function like m(). # The pyclbr.py module gets this right as it parses the text. # #f = f diff --git a/Lib/test/test_binhex.py b/Lib/test/test_binhex.py index d6ef84a..a807bca 100755 --- a/Lib/test/test_binhex.py +++ b/Lib/test/test_binhex.py @@ -15,10 +15,12 @@ class BinHexTestCase(unittest.TestCase): def setUp(self): self.fname1 = support.TESTFN + "1" self.fname2 = support.TESTFN + "2" + self.fname3 = support.TESTFN + "very_long_filename__very_long_filename__very_long_filename__very_long_filename__" def tearDown(self): support.unlink(self.fname1) support.unlink(self.fname2) + support.unlink(self.fname3) DATA = b'Jack is my hero' @@ -37,6 +39,15 @@ class BinHexTestCase(unittest.TestCase): self.assertEqual(self.DATA, finish) + def test_binhex_error_on_long_filename(self): + """ + The testcase fails if no exception is raised when a filename parameter provided to binhex.binhex() + is too long, or if the exception raised in binhex.binhex() is not an instance of binhex.Error. + """ + f3 = open(self.fname3, 'wb') + f3.close() + + self.assertRaises(binhex.Error, binhex.binhex, self.fname3, self.fname2) def test_main(): support.run_unittest(BinHexTestCase) diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 529a2a5..f913347 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -127,7 +127,7 @@ class TestPendingCalls(unittest.TestCase): context.event.set() def test_pendingcalls_non_threaded(self): - #again, just using the main thread, likely they will all be dispathced at + #again, just using the main thread, likely they will all be dispatched at #once. It is ok to ask for too many, because we loop until we find a slot. #the loop can be interrupted to dispatch. #there are only 32 dispatch slots, so we go for twice that! diff --git a/Lib/test/test_crashers.py b/Lib/test/test_crashers.py new file mode 100644 index 0000000..86f88f7 --- /dev/null +++ b/Lib/test/test_crashers.py @@ -0,0 +1,37 @@ +# Tests that the crashers in the Lib/test/crashers directory actually +# do crash the interpreter as expected +# +# If a crasher is fixed, it should be moved elsewhere in the test suite to +# ensure it continues to work correctly. + +import unittest +import glob +import os.path +import test.support +from test.script_helper import assert_python_failure + +CRASHER_DIR = os.path.join(os.path.dirname(__file__), "crashers") +CRASHER_FILES = os.path.join(CRASHER_DIR, "*.py") + +infinite_loops = ["infinite_loop_re.py", "nasty_eq_vs_dict.py"] + +class CrasherTest(unittest.TestCase): + + @test.support.cpython_only + def test_crashers_crash(self): + for fname in glob.glob(CRASHER_FILES): + if os.path.basename(fname) in infinite_loops: + continue + # Some "crashers" only trigger an exception rather than a + # segfault. Consider that an acceptable outcome. + if test.support.verbose: + print("Checking crasher:", fname) + assert_python_failure(fname) + + +def test_main(): + test.support.run_unittest(CrasherTest) + test.support.reap_children() + +if __name__ == "__main__": + test_main() diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 8f1f863..e46cd91 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -228,7 +228,7 @@ class DecimalTest(unittest.TestCase): try: t = self.eval_line(line) except DecimalException as exception: - #Exception raised where there shoudn't have been one. + #Exception raised where there shouldn't have been one. self.fail('Exception "'+exception.__class__.__name__ + '" raised on line '+line) return diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 067c98a..b0d531a 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -3967,7 +3967,7 @@ order (MRO) for bases """ except TypeError: pass else: - self.fail("Carlo Verre __setattr__ suceeded!") + self.fail("Carlo Verre __setattr__ succeeded!") try: object.__delattr__(str, "lower") except TypeError: diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py index b839556..cd87179 100644 --- a/Lib/test/test_doctest.py +++ b/Lib/test/test_doctest.py @@ -1297,7 +1297,7 @@ marking, as well as interline differences. ? + ++ ^ TestResults(failed=1, attempted=1) -The REPORT_ONLY_FIRST_FAILURE supresses result output after the first +The REPORT_ONLY_FIRST_FAILURE suppresses result output after the first failing example: >>> def f(x): @@ -1327,7 +1327,7 @@ failing example: 2 TestResults(failed=3, attempted=5) -However, output from `report_start` is not supressed: +However, output from `report_start` is not suppressed: >>> doctest.DocTestRunner(verbose=True, optionflags=flags).run(test) ... # doctest: +ELLIPSIS @@ -2278,7 +2278,7 @@ We don't want `-v` in sys.argv for these tests. >>> doctest.master = None # Reset master. (Note: we'll be clearing doctest.master after each call to -`doctest.testfile`, to supress warnings about multiple tests with the +`doctest.testfile`, to suppress warnings about multiple tests with the same name.) Globals may be specified with the `globs` and `extraglobs` parameters: @@ -2314,7 +2314,7 @@ optional `module_relative` parameter: TestResults(failed=0, attempted=2) >>> doctest.master = None # Reset master. -Verbosity can be increased with the optional `verbose` paremter: +Verbosity can be increased with the optional `verbose` parameter: >>> doctest.testfile('test_doctest.txt', globs=globs, verbose=True) Trying: @@ -2351,7 +2351,7 @@ parameter: TestResults(failed=1, attempted=2) >>> doctest.master = None # Reset master. -The summary report may be supressed with the optional `report` +The summary report may be suppressed with the optional `report` parameter: >>> doctest.testfile('test_doctest.txt', report=False) diff --git a/Lib/test/test_extcall.py b/Lib/test/test_extcall.py index c31e920..1f7f630 100644 --- a/Lib/test/test_extcall.py +++ b/Lib/test/test_extcall.py @@ -228,7 +228,7 @@ Another helper function >>> Foo.method(1, *[2, 3]) 5 -A PyCFunction that takes only positional parameters shoud allow an +A PyCFunction that takes only positional parameters should allow an empty keyword dictionary to pass without a complaint, but raise a TypeError if te dictionary is not empty diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py index 72a2643..4e6f854 100644 --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -67,7 +67,7 @@ class GeneralFloatCases(unittest.TestCase): def test_float_with_comma(self): # set locale to something that doesn't use '.' for the decimal point # float must not accept the locale specific decimal point but - # it still has to accept the normal python syntac + # it still has to accept the normal python syntax import locale if not locale.localeconv()['decimal_point'] == ',': return @@ -189,7 +189,7 @@ class GeneralFloatCases(unittest.TestCase): def assertEqualAndEqualSign(self, a, b): # fail unless a == b and a and b have the same sign bit; # the only difference from assertEqual is that this test - # distingishes -0.0 and 0.0. + # distinguishes -0.0 and 0.0. self.assertEqual((a, copysign(1.0, a)), (b, copysign(1.0, b))) @support.requires_IEEE_754 diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py index 5127a6f..17b44ea 100644 --- a/Lib/test/test_gdb.py +++ b/Lib/test/test_gdb.py @@ -127,6 +127,9 @@ class DebuggerTests(unittest.TestCase): " inferior's thread library, thread debugging will" " not be available.\n", '') + err = err.replace("warning: Cannot initialize thread debugging" + " library: Debugger service failed\n", + '') # Ensure no unexpected error messages: self.assertEqual(err, '') diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index 05a036a..329b258 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -350,7 +350,7 @@ class GrammarTests(unittest.TestCase): ### simple_stmt: small_stmt (';' small_stmt)* [';'] x = 1; pass; del x def foo(): - # verify statments that end with semi-colons + # verify statements that end with semi-colons x = 1; pass; del x; foo() diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py index 95b9c19..a16e0e3 100644 --- a/Lib/test/test_httpservers.py +++ b/Lib/test/test_httpservers.py @@ -462,7 +462,7 @@ class RejectingSocketlessRequestHandler(SocketlessRequestHandler): return False class BaseHTTPRequestHandlerTestCase(unittest.TestCase): - """Test the functionaility of the BaseHTTPServer. + """Test the functionality of the BaseHTTPServer. Test the support for the Expect 100-continue header. """ diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index ccfcaba..331d247 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -906,6 +906,53 @@ class TestGetattrStatic(unittest.TestCase): self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3) self.assertEqual(inspect.getattr_static(Something, 'foo'), 3) + def test_dict_as_property(self): + test = self + test.called = False + + class Foo(dict): + a = 3 + @property + def __dict__(self): + test.called = True + return {} + + foo = Foo() + foo.a = 4 + self.assertEqual(inspect.getattr_static(foo, 'a'), 3) + self.assertFalse(test.called) + + def test_custom_object_dict(self): + test = self + test.called = False + + class Custom(dict): + def get(self, key, default=None): + test.called = True + super().get(key, default) + + class Foo(object): + a = 3 + foo = Foo() + foo.__dict__ = Custom() + self.assertEqual(inspect.getattr_static(foo, 'a'), 3) + self.assertFalse(test.called) + + def test_metaclass_dict_as_property(self): + class Meta(type): + @property + def __dict__(self): + self.executed = True + + class Thing(metaclass=Meta): + executed = False + + def __init__(self): + self.spam = 42 + + instance = Thing() + self.assertEqual(inspect.getattr_static(instance, "spam"), 42) + self.assertFalse(Thing.executed) class TestGetGeneratorState(unittest.TestCase): diff --git a/Lib/test/test_iterlen.py b/Lib/test/test_iterlen.py index cd92801..7469a31 100644 --- a/Lib/test/test_iterlen.py +++ b/Lib/test/test_iterlen.py @@ -20,11 +20,11 @@ This is the case for tuples, range objects, and itertools.repeat(). Some containers become temporarily immutable during iteration. This includes dicts, sets, and collections.deque. Their implementation is equally simple -though they need to permantently set their length to zero whenever there is +though they need to permanently set their length to zero whenever there is an attempt to iterate after a length mutation. The situation slightly more involved whenever an object allows length mutation -during iteration. Lists and sequence iterators are dynanamically updatable. +during iteration. Lists and sequence iterators are dynamically updatable. So, if a list is extended during iteration, the iterator will continue through the new items. If it shrinks to a point before the most recent iteration, then no further items are available and the length is reported at zero. diff --git a/Lib/test/test_itertools.py b/Lib/test/test_itertools.py index b744636..5e4bf1b 100644 --- a/Lib/test/test_itertools.py +++ b/Lib/test/test_itertools.py @@ -1526,7 +1526,7 @@ Samuele ... return chain(iterable, repeat(None)) >>> def ncycles(iterable, n): -... "Returns the seqeuence elements n times" +... "Returns the sequence elements n times" ... return chain(*repeat(iterable, n)) >>> def dotproduct(vec1, vec2): diff --git a/Lib/test/test_marshal.py b/Lib/test/test_marshal.py index f9b1900..81cf598 100644 --- a/Lib/test/test_marshal.py +++ b/Lib/test/test_marshal.py @@ -194,7 +194,7 @@ class BugsTestCase(unittest.TestCase): # >>> type(loads(dumps(Int()))) # <type 'int'> for typ in (int, float, complex, tuple, list, dict, set, frozenset): - # Note: str sublclasses are not tested because they get handled + # Note: str subclasses are not tested because they get handled # by marshal's routines for objects supporting the buffer API. subtyp = type('subtyp', (typ,), {}) self.assertRaises(ValueError, marshal.dumps, subtyp()) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index c72383a..dddc889 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -820,7 +820,7 @@ class MathTests(unittest.TestCase): # the following tests have been commented out since they don't # really belong here: the implementation of ** for floats is - # independent of the implemention of math.pow + # independent of the implementation of math.pow #self.assertEqual(1**NAN, 1) #self.assertEqual(1**INF, 1) #self.assertEqual(1**NINF, 1) diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py index 9b7100d..e62a046 100644 --- a/Lib/test/test_mmap.py +++ b/Lib/test/test_mmap.py @@ -594,7 +594,7 @@ class MmapTests(unittest.TestCase): m2.close() m1.close() - # Test differnt tag + # Test different tag m1 = mmap.mmap(-1, len(data1), tagname="foo") m1[:] = data1 m2 = mmap.mmap(-1, len(data2), tagname="boo") diff --git a/Lib/test/test_multiprocessing.py b/Lib/test/test_multiprocessing.py index 6f36c19..139ab03 100644 --- a/Lib/test/test_multiprocessing.py +++ b/Lib/test/test_multiprocessing.py @@ -795,7 +795,7 @@ class _TestEvent(BaseTestCase): event = self.Event() wait = TimingWrapper(event.wait) - # Removed temporaily, due to API shear, this does not + # Removed temporarily, due to API shear, this does not # work with threading._Event objects. is_set == isSet self.assertEqual(event.is_set(), False) @@ -1765,7 +1765,7 @@ class _TestFinalize(BaseTestCase): util.Finalize(None, conn.send, args=('STOP',), exitpriority=-100) - # call mutliprocessing's cleanup function then exit process without + # call multiprocessing's cleanup function then exit process without # garbage collecting locals util._exit_function() conn.close() diff --git a/Lib/test/test_pkg.py b/Lib/test/test_pkg.py index a342f7a..a4ddb15 100644 --- a/Lib/test/test_pkg.py +++ b/Lib/test/test_pkg.py @@ -56,7 +56,7 @@ class TestPkg(unittest.TestCase): if self.root: # Only clean if the test was actually run cleanout(self.root) - # delete all modules concerning the tested hiearchy + # delete all modules concerning the tested hierarchy if self.pkgname: modules = [name for name in sys.modules if self.pkgname in name.split('.')] diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py index f045b0b..bb4559c 100644 --- a/Lib/test/test_posixpath.py +++ b/Lib/test/test_posixpath.py @@ -6,6 +6,11 @@ import os import sys from posixpath import realpath, abspath, dirname, basename +try: + import posix +except ImportError: + posix = None + # An absolute path to a temporary filename for testing. We can't rely on TESTFN # being an absolute path, so we need this. @@ -150,6 +155,7 @@ class PosixPathTest(unittest.TestCase): def test_islink(self): self.assertIs(posixpath.islink(support.TESTFN + "1"), False) + self.assertIs(posixpath.lexists(support.TESTFN + "2"), False) f = open(support.TESTFN + "1", "wb") try: f.write(b"foo") @@ -225,6 +231,44 @@ class PosixPathTest(unittest.TestCase): def test_ismount(self): self.assertIs(posixpath.ismount("/"), True) + self.assertIs(posixpath.ismount(b"/"), True) + + def test_ismount_non_existent(self): + # Non-existent mountpoint. + self.assertIs(posixpath.ismount(ABSTFN), False) + try: + os.mkdir(ABSTFN) + self.assertIs(posixpath.ismount(ABSTFN), False) + finally: + safe_rmdir(ABSTFN) + + @unittest.skipUnless(support.can_symlink(), + "Test requires symlink support") + def test_ismount_symlinks(self): + # Symlinks are never mountpoints. + try: + os.symlink("/", ABSTFN) + self.assertIs(posixpath.ismount(ABSTFN), False) + finally: + os.unlink(ABSTFN) + + @unittest.skipIf(posix is None, "Test requires posix module") + def test_ismount_different_device(self): + # Simulate the path being on a different device from its parent by + # mocking out st_dev. + save_lstat = os.lstat + def fake_lstat(path): + st_ino = 0 + st_dev = 0 + if path == ABSTFN: + st_dev = 1 + st_ino = 1 + return posix.stat_result((0, st_ino, st_dev, 0, 0, 0, 0, 0, 0, 0)) + try: + os.lstat = fake_lstat + self.assertIs(posixpath.ismount(ABSTFN), True) + finally: + os.lstat = save_lstat def test_expanduser(self): self.assertEqual(posixpath.expanduser("foo"), "foo") @@ -254,6 +298,10 @@ class PosixPathTest(unittest.TestCase): with support.EnvironmentVarGuard() as env: env['HOME'] = '/' self.assertEqual(posixpath.expanduser("~"), "/") + # expanduser should fall back to using the password database + del env['HOME'] + home = pwd.getpwuid(os.getuid()).pw_dir + self.assertEqual(posixpath.expanduser("~"), home) def test_normpath(self): self.assertEqual(posixpath.normpath(""), ".") @@ -289,6 +337,16 @@ class PosixPathTest(unittest.TestCase): @unittest.skipUnless(hasattr(os, "symlink"), "Missing symlink implementation") @skip_if_ABSTFN_contains_backslash + def test_realpath_relative(self): + try: + os.symlink(posixpath.relpath(ABSTFN+"1"), ABSTFN) + self.assertEqual(realpath(ABSTFN), ABSTFN+"1") + finally: + support.unlink(ABSTFN) + + @unittest.skipUnless(hasattr(os, "symlink"), + "Missing symlink implementation") + @skip_if_ABSTFN_contains_backslash def test_realpath_symlink_loops(self): # Bug #930024, return the path unchanged if we get into an infinite # symlink loop. @@ -443,6 +501,11 @@ class PosixPathTest(unittest.TestCase): finally: os.getcwdb = real_getcwdb + def test_sameopenfile(self): + fname = support.TESTFN + "1" + with open(fname, "wb") as a, open(fname, "wb") as b: + self.assertTrue(posixpath.sameopenfile(a.fileno(), b.fileno())) + class PosixCommonTest(test_genericpath.CommonTest): pathmodule = posixpath diff --git a/Lib/test/test_print.py b/Lib/test/test_print.py index ad71462..8d37bbc 100644 --- a/Lib/test/test_print.py +++ b/Lib/test/test_print.py @@ -20,7 +20,7 @@ NotDefined = object() # A dispatch table all 8 combinations of providing # sep, end, and file # I use this machinery so that I'm not just passing default -# values to print, I'm eiher passing or not passing in the +# values to print, I'm either passing or not passing in the # arguments dispatch = { (False, False, False): diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index 30d9e07..5252d4d 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -7,6 +7,7 @@ import sys import stat import os import os.path +import functools from test import support from test.support import TESTFN from os.path import splitdrive @@ -48,6 +49,21 @@ try: except ImportError: ZIP_SUPPORT = find_executable('zip') +def _fake_rename(*args, **kwargs): + # Pretend the destination path is on a different filesystem. + raise OSError() + +def mock_rename(func): + @functools.wraps(func) + def wrap(*args, **kwargs): + try: + builtin_rename = os.rename + os.rename = _fake_rename + return func(*args, **kwargs) + finally: + os.rename = builtin_rename + return wrap + class TestShutil(unittest.TestCase): def setUp(self): @@ -393,6 +409,41 @@ class TestShutil(unittest.TestCase): shutil.copytree(src_dir, dst_dir, symlinks=True) self.assertIn('test.txt', os.listdir(dst_dir)) + def _copy_file(self, method): + fname = 'test.txt' + tmpdir = self.mkdtemp() + self.write_file([tmpdir, fname]) + file1 = os.path.join(tmpdir, fname) + tmpdir2 = self.mkdtemp() + method(file1, tmpdir2) + file2 = os.path.join(tmpdir2, fname) + return (file1, file2) + + @unittest.skipUnless(hasattr(os, 'chmod'), 'requires os.chmod') + def test_copy(self): + # Ensure that the copied file exists and has the same mode bits. + file1, file2 = self._copy_file(shutil.copy) + self.assertTrue(os.path.exists(file2)) + self.assertEqual(os.stat(file1).st_mode, os.stat(file2).st_mode) + + @unittest.skipUnless(hasattr(os, 'chmod'), 'requires os.chmod') + @unittest.skipUnless(hasattr(os, 'chmod'), 'requires os.utime') + def test_copy2(self): + # Ensure that the copied file exists and has the same mode and + # modification time bits. + file1, file2 = self._copy_file(shutil.copy2) + self.assertTrue(os.path.exists(file2)) + file1_stat = os.stat(file1) + file2_stat = os.stat(file2) + self.assertEqual(file1_stat.st_mode, file2_stat.st_mode) + for attr in 'st_atime', 'st_mtime': + # The modification times may be truncated in the new file. + self.assertLessEqual(getattr(file1_stat, attr), + getattr(file2_stat, attr) + 1) + if hasattr(os, 'chflags') and hasattr(file1_stat, 'st_flags'): + self.assertEqual(getattr(file1_stat, 'st_flags'), + getattr(file2_stat, 'st_flags')) + @unittest.skipUnless(zlib, "requires zlib") def test_make_tarball(self): # creating something to tar @@ -403,6 +454,8 @@ class TestShutil(unittest.TestCase): self.write_file([tmpdir, 'sub', 'file3'], 'xxx') tmpdir2 = self.mkdtemp() + # force shutil to create the directory + os.rmdir(tmpdir2) unittest.skipUnless(splitdrive(tmpdir)[0] == splitdrive(tmpdir2)[0], "source and target should be on same drive") @@ -518,6 +571,8 @@ class TestShutil(unittest.TestCase): self.write_file([tmpdir, 'file2'], 'xxx') tmpdir2 = self.mkdtemp() + # force shutil to create the directory + os.rmdir(tmpdir2) base_name = os.path.join(tmpdir2, 'archive') _make_zipfile(base_name, tmpdir) @@ -645,6 +700,14 @@ class TestShutil(unittest.TestCase): diff = self._compare_dirs(tmpdir, tmpdir2) self.assertEqual(diff, []) + # and again, this time with the format specified + tmpdir3 = self.mkdtemp() + unpack_archive(filename, tmpdir3, format=format) + diff = self._compare_dirs(tmpdir, tmpdir3) + self.assertEqual(diff, []) + self.assertRaises(shutil.ReadError, unpack_archive, TESTFN) + self.assertRaises(ValueError, unpack_archive, TESTFN, format='xxx') + def test_unpack_registery(self): formats = get_unpack_formats() @@ -680,20 +743,11 @@ class TestMove(unittest.TestCase): self.dst_dir = tempfile.mkdtemp() self.src_file = os.path.join(self.src_dir, filename) self.dst_file = os.path.join(self.dst_dir, filename) - # Try to create a dir in the current directory, hoping that it is - # not located on the same filesystem as the system tmp dir. - try: - self.dir_other_fs = tempfile.mkdtemp( - dir=os.path.dirname(__file__)) - self.file_other_fs = os.path.join(self.dir_other_fs, - filename) - except OSError: - self.dir_other_fs = None with open(self.src_file, "wb") as f: f.write(b"spam") def tearDown(self): - for d in (self.src_dir, self.dst_dir, self.dir_other_fs): + for d in (self.src_dir, self.dst_dir): try: if d: shutil.rmtree(d) @@ -722,21 +776,15 @@ class TestMove(unittest.TestCase): # Move a file inside an existing dir on the same filesystem. self._check_move_file(self.src_file, self.dst_dir, self.dst_file) + @mock_rename def test_move_file_other_fs(self): # Move a file to an existing dir on another filesystem. - if not self.dir_other_fs: - # skip - return - self._check_move_file(self.src_file, self.file_other_fs, - self.file_other_fs) + self.test_move_file() + @mock_rename def test_move_file_to_dir_other_fs(self): # Move a file to another location on another filesystem. - if not self.dir_other_fs: - # skip - return - self._check_move_file(self.src_file, self.dir_other_fs, - self.file_other_fs) + self.test_move_file_to_dir() def test_move_dir(self): # Move a dir to another location on the same filesystem. @@ -749,32 +797,20 @@ class TestMove(unittest.TestCase): except: pass + @mock_rename def test_move_dir_other_fs(self): # Move a dir to another location on another filesystem. - if not self.dir_other_fs: - # skip - return - dst_dir = tempfile.mktemp(dir=self.dir_other_fs) - try: - self._check_move_dir(self.src_dir, dst_dir, dst_dir) - finally: - try: - shutil.rmtree(dst_dir) - except: - pass + self.test_move_dir() def test_move_dir_to_dir(self): # Move a dir inside an existing dir on the same filesystem. self._check_move_dir(self.src_dir, self.dst_dir, os.path.join(self.dst_dir, os.path.basename(self.src_dir))) + @mock_rename def test_move_dir_to_dir_other_fs(self): # Move a dir inside an existing dir on another filesystem. - if not self.dir_other_fs: - # skip - return - self._check_move_dir(self.src_dir, self.dir_other_fs, - os.path.join(self.dir_other_fs, os.path.basename(self.src_dir))) + self.test_move_dir_to_dir() def test_existing_file_inside_dest_dir(self): # A file with the same name inside the destination dir already exists. diff --git a/Lib/test/test_strlit.py b/Lib/test/test_strlit.py index 2bcf4d1..fb9cdbb 100644 --- a/Lib/test/test_strlit.py +++ b/Lib/test/test_strlit.py @@ -22,7 +22,7 @@ We have to test this with various file encodings. We also test it with exec()/eval(), which uses a different code path. This file is really about correct treatment of encodings and -backslashes. It doens't concern itself with issues like single +backslashes. It doesn't concern itself with issues like single vs. double quotes or singly- vs. triply-quoted strings: that's dealt with elsewhere (I assume). """ diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py index 77d3789..89c08ed 100644 --- a/Lib/test/test_strptime.py +++ b/Lib/test/test_strptime.py @@ -536,7 +536,7 @@ class CacheTests(unittest.TestCase): self.assertIsNot(first_time_re, second_time_re) # Possible test locale is not supported while initial locale is. # If this is the case just suppress the exception and fall-through - # to the reseting to the original locale. + # to the resetting to the original locale. except locale.Error: pass # Make sure we don't trample on the locale setting once we leave the diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py index 9a9da37..2ccaad2 100644 --- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -463,7 +463,7 @@ class StructTest(unittest.TestCase): test_string) def test_unpack_with_buffer(self): - # SF bug 1563759: struct.unpack doens't support buffer protocol objects + # SF bug 1563759: struct.unpack doesn't support buffer protocol objects data1 = array.array('B', b'\x12\x34\x56\x78') data2 = memoryview(b'\x12\x34\x56\x78') # XXX b'......XXXX......', 6, 4 for data in [data1, data2]: diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index 5f158b9..2dde245 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -130,7 +130,9 @@ class ProcessTestCase(BaseTestCase): "import sys; sys.stdout.write('BDFL')\n" "sys.stdout.flush()\n" "while True: pass"], - timeout=1.5) + # Some heavily loaded buildbots (sparc Debian 3.x) require + # this much time to start and print. + timeout=3) self.fail("Expected TimeoutExpired.") self.assertEqual(c.exception.output, b'BDFL') @@ -323,6 +325,31 @@ class ProcessTestCase(BaseTestCase): rc = subprocess.call([sys.executable, "-c", cmd], stdout=1) self.assertEqual(rc, 2) + def test_stdout_devnull(self): + p = subprocess.Popen([sys.executable, "-c", + 'for i in range(10240):' + 'print("x" * 1024)'], + stdout=subprocess.DEVNULL) + p.wait() + self.assertEqual(p.stdout, None) + + def test_stderr_devnull(self): + p = subprocess.Popen([sys.executable, "-c", + 'import sys\n' + 'for i in range(10240):' + 'sys.stderr.write("x" * 1024)'], + stderr=subprocess.DEVNULL) + p.wait() + self.assertEqual(p.stderr, None) + + def test_stdin_devnull(self): + p = subprocess.Popen([sys.executable, "-c", + 'import sys;' + 'sys.stdin.read(1)'], + stdin=subprocess.DEVNULL) + p.wait() + self.assertEqual(p.stdin, None) + def test_cwd(self): tmpdir = tempfile.gettempdir() # We cannot use os.path.realpath to canonicalize the path, @@ -622,13 +649,15 @@ class ProcessTestCase(BaseTestCase): # Subsequent invocations should just return the returncode self.assertEqual(p.wait(), 0) - def test_wait_timeout(self): p = subprocess.Popen([sys.executable, "-c", "import time; time.sleep(0.1)"]) - self.assertRaises(subprocess.TimeoutExpired, p.wait, timeout=0.01) - self.assertEqual(p.wait(timeout=2), 0) - + with self.assertRaises(subprocess.TimeoutExpired) as c: + p.wait(timeout=0.01) + self.assertIn("0.01", str(c.exception)) # For coverage of __str__. + # Some heavily loaded buildbots (sparc Debian 3.x) require this much + # time to start. + self.assertEqual(p.wait(timeout=3), 0) def test_invalid_bufsize(self): # an invalid type of the bufsize argument should raise diff --git a/Lib/test/test_sundry.py b/Lib/test/test_sundry.py index 4dacb9d..07802d6 100644 --- a/Lib/test/test_sundry.py +++ b/Lib/test/test_sundry.py @@ -54,7 +54,6 @@ class TestUntestedModules(unittest.TestCase): import py_compile import sndhdr import tabnanny - import timeit try: import tty # not available on Windows except ImportError: diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index cd6b9a5..02372ba 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -237,7 +237,7 @@ SyntaxError: can't assign to function call Test continue in finally in weird combinations. -continue in for loop under finally shouuld be ok. +continue in for loop under finally should be ok. >>> def test(): ... try: diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index e2137ab..d412e67 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -492,7 +492,7 @@ class SysModuleTest(unittest.TestCase): # provide too much opportunity for insane things to happen. # We don't want them in the interned dict and if they aren't # actually interned, we don't want to create the appearance - # that they are by allowing intern() to succeeed. + # that they are by allowing intern() to succeed. class S(str): def __hash__(self): return 123 diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index 029218d..c107652 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -578,7 +578,7 @@ class ThreadJoinOnShutdown(BaseTestCase): # This acquires the lock and then waits until the child has forked # before returning, which will release the lock soon after. If # someone else tries to fix this test case by acquiring this lock - # before forking instead of reseting it, the test case will + # before forking instead of resetting it, the test case will # deadlock when it shouldn't. condition = w._block orig_acquire = condition.acquire diff --git a/Lib/test/test_timeit.py b/Lib/test/test_timeit.py new file mode 100644 index 0000000..eb3b1a1 --- /dev/null +++ b/Lib/test/test_timeit.py @@ -0,0 +1,305 @@ +import timeit +import unittest +import sys +import io +import time +from textwrap import dedent + +from test.support import run_unittest +from test.support import captured_stdout +from test.support import captured_stderr + +# timeit's default number of iterations. +DEFAULT_NUMBER = 1000000 + +# timeit's default number of repetitions. +DEFAULT_REPEAT = 3 + +# XXX: some tests are commented out that would improve the coverage but take a +# long time to run because they test the default number of loops, which is +# large. The tests could be enabled if there was a way to override the default +# number of loops during testing, but this would require changing the signature +# of some functions that use the default as a default argument. + +class FakeTimer: + BASE_TIME = 42.0 + def __init__(self, seconds_per_increment=1.0): + self.count = 0 + self.setup_calls = 0 + self.seconds_per_increment=seconds_per_increment + timeit._fake_timer = self + + def __call__(self): + return self.BASE_TIME + self.count * self.seconds_per_increment + + def inc(self): + self.count += 1 + + def setup(self): + self.setup_calls += 1 + + def wrap_timer(self, timer): + """Records 'timer' and returns self as callable timer.""" + self.saved_timer = timer + return self + +class TestTimeit(unittest.TestCase): + + def tearDown(self): + try: + del timeit._fake_timer + except AttributeError: + pass + + def test_reindent_empty(self): + self.assertEqual(timeit.reindent("", 0), "") + self.assertEqual(timeit.reindent("", 4), "") + + def test_reindent_single(self): + self.assertEqual(timeit.reindent("pass", 0), "pass") + self.assertEqual(timeit.reindent("pass", 4), "pass") + + def test_reindent_multi_empty(self): + self.assertEqual(timeit.reindent("\n\n", 0), "\n\n") + self.assertEqual(timeit.reindent("\n\n", 4), "\n \n ") + + def test_reindent_multi(self): + self.assertEqual(timeit.reindent( + "print()\npass\nbreak", 0), + "print()\npass\nbreak") + self.assertEqual(timeit.reindent( + "print()\npass\nbreak", 4), + "print()\n pass\n break") + + def test_timer_invalid_stmt(self): + self.assertRaises(ValueError, timeit.Timer, stmt=None) + + def test_timer_invalid_setup(self): + self.assertRaises(ValueError, timeit.Timer, setup=None) + + fake_setup = "import timeit; timeit._fake_timer.setup()" + fake_stmt = "import timeit; timeit._fake_timer.inc()" + + def fake_callable_setup(self): + self.fake_timer.setup() + + def fake_callable_stmt(self): + self.fake_timer.inc() + + def timeit(self, stmt, setup, number=None): + self.fake_timer = FakeTimer() + t = timeit.Timer(stmt=stmt, setup=setup, timer=self.fake_timer) + kwargs = {} + if number is None: + number = DEFAULT_NUMBER + else: + kwargs['number'] = number + delta_time = t.timeit(**kwargs) + self.assertEqual(self.fake_timer.setup_calls, 1) + self.assertEqual(self.fake_timer.count, number) + self.assertEqual(delta_time, number) + + # Takes too long to run in debug build. + #def test_timeit_default_iters(self): + # self.timeit(self.fake_stmt, self.fake_setup) + + def test_timeit_zero_iters(self): + self.timeit(self.fake_stmt, self.fake_setup, number=0) + + def test_timeit_few_iters(self): + self.timeit(self.fake_stmt, self.fake_setup, number=3) + + def test_timeit_callable_stmt(self): + self.timeit(self.fake_callable_stmt, self.fake_setup, number=3) + + def test_timeit_callable_stmt_and_setup(self): + self.timeit(self.fake_callable_stmt, + self.fake_callable_setup, number=3) + + # Takes too long to run in debug build. + #def test_timeit_function(self): + # delta_time = timeit.timeit(self.fake_stmt, self.fake_setup, + # timer=FakeTimer()) + # self.assertEqual(delta_time, DEFAULT_NUMBER) + + def test_timeit_function_zero_iters(self): + delta_time = timeit.timeit(self.fake_stmt, self.fake_setup, number=0, + timer=FakeTimer()) + self.assertEqual(delta_time, 0) + + def repeat(self, stmt, setup, repeat=None, number=None): + self.fake_timer = FakeTimer() + t = timeit.Timer(stmt=stmt, setup=setup, timer=self.fake_timer) + kwargs = {} + if repeat is None: + repeat = DEFAULT_REPEAT + else: + kwargs['repeat'] = repeat + if number is None: + number = DEFAULT_NUMBER + else: + kwargs['number'] = number + delta_times = t.repeat(**kwargs) + self.assertEqual(self.fake_timer.setup_calls, repeat) + self.assertEqual(self.fake_timer.count, repeat * number) + self.assertEqual(delta_times, repeat * [float(number)]) + + # Takes too long to run in debug build. + #def test_repeat_default(self): + # self.repeat(self.fake_stmt, self.fake_setup) + + def test_repeat_zero_reps(self): + self.repeat(self.fake_stmt, self.fake_setup, repeat=0) + + def test_repeat_zero_iters(self): + self.repeat(self.fake_stmt, self.fake_setup, number=0) + + def test_repeat_few_reps_and_iters(self): + self.repeat(self.fake_stmt, self.fake_setup, repeat=3, number=5) + + def test_repeat_callable_stmt(self): + self.repeat(self.fake_callable_stmt, self.fake_setup, + repeat=3, number=5) + + def test_repeat_callable_stmt_and_setup(self): + self.repeat(self.fake_callable_stmt, self.fake_callable_setup, + repeat=3, number=5) + + # Takes too long to run in debug build. + #def test_repeat_function(self): + # delta_times = timeit.repeat(self.fake_stmt, self.fake_setup, + # timer=FakeTimer()) + # self.assertEqual(delta_times, DEFAULT_REPEAT * [float(DEFAULT_NUMBER)]) + + def test_repeat_function_zero_reps(self): + delta_times = timeit.repeat(self.fake_stmt, self.fake_setup, repeat=0, + timer=FakeTimer()) + self.assertEqual(delta_times, []) + + def test_repeat_function_zero_iters(self): + delta_times = timeit.repeat(self.fake_stmt, self.fake_setup, number=0, + timer=FakeTimer()) + self.assertEqual(delta_times, DEFAULT_REPEAT * [0.0]) + + def assert_exc_string(self, exc_string, expected_exc_name): + exc_lines = exc_string.splitlines() + self.assertGreater(len(exc_lines), 2) + self.assertTrue(exc_lines[0].startswith('Traceback')) + self.assertTrue(exc_lines[-1].startswith(expected_exc_name)) + + def test_print_exc(self): + s = io.StringIO() + t = timeit.Timer("1/0") + try: + t.timeit() + except: + t.print_exc(s) + self.assert_exc_string(s.getvalue(), 'ZeroDivisionError') + + MAIN_DEFAULT_OUTPUT = "10 loops, best of 3: 1 sec per loop\n" + + def run_main(self, seconds_per_increment=1.0, switches=None, timer=None): + if timer is None: + timer = FakeTimer(seconds_per_increment=seconds_per_increment) + if switches is None: + args = [] + else: + args = switches[:] + args.append(self.fake_stmt) + # timeit.main() modifies sys.path, so save and restore it. + orig_sys_path = sys.path[:] + with captured_stdout() as s: + timeit.main(args=args, _wrap_timer=timer.wrap_timer) + sys.path[:] = orig_sys_path[:] + return s.getvalue() + + def test_main_bad_switch(self): + s = self.run_main(switches=['--bad-switch']) + self.assertEqual(s, dedent("""\ + option --bad-switch not recognized + use -h/--help for command line help + """)) + + def test_main_seconds(self): + s = self.run_main(seconds_per_increment=5.5) + self.assertEqual(s, "10 loops, best of 3: 5.5 sec per loop\n") + + def test_main_milliseconds(self): + s = self.run_main(seconds_per_increment=0.0055) + self.assertEqual(s, "100 loops, best of 3: 5.5 msec per loop\n") + + def test_main_microseconds(self): + s = self.run_main(seconds_per_increment=0.0000025, switches=['-n100']) + self.assertEqual(s, "100 loops, best of 3: 2.5 usec per loop\n") + + def test_main_fixed_iters(self): + s = self.run_main(seconds_per_increment=2.0, switches=['-n35']) + self.assertEqual(s, "35 loops, best of 3: 2 sec per loop\n") + + def test_main_setup(self): + s = self.run_main(seconds_per_increment=2.0, + switches=['-n35', '-s', 'print("CustomSetup")']) + self.assertEqual(s, "CustomSetup\n" * 3 + + "35 loops, best of 3: 2 sec per loop\n") + + def test_main_fixed_reps(self): + s = self.run_main(seconds_per_increment=60.0, switches=['-r9']) + self.assertEqual(s, "10 loops, best of 9: 60 sec per loop\n") + + def test_main_negative_reps(self): + s = self.run_main(seconds_per_increment=60.0, switches=['-r-5']) + self.assertEqual(s, "10 loops, best of 1: 60 sec per loop\n") + + def test_main_help(self): + s = self.run_main(switches=['-h']) + # Note: It's not clear that the trailing space was intended as part of + # the help text, but since it's there, check for it. + self.assertEqual(s, timeit.__doc__ + ' ') + + def test_main_using_time(self): + fake_timer = FakeTimer() + s = self.run_main(switches=['-t'], timer=fake_timer) + self.assertEqual(s, self.MAIN_DEFAULT_OUTPUT) + self.assertIs(fake_timer.saved_timer, time.time) + + def test_main_using_clock(self): + fake_timer = FakeTimer() + s = self.run_main(switches=['-c'], timer=fake_timer) + self.assertEqual(s, self.MAIN_DEFAULT_OUTPUT) + self.assertIs(fake_timer.saved_timer, time.clock) + + def test_main_verbose(self): + s = self.run_main(switches=['-v']) + self.assertEqual(s, dedent("""\ + 10 loops -> 10 secs + raw times: 10 10 10 + 10 loops, best of 3: 1 sec per loop + """)) + + def test_main_very_verbose(self): + s = self.run_main(seconds_per_increment=0.000050, switches=['-vv']) + self.assertEqual(s, dedent("""\ + 10 loops -> 0.0005 secs + 100 loops -> 0.005 secs + 1000 loops -> 0.05 secs + 10000 loops -> 0.5 secs + raw times: 0.5 0.5 0.5 + 10000 loops, best of 3: 50 usec per loop + """)) + + def test_main_exception(self): + with captured_stderr() as error_stringio: + s = self.run_main(switches=['1/0']) + self.assert_exc_string(error_stringio.getvalue(), 'ZeroDivisionError') + + def test_main_exception_fixed_reps(self): + with captured_stderr() as error_stringio: + s = self.run_main(switches=['-n1', '1/0']) + self.assert_exc_string(error_stringio.getvalue(), 'ZeroDivisionError') + + +def test_main(): + run_unittest(TestTimeit) + +if __name__ == '__main__': + test_main() diff --git a/Lib/test/test_trace.py b/Lib/test/test_trace.py index d2d15f2..d9bef38 100644 --- a/Lib/test/test_trace.py +++ b/Lib/test/test_trace.py @@ -209,7 +209,7 @@ class TestRunExecCounts(unittest.TestCase): (self.my_py_filename, firstlineno + 4): 1, } - # When used through 'run', some other spurios counts are produced, like + # When used through 'run', some other spurious counts are produced, like # the settrace of threading, which we ignore, just making sure that the # counts fo traced_func_loop were right. # diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py index e148c62..420ff1c 100644 --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -1021,7 +1021,7 @@ class URLopener_Tests(unittest.TestCase): # Just commented them out. # Can't really tell why keep failing in windows and sparc. -# Everywhere else they work ok, but on those machines, someteimes +# Everywhere else they work ok, but on those machines, sometimes # fail in one of the tests, sometimes in other. I have a linux, and # the tests go ok. # If anybody has one of the problematic enviroments, please help! diff --git a/Lib/test/test_warnings.py b/Lib/test/test_warnings.py index c8865fe..dbf30e9 100644 --- a/Lib/test/test_warnings.py +++ b/Lib/test/test_warnings.py @@ -332,7 +332,7 @@ class WarnTests(unittest.TestCase): sys.argv = argv def test_warn_explicit_type_errors(self): - # warn_explicit() shoud error out gracefully if it is given objects + # warn_explicit() should error out gracefully if it is given objects # of the wrong types. # lineno is expected to be an integer. self.assertRaises(TypeError, self.module.warn_explicit, |