diff options
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/output/test_cProfile | 92 | ||||
-rw-r--r-- | Lib/test/output/test_extcall | 117 | ||||
-rwxr-xr-x | Lib/test/regrtest.py | 75 | ||||
-rwxr-xr-x | Lib/test/test_dbm.py | 83 | ||||
-rw-r--r-- | Lib/test/test_dict.py | 10 | ||||
-rw-r--r-- | Lib/test/test_dummy_threading.py | 108 | ||||
-rwxr-xr-x | Lib/test/test_errno.py | 83 | ||||
-rw-r--r-- | Lib/test/test_extcall.py | 536 | ||||
-rw-r--r-- | Lib/test/test_parser.py | 3 | ||||
-rw-r--r-- | Lib/test/test_pep247.py | 105 | ||||
-rw-r--r-- | Lib/test/test_smtplib.py | 8 | ||||
-rwxr-xr-x | Lib/test/test_strftime.py | 315 | ||||
-rw-r--r-- | Lib/test/test_thread.py | 16 | ||||
-rw-r--r-- | Lib/test/test_types.py | 9 | ||||
-rw-r--r-- | Lib/test/test_winsound.py | 12 | ||||
-rw-r--r-- | Lib/test/test_zlib.py | 1 |
16 files changed, 717 insertions, 856 deletions
diff --git a/Lib/test/output/test_cProfile b/Lib/test/output/test_cProfile deleted file mode 100644 index 1221c63..0000000 --- a/Lib/test/output/test_cProfile +++ /dev/null @@ -1,92 +0,0 @@ -test_cProfile - 124 function calls (104 primitive calls) in 1.000 CPU seconds - - Ordered by: standard name - - ncalls tottime percall cumtime percall filename:lineno(function) - 1 0.000 0.000 1.000 1.000 <string>:1(<module>) - 2 0.000 0.000 0.000 0.000 io.py:1213(flush) - 1 0.000 0.000 0.000 0.000 io.py:269(flush) - 1 0.000 0.000 0.000 0.000 io.py:656(closed) - 1 0.000 0.000 0.000 0.000 io.py:874(flush) - 8 0.064 0.008 0.080 0.010 test_cProfile.py:103(subhelper) - 28 0.028 0.001 0.028 0.001 test_cProfile.py:115(__getattr__) - 1 0.270 0.270 1.000 1.000 test_cProfile.py:30(testfunc) - 23/3 0.150 0.007 0.170 0.057 test_cProfile.py:40(factorial) - 20 0.020 0.001 0.020 0.001 test_cProfile.py:53(mul) - 2 0.040 0.020 0.600 0.300 test_cProfile.py:60(helper) - 4 0.116 0.029 0.120 0.030 test_cProfile.py:78(helper1) - 2 0.000 0.000 0.140 0.070 test_cProfile.py:89(helper2_indirect) - 8 0.312 0.039 0.400 0.050 test_cProfile.py:93(helper2) - 1 0.000 0.000 1.000 1.000 {exec} - 12 0.000 0.000 0.012 0.001 {hasattr} - 4 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects} - 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} - 4 0.000 0.000 0.000 0.000 {sys.exc_info} - - - Ordered by: standard name - -Function called... - ncalls tottime cumtime -<string>:1(<module>) -> 1 0.270 1.000 test_cProfile.py:30(testfunc) -io.py:1213(flush) -> 1 0.000 0.000 io.py:269(flush) - 1 0.000 0.000 io.py:874(flush) -io.py:269(flush) -> -io.py:656(closed) -> -io.py:874(flush) -> 1 0.000 0.000 io.py:656(closed) -test_cProfile.py:103(subhelper) -> 16 0.016 0.016 test_cProfile.py:115(__getattr__) -test_cProfile.py:115(__getattr__) -> -test_cProfile.py:30(testfunc) -> 1 0.014 0.130 test_cProfile.py:40(factorial) - 2 0.040 0.600 test_cProfile.py:60(helper) -test_cProfile.py:40(factorial) -> 20/3 0.130 0.147 test_cProfile.py:40(factorial) - 20 0.020 0.020 test_cProfile.py:53(mul) -test_cProfile.py:53(mul) -> -test_cProfile.py:60(helper) -> 4 0.116 0.120 test_cProfile.py:78(helper1) - 2 0.000 0.140 test_cProfile.py:89(helper2_indirect) - 6 0.234 0.300 test_cProfile.py:93(helper2) -test_cProfile.py:78(helper1) -> 4 0.000 0.004 {hasattr} - 4 0.000 0.000 {method 'append' of 'list' objects} - 4 0.000 0.000 {sys.exc_info} -test_cProfile.py:89(helper2_indirect) -> 2 0.006 0.040 test_cProfile.py:40(factorial) - 2 0.078 0.100 test_cProfile.py:93(helper2) -test_cProfile.py:93(helper2) -> 8 0.064 0.080 test_cProfile.py:103(subhelper) - 8 0.000 0.008 {hasattr} -{exec} -> 1 0.000 1.000 <string>:1(<module>) - 2 0.000 0.000 io.py:1213(flush) -{hasattr} -> 12 0.012 0.012 test_cProfile.py:115(__getattr__) -{method 'append' of 'list' objects} -> -{method 'disable' of '_lsprof.Profiler' objects} -> -{sys.exc_info} -> - - - Ordered by: standard name - -Function was called by... - ncalls tottime cumtime -<string>:1(<module>) <- 1 0.000 1.000 {exec} -io.py:1213(flush) <- 2 0.000 0.000 {exec} -io.py:269(flush) <- 1 0.000 0.000 io.py:1213(flush) -io.py:656(closed) <- 1 0.000 0.000 io.py:874(flush) -io.py:874(flush) <- 1 0.000 0.000 io.py:1213(flush) -test_cProfile.py:103(subhelper) <- 8 0.064 0.080 test_cProfile.py:93(helper2) -test_cProfile.py:115(__getattr__) <- 16 0.016 0.016 test_cProfile.py:103(subhelper) - 12 0.012 0.012 {hasattr} -test_cProfile.py:30(testfunc) <- 1 0.270 1.000 <string>:1(<module>) -test_cProfile.py:40(factorial) <- 1 0.014 0.130 test_cProfile.py:30(testfunc) - 20/3 0.130 0.147 test_cProfile.py:40(factorial) - 2 0.006 0.040 test_cProfile.py:89(helper2_indirect) -test_cProfile.py:53(mul) <- 20 0.020 0.020 test_cProfile.py:40(factorial) -test_cProfile.py:60(helper) <- 2 0.040 0.600 test_cProfile.py:30(testfunc) -test_cProfile.py:78(helper1) <- 4 0.116 0.120 test_cProfile.py:60(helper) -test_cProfile.py:89(helper2_indirect) <- 2 0.000 0.140 test_cProfile.py:60(helper) -test_cProfile.py:93(helper2) <- 6 0.234 0.300 test_cProfile.py:60(helper) - 2 0.078 0.100 test_cProfile.py:89(helper2_indirect) -{exec} <- -{hasattr} <- 4 0.000 0.004 test_cProfile.py:78(helper1) - 8 0.000 0.008 test_cProfile.py:93(helper2) -{method 'append' of 'list' objects} <- 4 0.000 0.000 test_cProfile.py:78(helper1) -{method 'disable' of '_lsprof.Profiler' objects} <- -{sys.exc_info} <- 4 0.000 0.000 test_cProfile.py:78(helper1) - - diff --git a/Lib/test/output/test_extcall b/Lib/test/output/test_extcall deleted file mode 100644 index 63f5b71..0000000 --- a/Lib/test/output/test_extcall +++ /dev/null @@ -1,117 +0,0 @@ -test_extcall -() {} -(1,) {} -(1, 2) {} -(1, 2, 3) {} -(1, 2, 3, 4, 5) {} -(1, 2, 3, 4, 5) {} -(1, 2, 3, 4, 5) {} -(1, 2, 3) {'a': 4, 'b': 5} -(1, 2, 3, 4, 5) {'a': 6, 'b': 7} -(1, 2, 3, 6, 7) {'a': 8, 'b': 9, 'x': 4, 'y': 5} -(1, 2, 3) {'a': 4, 'b': 5} -(1, 2, 3, 4, 5) {'a': 6, 'b': 7} -(1, 2, 3, 6, 7) {'a': 8, 'b': 9, 'x': 4, 'y': 5} -TypeError: g() takes at least 1 positional argument (0 given) -TypeError: g() takes at least 1 positional argument (0 given) -TypeError: g() takes at least 1 positional argument (0 given) -1 () {} -1 (2,) {} -1 (2, 3) {} -1 (2, 3, 4, 5) {} -0 (1, 2) {} -0 (1, 2, 3) {} -1 () {'a': 1, 'b': 2, 'c': 3, 'd': 4} -{'a': 1, 'b': 2, 'c': 3} -{'a': 1, 'b': 2, 'c': 3} -g() got multiple values for keyword argument 'x' -g() got multiple values for keyword argument 'b' -f() keywords must be strings -h() got an unexpected keyword argument 'e' -h() argument after * must be a sequence, not function -dir() argument after * must be a sequence, not function -NoneType object argument after * must be a sequence, not function -h() argument after ** must be a mapping, not function -dir() argument after ** must be a mapping, not function -NoneType object argument after ** must be a mapping, not function -dir() got multiple values for keyword argument 'b' -3 512 True -3 -3 -5 -5 -za () {} -> za() takes exactly 1 positional argument (0 given) -za () {'a': 'aa'} -> ok za aa B D E V a -za () {'d': 'dd'} -> za() got an unexpected keyword argument 'd' -za () {'a': 'aa', 'd': 'dd'} -> za() got an unexpected keyword argument 'd' -za () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> za() got an unexpected keyword argument 'b' -za (1, 2) {} -> za() takes exactly 1 positional argument (2 given) -za (1, 2) {'a': 'aa'} -> za() takes exactly 1 non-keyword positional argument (2 given) -za (1, 2) {'d': 'dd'} -> za() takes exactly 1 non-keyword positional argument (2 given) -za (1, 2) {'a': 'aa', 'd': 'dd'} -> za() takes exactly 1 non-keyword positional argument (2 given) -za (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> za() takes exactly 1 non-keyword positional argument (2 given) -za (1, 2, 3, 4, 5) {} -> za() takes exactly 1 positional argument (5 given) -za (1, 2, 3, 4, 5) {'a': 'aa'} -> za() takes exactly 1 non-keyword positional argument (5 given) -za (1, 2, 3, 4, 5) {'d': 'dd'} -> za() takes exactly 1 non-keyword positional argument (5 given) -za (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> za() takes exactly 1 non-keyword positional argument (5 given) -za (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> za() takes exactly 1 non-keyword positional argument (5 given) -zade () {} -> zade() takes at least 1 positional argument (0 given) -zade () {'a': 'aa'} -> ok zade aa B d e V a -zade () {'d': 'dd'} -> zade() takes at least 1 non-keyword positional argument (0 given) -zade () {'a': 'aa', 'd': 'dd'} -> ok zade aa B dd e V d -zade () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zade() got an unexpected keyword argument 'b' -zade (1, 2) {} -> ok zade 1 B 2 e V e -zade (1, 2) {'a': 'aa'} -> zade() got multiple values for keyword argument 'a' -zade (1, 2) {'d': 'dd'} -> zade() got multiple values for keyword argument 'd' -zade (1, 2) {'a': 'aa', 'd': 'dd'} -> zade() got multiple values for keyword argument 'a' -zade (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zade() got multiple values for keyword argument 'a' -zade (1, 2, 3, 4, 5) {} -> zade() takes at most 3 positional arguments (5 given) -zade (1, 2, 3, 4, 5) {'a': 'aa'} -> zade() takes at most 3 non-keyword positional arguments (5 given) -zade (1, 2, 3, 4, 5) {'d': 'dd'} -> zade() takes at most 3 non-keyword positional arguments (5 given) -zade (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zade() takes at most 3 non-keyword positional arguments (5 given) -zade (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zade() takes at most 3 non-keyword positional arguments (5 given) -zabk () {} -> zabk() takes exactly 2 positional arguments (0 given) -zabk () {'a': 'aa'} -> zabk() takes exactly 2 non-keyword positional arguments (1 given) -zabk () {'d': 'dd'} -> zabk() takes exactly 2 non-keyword positional arguments (0 given) -zabk () {'a': 'aa', 'd': 'dd'} -> zabk() takes exactly 2 non-keyword positional arguments (1 given) -zabk () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> ok zabk aa bb D E V {'d': 'dd', 'e': 'ee'} -zabk (1, 2) {} -> ok zabk 1 2 D E V {} -zabk (1, 2) {'a': 'aa'} -> zabk() got multiple values for keyword argument 'a' -zabk (1, 2) {'d': 'dd'} -> ok zabk 1 2 D E V {'d': 'dd'} -zabk (1, 2) {'a': 'aa', 'd': 'dd'} -> zabk() got multiple values for keyword argument 'a' -zabk (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabk() got multiple values for keyword argument 'a' -zabk (1, 2, 3, 4, 5) {} -> zabk() takes exactly 2 positional arguments (5 given) -zabk (1, 2, 3, 4, 5) {'a': 'aa'} -> zabk() takes exactly 2 non-keyword positional arguments (5 given) -zabk (1, 2, 3, 4, 5) {'d': 'dd'} -> zabk() takes exactly 2 non-keyword positional arguments (5 given) -zabk (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zabk() takes exactly 2 non-keyword positional arguments (5 given) -zabk (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabk() takes exactly 2 non-keyword positional arguments (5 given) -zabdv () {} -> zabdv() takes at least 2 positional arguments (0 given) -zabdv () {'a': 'aa'} -> zabdv() takes at least 2 non-keyword positional arguments (1 given) -zabdv () {'d': 'dd'} -> zabdv() takes at least 2 non-keyword positional arguments (0 given) -zabdv () {'a': 'aa', 'd': 'dd'} -> zabdv() takes at least 2 non-keyword positional arguments (1 given) -zabdv () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdv() got an unexpected keyword argument 'e' -zabdv (1, 2) {} -> ok zabdv 1 2 d E () e -zabdv (1, 2) {'a': 'aa'} -> zabdv() got multiple values for keyword argument 'a' -zabdv (1, 2) {'d': 'dd'} -> ok zabdv 1 2 dd E () d -zabdv (1, 2) {'a': 'aa', 'd': 'dd'} -> zabdv() got multiple values for keyword argument 'a' -zabdv (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdv() got multiple values for keyword argument 'a' -zabdv (1, 2, 3, 4, 5) {} -> ok zabdv 1 2 3 E (4, 5) e -zabdv (1, 2, 3, 4, 5) {'a': 'aa'} -> zabdv() got multiple values for keyword argument 'a' -zabdv (1, 2, 3, 4, 5) {'d': 'dd'} -> zabdv() got multiple values for keyword argument 'd' -zabdv (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zabdv() got multiple values for keyword argument 'a' -zabdv (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdv() got multiple values for keyword argument 'a' -zabdevk () {} -> zabdevk() takes at least 2 positional arguments (0 given) -zabdevk () {'a': 'aa'} -> zabdevk() takes at least 2 non-keyword positional arguments (1 given) -zabdevk () {'d': 'dd'} -> zabdevk() takes at least 2 non-keyword positional arguments (0 given) -zabdevk () {'a': 'aa', 'd': 'dd'} -> zabdevk() takes at least 2 non-keyword positional arguments (1 given) -zabdevk () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> ok zabdevk aa bb dd ee () {} -zabdevk (1, 2) {} -> ok zabdevk 1 2 d e () {} -zabdevk (1, 2) {'a': 'aa'} -> zabdevk() got multiple values for keyword argument 'a' -zabdevk (1, 2) {'d': 'dd'} -> ok zabdevk 1 2 dd e () {} -zabdevk (1, 2) {'a': 'aa', 'd': 'dd'} -> zabdevk() got multiple values for keyword argument 'a' -zabdevk (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdevk() got multiple values for keyword argument 'a' -zabdevk (1, 2, 3, 4, 5) {} -> ok zabdevk 1 2 3 4 (5,) {} -zabdevk (1, 2, 3, 4, 5) {'a': 'aa'} -> zabdevk() got multiple values for keyword argument 'a' -zabdevk (1, 2, 3, 4, 5) {'d': 'dd'} -> zabdevk() got multiple values for keyword argument 'd' -zabdevk (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zabdevk() got multiple values for keyword argument 'a' -zabdevk (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdevk() got multiple values for keyword argument 'a' diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py index cb7cf75..20d3777 100755 --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -12,10 +12,9 @@ Command line options: -w: verbose2 -- re-run failed tests in verbose mode -d: debug -- print traceback for failed tests -q: quiet -- don't print anything except if a test fails --g: generate -- write the output file for a test instead of comparing it -x: exclude -- arguments are tests to *exclude* -s: single -- run only a single test (see below) --S: start -- start running all the tests with the specified one first +-S: slow -- print the slowest 10 tests -r: random -- randomize test execution order -f: fromfile -- read names of tests to run from a file (see below) -l: findleaks -- if GC is available detect tests that leak memory @@ -127,14 +126,15 @@ example, to run all the tests except for the bsddb tests, give the option '-uall,-bsddb'. """ -import os -import sys import getopt +import os import random -import warnings import re import io +import sys +import time import traceback +import warnings from inspect import isabstract # I see no other way to suppress these warnings; @@ -186,8 +186,7 @@ def usage(msg): def main(tests=None, testdir=None, verbose=0, quiet=False, generate=False, exclude=False, single=False, randomize=False, fromfile=None, findleaks=False, use_resources=None, trace=False, coverdir='coverage', - runleaks=False, huntrleaks=None, verbose2=False, debug=False, - start=None): + runleaks=False, huntrleaks=False, verbose2=False, print_slow=False): """Execute a test suite. This also parses command-line options and modifies its behavior @@ -204,17 +203,17 @@ def main(tests=None, testdir=None, verbose=0, quiet=False, generate=False, command-line will be used. If that's empty, too, then all *.py files beginning with test_ will be used. - The other default arguments (verbose, quiet, generate, exclude, single, - randomize, findleaks, use_resources, trace and coverdir) allow programmers - calling main() directly to set the values that would normally be set by - flags on the command line. + The other default arguments (verbose, quiet, generate, exclude, + single, randomize, findleaks, use_resources, trace, coverdir, and + print_slow) allow programmers calling main() directly to set the + values that would normally be set by flags on the command line. """ test_support.record_original_stdout(sys.stdout) try: - opts, args = getopt.getopt(sys.argv[1:], 'dhvgqxsS:rf:lu:t:TD:NLR:wM:n', - ['help', 'verbose', 'quiet', 'generate', - 'exclude', 'single', 'random', 'fromfile', + opts, args = getopt.getopt(sys.argv[1:], 'hvgqxsSrf:lu:t:TD:NLR:wM:', + ['help', 'verbose', 'quiet', 'exclude', + 'single', 'slow', 'random', 'fromfile', 'findleaks', 'use=', 'threshold=', 'trace', 'coverdir=', 'nocoverdir', 'runleaks', 'huntrleaks=', 'verbose2', 'memlimit=', @@ -239,14 +238,14 @@ def main(tests=None, testdir=None, verbose=0, quiet=False, generate=False, elif o in ('-q', '--quiet'): quiet = True; verbose = 0 - elif o in ('-g', '--generate'): - generate = True elif o in ('-x', '--exclude'): exclude = True elif o in ('-S', '--start'): start = a elif o in ('-s', '--single'): single = True + elif o in ('-S', '--slow'): + print_slow = True elif o in ('-r', '--randomize'): randomize = True elif o in ('-f', '--fromfile'): @@ -376,18 +375,19 @@ def main(tests=None, testdir=None, verbose=0, quiet=False, generate=False, tests = tests or args or findtests(testdir, stdtests, nottests) if single: tests = tests[:1] - # Remove all the tests that precede start if it's set. - if start: - try: - del tests[:tests.index(start)] - except ValueError: - print("Couldn't find starting test (%s), using all tests" % start) + ## Remove all the tests that precede start if it's set. + #if start: + # try: + # del tests[:tests.index(start)] + # except ValueError: + # print("Couldn't find starting test (%s), using all tests" % start) if randomize: random.shuffle(tests) if trace: import trace tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix], trace=False, count=True) + test_times = [] test_support.verbose = verbose # Tell tests to be moderately quiet test_support.use_resources = use_resources save_modules = sys.modules.keys() @@ -398,12 +398,13 @@ def main(tests=None, testdir=None, verbose=0, quiet=False, generate=False, if trace: # If we're tracing code coverage, then we don't exit with status # if on a false return value from main. - tracer.runctx('runtest(test, generate, verbose, quiet, testdir)', + tracer.runctx('runtest(test, generate, verbose, quiet,' + ' test_times, testdir)', globals=globals(), locals=vars()) else: try: - ok = runtest(test, generate, verbose, quiet, testdir, - huntrleaks) + ok = runtest(test, generate, verbose, quiet, test_times, + testdir, huntrleaks) except KeyboardInterrupt: # print a newline separate from the ^C print() @@ -444,6 +445,11 @@ def main(tests=None, testdir=None, verbose=0, quiet=False, generate=False, if verbose: print("CAUTION: stdout isn't compared in verbose mode:") print("a test that passes in verbose mode may fail without it.") + if print_slow: + test_times.sort(reverse=True) + print("10 slowest tests:") + for time, test in test_times[:10]: + print("%s: %.1fs" % (test, time)) if bad: print(count(len(bad), "test"), "failed:") printlist(bad) @@ -537,15 +543,14 @@ def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS): tests.sort() return stdtests + tests -def runtest(test, generate, verbose, quiet, testdir=None, - huntrleaks=None, debug=False): +def runtest(test, generate, verbose, quiet, test_times, + testdir=None, huntrleaks=False): """Run a single test. test -- the name of the test - generate -- if true, generate output, instead of running the test - and comparing it to a previously created output file verbose -- if true, print more messages quiet -- if true, don't print 'skipped' messages (probably redundant) + test_times -- a list of (time, test_name) pairs testdir -- test directory huntrleaks -- run multiple times to test for leaks; requires a debug build; a triple corresponding to -R's three arguments @@ -559,13 +564,13 @@ def runtest(test, generate, verbose, quiet, testdir=None, """ try: - return runtest_inner(test, generate, verbose, quiet, testdir, - huntrleaks, debug) + return runtest_inner(test, generate, verbose, quiet, test_times, + testdir, huntrleaks) finally: cleanup_test_droppings(test, verbose) -def runtest_inner(test, generate, verbose, quiet, - testdir=None, huntrleaks=None, debug=False): +def runtest_inner(test, generate, verbose, quiet, test_times, + testdir=None, huntrleaks=False, debug=False): test_support.unload(test) if not testdir: testdir = findtestdir() @@ -587,6 +592,7 @@ def runtest_inner(test, generate, verbose, quiet, else: # Always import it from the test package abstest = 'test.' + test + start_time = time.time() the_package = __import__(abstest, globals(), locals(), []) the_module = getattr(the_package, test) # Old tests run to completion simply as a side-effect of @@ -597,6 +603,8 @@ def runtest_inner(test, generate, verbose, quiet, indirect_test() if huntrleaks: dash_R(the_module, test, indirect_test, huntrleaks) + test_time = time.time() - start_time + test_times.append((test_time, test)) finally: sys.stdout = save_stdout except test_support.ResourceDenied as msg: @@ -648,6 +656,7 @@ def runtest_inner(test, generate, verbose, quiet, fp.close() else: expected = test + "\n" + expected = test + "\n" if output == expected or huntrleaks: return 1 print("test", test, "produced unexpected output:") diff --git a/Lib/test/test_dbm.py b/Lib/test/test_dbm.py index 1a40ef6..44b712c 100755 --- a/Lib/test/test_dbm.py +++ b/Lib/test/test_dbm.py @@ -1,61 +1,40 @@ -#! /usr/bin/env python -"""Test script for the dbm module - Roger E. Masse -""" +from test import test_support +import unittest import os +import random import dbm from dbm import error -from test.test_support import verbose, verify, TestSkipped, TESTFN -# make filename unique to allow multiple concurrent tests -# and to minimize the likelihood of a problem from an old file -filename = TESTFN - -def cleanup(): - for suffix in ['', '.pag', '.dir', '.db']: - try: - os.unlink(filename + suffix) - except OSError as e: - (errno, strerror) = e.errno, e.strerror - # if we can't delete the file because of permissions, - # nothing will work, so skip the test - if errno == 1: - raise TestSkipped('unable to remove: ' + filename + suffix) - -def test_keys(): - d = dbm.open(filename, 'c') - verify(d.keys() == []) - d[b'a'] = b'b' - d[b'12345678910'] = b'019237410982340912840198242' - d.keys() - if b'a' in d: - if verbose: - print('Test dbm keys: ', d.keys()) - - d.close() - -def test_modes(): - d = dbm.open(filename, 'r') - d.close() - d = dbm.open(filename, 'rw') - d.close() - d = dbm.open(filename, 'w') - d.close() - d = dbm.open(filename, 'n') - d.close() +class DbmTestCase(unittest.TestCase): + + def setUp(self): + self.filename = test_support.TESTFN + self.d = dbm.open(self.filename, 'c') + self.d.close() + + def tearDown(self): + for suffix in ['', '.pag', '.dir', '.db']: + test_support.unlink(self.filename + suffix) + + def test_keys(self): + self.d = dbm.open(self.filename, 'c') + self.assert_(self.d.keys() == []) + self.d['a'] = 'b' + self.d['12345678910'] = '019237410982340912840198242' + self.d.keys() + self.assert_(b'a' in self.d) + self.d.close() + + def test_modes(self): + for mode in ['r', 'rw', 'w', 'n']: + try: + self.d = dbm.open(self.filename, mode) + self.d.close() + except dbm.error: + self.fail() def test_main(): - cleanup() - try: - test_keys() - test_modes() - except: - cleanup() - raise - - cleanup() - - + test_support.run_unittest(DbmTestCase) if __name__ == '__main__': test_main() diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 1997dc5..01d47da 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -13,12 +13,14 @@ class DictTest(unittest.TestCase): def test_literal_constructor(self): # check literal constructor for different sized dicts (to exercise the BUILD_MAP oparg - items = [] - for n in range(400): + for n in (0, 1, 6, 256, 400): + items = [(''.join([random.choice(string.ascii_letters) + for j in range(8)]), + i) + for i in range(n)] + random.shuffle(items) dictliteral = '{' + ', '.join('%r: %d' % item for item in items) + '}' self.assertEqual(eval(dictliteral), dict(items)) - items.append((''.join([random.choice(string.ascii_letters) for j in range(8)]), n)) - random.shuffle(items) def test_bool(self): self.assert_(not {}) diff --git a/Lib/test/test_dummy_threading.py b/Lib/test/test_dummy_threading.py index 6f16241..2d0dadd 100644 --- a/Lib/test/test_dummy_threading.py +++ b/Lib/test/test_dummy_threading.py @@ -1,71 +1,63 @@ -# Very rudimentary test of threading module - -# Create a bunch of threads, let each do some work, wait until all are done - -from test.test_support import verbose +from test import test_support +import unittest import dummy_threading as _threading import time +class DummyThreadingTestCase(unittest.TestCase): -class TestThread(_threading.Thread): + class TestThread(_threading.Thread): - def run(self): + def run(self): + global running + global sema + global mutex + # Uncomment if testing another module, such as the real 'threading' + # module. + #delay = random.random() * 2 + delay = 0 + if test_support.verbose: + print('task', self.getName(), 'will run for', delay, 'sec') + sema.acquire() + mutex.acquire() + running += 1 + if test_support.verbose: + print(running, 'tasks are running') + mutex.release() + time.sleep(delay) + if test_support.verbose: + print('task', self.getName(), 'done') + mutex.acquire() + running -= 1 + if test_support.verbose: + print(self.getName(), 'is finished.', running, 'tasks are running') + mutex.release() + sema.release() + + def setUp(self): + self.numtasks = 10 + global sema + sema = _threading.BoundedSemaphore(value=3) + global mutex + mutex = _threading.RLock() global running - # Uncomment if testing another module, such as the real 'threading' - # module. - #delay = random.random() * 2 - delay = 0 - if verbose: - print('task', self.getName(), 'will run for', delay, 'sec') - sema.acquire() - mutex.acquire() - running = running + 1 - if verbose: - print(running, 'tasks are running') - mutex.release() - time.sleep(delay) - if verbose: - print('task', self.getName(), 'done') - mutex.acquire() - running = running - 1 - if verbose: - print(self.getName(), 'is finished.', running, 'tasks are running') - mutex.release() - sema.release() + running = 0 + self.threads = [] -def starttasks(): - for i in range(numtasks): - t = TestThread(name="<thread %d>"%i) - threads.append(t) - t.start() + def test_tasks(self): + for i in range(self.numtasks): + t = self.TestThread(name="<thread %d>"%i) + self.threads.append(t) + t.start() + if test_support.verbose: + print('waiting for all tasks to complete') + for t in self.threads: + t.join() + if test_support.verbose: + print('all tasks done') def test_main(): - # This takes about n/3 seconds to run (about n/3 clumps of tasks, times - # about 1 second per clump). - global numtasks - numtasks = 10 - - # no more than 3 of the 10 can run at once - global sema - sema = _threading.BoundedSemaphore(value=3) - global mutex - mutex = _threading.RLock() - global running - running = 0 - - global threads - threads = [] - - starttasks() - - if verbose: - print('waiting for all tasks to complete') - for t in threads: - t.join() - if verbose: - print('all tasks done') - + test_support.run_unittest(DummyThreadingTestCase) if __name__ == '__main__': diff --git a/Lib/test/test_errno.py b/Lib/test/test_errno.py index 25937dc..70bbfbc 100755 --- a/Lib/test/test_errno.py +++ b/Lib/test/test_errno.py @@ -4,46 +4,83 @@ """ import errno -from test.test_support import verbose +from test import test_support +import unittest errors = ['E2BIG', 'EACCES', 'EADDRINUSE', 'EADDRNOTAVAIL', 'EADV', 'EAFNOSUPPORT', 'EAGAIN', 'EALREADY', 'EBADE', 'EBADF', 'EBADFD', 'EBADMSG', 'EBADR', 'EBADRQC', 'EBADSLT', 'EBFONT', 'EBUSY', 'ECHILD', 'ECHRNG', 'ECOMM', 'ECONNABORTED', 'ECONNREFUSED', 'ECONNRESET', - 'EDEADLK', 'EDEADLOCK', 'EDESTADDRREQ', 'EDOM', + 'EDEADLK', 'EDEADLOCK', 'EDESTADDRREQ', 'EDOTDOT', 'EDOM', 'EDQUOT', 'EEXIST', 'EFAULT', 'EFBIG', 'EHOSTDOWN', 'EHOSTUNREACH', 'EIDRM', 'EILSEQ', 'EINPROGRESS', - 'EINTR', 'EINVAL', 'EIO', 'EISCONN', 'EISDIR', + 'EINTR', 'EINVAL', 'EIO', 'EISCONN', 'EISDIR', 'EISNAM', 'EL2HLT', 'EL2NSYNC', 'EL3HLT', 'EL3RST', 'ELIBACC', 'ELIBBAD', 'ELIBEXEC', 'ELIBMAX', 'ELIBSCN', 'ELNRNG', 'ELOOP', 'EMFILE', 'EMLINK', 'EMSGSIZE', 'EMULTIHOP', - 'ENAMETOOLONG', 'ENETDOWN', 'ENETRESET', 'ENETUNREACH', + 'ENAMETOOLONG', 'ENAVAIL', 'ENETDOWN', 'ENETRESET', 'ENETUNREACH', 'ENFILE', 'ENOANO', 'ENOBUFS', 'ENOCSI', 'ENODATA', 'ENODEV', 'ENOENT', 'ENOEXEC', 'ENOLCK', 'ENOLINK', 'ENOMEM', 'ENOMSG', 'ENONET', 'ENOPKG', 'ENOPROTOOPT', 'ENOSPC', 'ENOSR', 'ENOSTR', 'ENOSYS', 'ENOTBLK', - 'ENOTCONN', 'ENOTDIR', 'ENOTEMPTY', 'ENOTOBACCO', 'ENOTSOCK', + 'ENOTCONN', 'ENOTDIR', 'ENOTEMPTY', 'ENOTNAM', 'ENOTOBACCO', 'ENOTSOCK', 'ENOTTY', 'ENOTUNIQ', 'ENXIO', 'EOPNOTSUPP', 'EOVERFLOW', 'EPERM', 'EPFNOSUPPORT', 'EPIPE', 'EPROTO', 'EPROTONOSUPPORT', 'EPROTOTYPE', - 'ERANGE', 'EREMCHG', 'EREMOTE', 'ERESTART', + 'ERANGE', 'EREMCHG', 'EREMOTE', 'EREMOTEIO', 'ERESTART', 'EROFS', 'ESHUTDOWN', 'ESOCKTNOSUPPORT', 'ESPIPE', 'ESRCH', 'ESRMNT', 'ESTALE', 'ESTRPIPE', 'ETIME', - 'ETIMEDOUT', 'ETOOMANYREFS', 'ETXTBSY', 'EUNATCH', - 'EUSERS', 'EWOULDBLOCK', 'EXDEV', 'EXFULL'] - -# -# This is a wee bit bogus since the module only conditionally adds -# errno constants if they have been defined by errno.h However, this -# test seems to work on SGI, Sparc & intel Solaris, and linux. -# -for error in errors: - try: - a = getattr(errno, error) - except AttributeError: - if verbose: - print('%s: not found' % error) - else: - if verbose: - print('%s: %d' % (error, a)) + 'ETIMEDOUT', 'ETOOMANYREFS', 'ETXTBSY', 'EUCLEAN', 'EUNATCH', + 'EUSERS', 'EWOULDBLOCK', 'EXDEV', 'EXFULL', + 'WSABASEERR', 'WSADESCRIPTIO', 'WSAEACCES', 'WSAEADDRINUSE', + 'WSAEADDRNOTAVAIL', 'WSAEAFNOSUPPORT', 'WSAEALREADY', + 'WSAEBADF', 'WSAECONNABORTED', 'WSAECONNREFUSED', + 'WSAECONNRESET', 'WSAEDESTADDRREQ', 'WSAEDISCON', + 'WSAEDQUOT', 'WSAEFAULT', 'WSAEHOSTDOWN', 'WSAEHOSTUNREACH', + 'WSAEINPROGRESS', 'WSAEINTR', 'WSAEINVAL', 'WSAEISCONN', + 'WSAELOOP', 'WSAEMFILE', 'WSAEMSGSIZE', 'WSAENAMETOOLONG', + 'WSAENETDOWN', 'WSAENETRESET', 'WSAENETUNREACH', + 'WSAENOBUFS', 'WSAENOPROTOOPT', 'WSAENOTCONN', + 'WSAENOTEMPTY', 'WSAENOTSOCK', 'WSAEOPNOTSUPP', + 'WSAEPFNOSUPPORT', 'WSAEPROCLIM', 'WSAEPROTONOSUPPORT', + 'WSAEPROTOTYPE', 'WSAEREMOTE', 'WSAESHUTDOWN', + 'WSAESOCKTNOSUPPORT', 'WSAESTALE', 'WSAETIMEDOUT', + 'WSAETOOMANYREFS', 'WSAEUSERS', 'WSAEWOULDBLOCK', + 'WSAGETASYNCBUFLE', 'WSAGETASYNCERRO', 'WSAGETSELECTERRO', + 'WSAGETSELECTEVEN', 'WSAHOS', 'WSAMAKEASYNCREPL', + 'WSAMAKESELECTREPL', 'WSAN', 'WSANOTINITIALISED', 'WSASY', + 'WSASYSNOTREADY', 'WSATR', 'WSAVERNOTSUPPORTED'] + + +class ErrnoAttributeTests(unittest.TestCase): + + def test_for_improper_attributes(self): + # No unexpected attributes should be on the module. + errors_set = set(errors) + for attribute in errno.__dict__.keys(): + if attribute.isupper(): + self.assert_(attribute in errors_set, + "%s is an unexpected error value" % attribute) + + def test_using_errorcode(self): + # Every key value in errno.errorcode should be on the module. + for value in errno.errorcode.values(): + self.assert_(hasattr(errno, value), 'no %s attr in errno' % value) + + +class ErrorcodeTests(unittest.TestCase): + + def test_attributes_in_errorcode(self): + for attribute in errno.__dict__.keys(): + if attribute.isupper(): + self.assert_(getattr(errno, attribute) in errno.errorcode, + 'no %s attr in errno.errorcode' % attribute) + + +def test_main(): + test_support.run_unittest(ErrnoAttributeTests, ErrorcodeTests) + + +if __name__ == '__main__': + test_main() diff --git a/Lib/test/test_extcall.py b/Lib/test/test_extcall.py index bad1440..b6dc144 100644 --- a/Lib/test/test_extcall.py +++ b/Lib/test/test_extcall.py @@ -1,274 +1,262 @@ -from test.test_support import verify, TestFailed, sortdict -from collections import UserDict, UserList - -def e(a, b): - print(a, b) - -def f(*a, **k): - print(a, sortdict(k)) - -def g(x, *y, **z): - print(x, y, sortdict(z)) - -def h(j=1, a=2, h=3): - print(j, a, h) - -f() -f(1) -f(1, 2) -f(1, 2, 3) - -f(1, 2, 3, *(4, 5)) -f(1, 2, 3, *[4, 5]) -f(1, 2, 3, *UserList([4, 5])) -f(1, 2, 3, **{'a':4, 'b':5}) -f(1, 2, 3, *(4, 5), **{'a':6, 'b':7}) -f(1, 2, 3, x=4, y=5, *(6, 7), **{'a':8, 'b':9}) - - -f(1, 2, 3, **UserDict(a=4, b=5)) -f(1, 2, 3, *(4, 5), **UserDict(a=6, b=7)) -f(1, 2, 3, x=4, y=5, *(6, 7), **UserDict(a=8, b=9)) - - -# Verify clearing of SF bug #733667 -try: - e(c=3) -except TypeError: - pass -else: - print("should raise TypeError: e() got an unexpected keyword argument 'c'") - -try: - g() -except TypeError as err: - print("TypeError:", err) -else: - print("should raise TypeError: not enough arguments; expected 1, got 0") - -try: - g(*()) -except TypeError as err: - print("TypeError:", err) -else: - print("should raise TypeError: not enough arguments; expected 1, got 0") - -try: - g(*(), **{}) -except TypeError as err: - print("TypeError:", err) -else: - print("should raise TypeError: not enough arguments; expected 1, got 0") - -g(1) -g(1, 2) -g(1, 2, 3) -g(1, 2, 3, *(4, 5)) -class Nothing: pass -try: - g(*Nothing()) -except TypeError as attr: - pass -else: - print("should raise TypeError") - -class Nothing: - def __len__(self): - return 5 -try: - g(*Nothing()) -except TypeError as attr: - pass -else: - print("should raise TypeError") - -class Nothing: - def __len__(self): - return 5 - def __getitem__(self, i): - if i < 3: - return i - else: - raise IndexError(i) -g(*Nothing()) - -class Nothing: - def __init__(self): - self.c = 0 - def __iter__(self): - return self -try: - g(*Nothing()) -except TypeError as attr: - pass -else: - print("should raise TypeError") - -class Nothing: - def __init__(self): - self.c = 0 - def __iter__(self): - return self - def __next__(self): - if self.c == 4: - raise StopIteration - c = self.c - self.c += 1 - return c -g(*Nothing()) - -# make sure the function call doesn't stomp on the dictionary? -d = {'a': 1, 'b': 2, 'c': 3} -d2 = d.copy() -verify(d == d2) -g(1, d=4, **d) -print(sortdict(d)) -print(sortdict(d2)) -verify(d == d2, "function call modified dictionary") - -# what about willful misconduct? -def saboteur(**kw): - kw['x'] = locals() # yields a cyclic kw - return kw -d = {} -kw = saboteur(a=1, **d) -verify(d == {}) -# break the cycle -del kw['x'] - -try: - g(1, 2, 3, **{'x':4, 'y':5}) -except TypeError as err: - print(err) -else: - print("should raise TypeError: keyword parameter redefined") - -try: - g(1, 2, 3, a=4, b=5, *(6, 7), **{'a':8, 'b':9}) -except TypeError as err: - print(err) -else: - print("should raise TypeError: keyword parameter redefined") - -try: - f(**{1:2}) -except TypeError as err: - print(err) -else: - print("should raise TypeError: keywords must be strings") - -try: - h(**{'e': 2}) -except TypeError as err: - print(err) -else: - print("should raise TypeError: unexpected keyword argument: e") - -try: - h(*h) -except TypeError as err: - print(err) -else: - print("should raise TypeError: * argument must be a tuple") - -try: - dir(*h) -except TypeError as err: - print(err) -else: - print("should raise TypeError: * argument must be a tuple") - -try: - None(*h) -except TypeError as err: - print(err) -else: - print("should raise TypeError: * argument must be a tuple") - -try: - h(**h) -except TypeError as err: - print(err) -else: - print("should raise TypeError: ** argument must be a dictionary") - -try: - dir(**h) -except TypeError as err: - print(err) -else: - print("should raise TypeError: ** argument must be a dictionary") - -try: - None(**h) -except TypeError as err: - print(err) -else: - print("should raise TypeError: ** argument must be a dictionary") - -try: - dir(b=1,**{'b':1}) -except TypeError as err: - print(err) -else: - print("should raise TypeError: dir() got multiple values for keyword argument 'b'") - -def f2(*a, **b): - return a, b - -d = {} -for i in range(512): - key = 'k%d' % i - d[key] = i -a, b = f2(1, *(2, 3), **d) -print(len(a), len(b), b == d) - -class Foo: - def method(self, arg1, arg2): - return arg1 + arg2 - -x = Foo() -print(Foo.method(*(x, 1, 2))) -print(Foo.method(x, *(1, 2))) -print(Foo.method(*(1, 2, 3))) -print(Foo.method(1, *(2, 3))) - -# A PyCFunction that takes only positional parameters should allow an -# empty keyword dictionary to pass without a complaint, but raise a -# TypeError if the dictionary is non-empty. -id(1, **{}) -try: - id(1, **{"foo": 1}) -except TypeError: - pass -else: - raise TestFailed('expected TypeError; no exception raised') - -a, b, d, e, v, k = 'A', 'B', 'D', 'E', 'V', 'K' -funcs = [] -maxargs = {} -for args in ['', 'a', 'ab']: - for defargs in ['', 'd', 'de']: - for vararg in ['', 'v']: - for kwarg in ['', 'k']: - name = 'z' + args + defargs + vararg + kwarg - arglist = list(args) + ['%s="%s"' % (x, x) for x in defargs] - if vararg: arglist.append('*' + vararg) - if kwarg: arglist.append('**' + kwarg) - decl = (('def %s(%s): print("ok %s", a, b, d, e, v, ' + - 'type(k) is type ("") and k or sortdict(k))') - % (name, ', '.join(arglist), name)) - exec(decl) - func = eval(name) - funcs.append(func) - maxargs[func] = len(args + defargs) - -for name in ['za', 'zade', 'zabk', 'zabdv', 'zabdevk']: - func = eval(name) - for args in [(), (1, 2), (1, 2, 3, 4, 5)]: - for kwargs in ['', 'a', 'd', 'ad', 'abde']: - kwdict = {} - for k in kwargs: kwdict[k] = k + k - print(func.__name__, args, sortdict(kwdict), '->', end=' ') - try: func(*args, **kwdict) - except TypeError as err: print(err) +"""Doctest for method/function calls. + +We're going the use these types for extra testing + + >>> from UserList import UserList + >>> from UserDict import UserDict + +We're defining four helper functions + + >>> def e(a,b): + ... print a, b + + >>> def f(*a, **k): + ... print a, test_support.sortdict(k) + + >>> def g(x, *y, **z): + ... print x, y, test_support.sortdict(z) + + >>> def h(j=1, a=2, h=3): + ... print j, a, h + +Argument list examples + + >>> f() + () {} + >>> f(1) + (1,) {} + >>> f(1, 2) + (1, 2) {} + >>> f(1, 2, 3) + (1, 2, 3) {} + >>> f(1, 2, 3, *(4, 5)) + (1, 2, 3, 4, 5) {} + >>> f(1, 2, 3, *[4, 5]) + (1, 2, 3, 4, 5) {} + >>> f(1, 2, 3, *UserList([4, 5])) + (1, 2, 3, 4, 5) {} + +Here we add keyword arguments + + >>> f(1, 2, 3, **{'a':4, 'b':5}) + (1, 2, 3) {'a': 4, 'b': 5} + >>> f(1, 2, 3, *[4, 5], **{'a':6, 'b':7}) + (1, 2, 3, 4, 5) {'a': 6, 'b': 7} + >>> f(1, 2, 3, x=4, y=5, *(6, 7), **{'a':8, 'b': 9}) + (1, 2, 3, 6, 7) {'a': 8, 'b': 9, 'x': 4, 'y': 5} + + >>> f(1, 2, 3, **UserDict(a=4, b=5)) + (1, 2, 3) {'a': 4, 'b': 5} + >>> f(1, 2, 3, *(4, 5), **UserDict(a=6, b=7)) + (1, 2, 3, 4, 5) {'a': 6, 'b': 7} + >>> f(1, 2, 3, x=4, y=5, *(6, 7), **UserDict(a=8, b=9)) + (1, 2, 3, 6, 7) {'a': 8, 'b': 9, 'x': 4, 'y': 5} + +Examples with invalid arguments (TypeErrors). We're also testing the function +names in the exception messages. + +Verify clearing of SF bug #733667 + + >>> e(c=4) + Traceback (most recent call last): + ... + TypeError: e() got an unexpected keyword argument 'c' + + >>> g() + Traceback (most recent call last): + ... + TypeError: g() takes at least 1 argument (0 given) + + >>> g(*()) + Traceback (most recent call last): + ... + TypeError: g() takes at least 1 argument (0 given) + + >>> g(*(), **{}) + Traceback (most recent call last): + ... + TypeError: g() takes at least 1 argument (0 given) + + >>> g(1) + 1 () {} + >>> g(1, 2) + 1 (2,) {} + >>> g(1, 2, 3) + 1 (2, 3) {} + >>> g(1, 2, 3, *(4, 5)) + 1 (2, 3, 4, 5) {} + + >>> class Nothing: pass + ... + >>> g(*Nothing()) + Traceback (most recent call last): + ... + TypeError: g() argument after * must be a sequence, not instance + + >>> class Nothing: + ... def __len__(self): return 5 + ... + + >>> g(*Nothing()) + Traceback (most recent call last): + ... + TypeError: g() argument after * must be a sequence, not instance + + >>> class Nothing(): + ... def __len__(self): return 5 + ... def __getitem__(self, i): + ... if i<3: return i + ... else: raise IndexError(i) + ... + + >>> g(*Nothing()) + 0 (1, 2) {} + + >>> class Nothing: + ... def __init__(self): self.c = 0 + ... def __iter__(self): return self + ... def next(self): + ... if self.c == 4: + ... raise StopIteration + ... c = self.c + ... self.c += 1 + ... return c + ... + + >>> g(*Nothing()) + 0 (1, 2, 3) {} + +Make sure that the function doesn't stomp the dictionary + + >>> d = {'a': 1, 'b': 2, 'c': 3} + >>> d2 = d.copy() + >>> g(1, d=4, **d) + 1 () {'a': 1, 'b': 2, 'c': 3, 'd': 4} + >>> d == d2 + True + +What about willful misconduct? + + >>> def saboteur(**kw): + ... kw['x'] = 'm' + ... return kw + + >>> d = {} + >>> kw = saboteur(a=1, **d) + >>> d + {} + + + >>> g(1, 2, 3, **{'x': 4, 'y': 5}) + Traceback (most recent call last): + ... + TypeError: g() got multiple values for keyword argument 'x' + + >>> f(**{1:2}) + Traceback (most recent call last): + ... + TypeError: f() keywords must be strings + + >>> h(**{'e': 2}) + Traceback (most recent call last): + ... + TypeError: h() got an unexpected keyword argument 'e' + + >>> h(*h) + Traceback (most recent call last): + ... + TypeError: h() argument after * must be a sequence, not function + + >>> dir(*h) + Traceback (most recent call last): + ... + TypeError: dir() argument after * must be a sequence, not function + + >>> None(*h) + Traceback (most recent call last): + ... + TypeError: NoneType object argument after * must be a sequence, \ +not function + + >>> h(**h) + Traceback (most recent call last): + ... + TypeError: h() argument after ** must be a mapping, not function + + >>> dir(**h) + Traceback (most recent call last): + ... + TypeError: dir() argument after ** must be a mapping, not function + + >>> None(**h) + Traceback (most recent call last): + ... + TypeError: NoneType object argument after ** must be a mapping, \ +not function + + >>> dir(b=1, **{'b': 1}) + Traceback (most recent call last): + ... + TypeError: dir() got multiple values for keyword argument 'b' + +Another helper function + + >>> def f2(*a, **b): + ... return a, b + + + >>> d = {} + >>> for i in xrange(512): + ... key = 'k%d' % i + ... d[key] = i + >>> a, b = f2(1, *(2,3), **d) + >>> len(a), len(b), b == d + (3, 512, True) + + >>> class Foo: + ... def method(self, arg1, arg2): + ... return arg1+arg2 + + >>> x = Foo() + >>> Foo.method(*(x, 1, 2)) + 3 + >>> Foo.method(x, *(1, 2)) + 3 + >>> Foo.method(*(1, 2, 3)) + Traceback (most recent call last): + ... + TypeError: unbound method method() must be called with Foo instance as \ +first argument (got int instance instead) + + >>> Foo.method(1, *[2, 3]) + Traceback (most recent call last): + ... + TypeError: unbound method method() must be called with Foo instance as \ +first argument (got int instance instead) + +A PyCFunction that takes only positional parameters shoud allow an +empty keyword dictionary to pass without a complaint, but raise a +TypeError if te dictionary is not empty + + >>> try: + ... silence = id(1, *{}) + ... True + ... except: + ... False + True + + >>> id(1, **{'foo': 1}) + Traceback (most recent call last): + ... + TypeError: id() takes no keyword arguments + +""" + +from test import test_support + +def test_main(): + import test_extcall # self import + test_support.run_doctest(test_extcall, True) + +if __name__ == '__main__': + test_main() diff --git a/Lib/test/test_parser.py b/Lib/test/test_parser.py index 054d6d2..7269ccb 100644 --- a/Lib/test/test_parser.py +++ b/Lib/test/test_parser.py @@ -1,5 +1,6 @@ import parser import unittest +import sys from test import test_support # @@ -465,6 +466,8 @@ class ParserStackLimitTestCase(unittest.TestCase): def test_trigger_memory_error(self): e = self._nested_expression(100) + print("Expecting 's_push: parser stack overflow' in next line", + file=sys.stderr) self.assertRaises(MemoryError, parser.expr, e) def test_main(): diff --git a/Lib/test/test_pep247.py b/Lib/test/test_pep247.py index 2a2d7ac..fb59d6a 100644 --- a/Lib/test/test_pep247.py +++ b/Lib/test/test_pep247.py @@ -1,56 +1,67 @@ -# -# Test suite to check compliance with PEP 247, the standard API for -# hashing algorithms. -# +""" +Test suite to check compilance with PEP 247, the standard API +for hashing algorithms +""" +import warnings +warnings.filterwarnings('ignore', 'the md5 module is deprecated.*', + DeprecationWarning) +warnings.filterwarnings('ignore', 'the sha module is deprecated.*', + DeprecationWarning) import hmac +import md5 +import sha +import unittest +from test import test_support -import hmac -from test.test_support import verbose - -def check_hash_module(module, key=None): - assert hasattr(module, 'digest_size'), "Must have digest_size" - assert (module.digest_size is None or - module.digest_size > 0), "digest_size must be None or positive" - - if key is not None: - obj1 = module.new(key) - obj2 = module.new(key, b"string") - - h1 = module.new(key, b"string").digest() - obj3 = module.new(key) ; obj3.update(b"string") ; h2 = obj3.digest() - assert h1 == h2, "Hashes must match" - - else: - obj1 = module.new() - obj2 = module.new(b"string") - - h1 = module.new(b"string").digest() - obj3 = module.new() ; obj3.update(b"string") ; h2 = obj3.digest() - assert h1 == h2, "Hashes must match" - - assert hasattr(obj1, 'digest_size'), "Objects must have digest_size attr" - if module.digest_size is not None: - assert obj1.digest_size == module.digest_size, "digest_size must match" - assert obj1.digest_size == len(h1), "digest_size must match actual size" - obj1.update(b"string") - obj_copy = obj1.copy() - assert obj1.digest() == obj_copy.digest(), "Copied objects must match" - assert obj1.hexdigest() == obj_copy.hexdigest(), \ - "Copied objects must match" - digest, hexdigest = obj1.digest(), obj1.hexdigest() - hd2 = "" - for byte in digest: - hd2 += "%02x" % byte - assert hd2 == hexdigest, "hexdigest doesn't appear correct" - - if verbose: - print('Module', module.__name__, 'seems to comply with PEP 247') +class Pep247Test(unittest.TestCase): + def check_module(self, module, key=None): + self.assert_(hasattr(module, 'digest_size')) + self.assert_(module.digest_size is None or module.digest_size > 0) + if not key is None: + obj1 = module.new(key) + obj2 = module.new(key, 'string') + h1 = module.new(key, 'string').digest() + obj3 = module.new(key) + obj3.update('string') + h2 = obj3.digest() + else: + obj1 = module.new() + obj2 = module.new('string') + h1 = module.new('string').digest() + obj3 = module.new() + obj3.update('string') + h2 = obj3.digest() + self.assertEquals(h1, h2) + self.assert_(hasattr(obj1, 'digest_size')) -def test_main(): - check_hash_module(hmac, key=b'abc') + if not module.digest_size is None: + self.assertEquals(obj1.digest_size, module.digest_size) + + self.assertEquals(obj1.digest_size, len(h1)) + obj1.update('string') + obj_copy = obj1.copy() + self.assertEquals(obj1.digest(), obj_copy.digest()) + self.assertEquals(obj1.hexdigest(), obj_copy.hexdigest()) + + digest, hexdigest = obj1.digest(), obj1.hexdigest() + hd2 = "" + for byte in digest: + hd2 += '%02x' % ord(byte) + self.assertEquals(hd2, hexdigest) + def test_md5(self): + self.check_module(md5) + + def test_sha(self): + self.check_module(sha) + + def test_hmac(self): + self.check_module(hmac, key='abc') + +def test_main(): + test_support.run_unittest(Pep247Test) if __name__ == '__main__': test_main() diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py index a9d5672..e1c198f5 100644 --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -348,11 +348,11 @@ class SMTPSimTests(TestCase): def testBasic(self): # smoke test - smtp = smtplib.SMTP(HOST, PORT, local_hostname='localhost', timeout=3) + smtp = smtplib.SMTP(HOST, PORT, local_hostname='localhost', timeout=15) smtp.quit() def testEHLO(self): - smtp = smtplib.SMTP(HOST, PORT, local_hostname='localhost', timeout=3) + smtp = smtplib.SMTP(HOST, PORT, local_hostname='localhost', timeout=15) # no features should be present before the EHLO self.assertEqual(smtp.esmtp_features, {}) @@ -373,7 +373,7 @@ class SMTPSimTests(TestCase): smtp.quit() def testVRFY(self): - smtp = smtplib.SMTP(HOST, PORT, local_hostname='localhost', timeout=3) + smtp = smtplib.SMTP(HOST, PORT, local_hostname='localhost', timeout=15) for email, name in sim_users.items(): expected_known = (250, bytes('%s %s' % @@ -388,7 +388,7 @@ class SMTPSimTests(TestCase): smtp.quit() def testEXPN(self): - smtp = smtplib.SMTP(HOST, PORT, local_hostname='localhost', timeout=3) + smtp = smtplib.SMTP(HOST, PORT, local_hostname='localhost', timeout=15) for listname, members in sim_lists.items(): users = [] diff --git a/Lib/test/test_strftime.py b/Lib/test/test_strftime.py index 0870134..5af5a0c 100755 --- a/Lib/test/test_strftime.py +++ b/Lib/test/test_strftime.py @@ -1,158 +1,185 @@ -#! /usr/bin/env python - -# Sanity checker for time.strftime - -import time, calendar, sys, re -from test.test_support import verbose - -def main(): - global verbose - # For C Python, these tests expect C locale, so we try to set that - # explicitly. For Jython, Finn says we need to be in the US locale; my - # understanding is that this is the closest Java gets to C's "C" locale. - # Jython ought to supply an _locale module which Does The Right Thing, but - # this is the best we can do given today's state of affairs. - try: - import java - java.util.Locale.setDefault(java.util.Locale.US) - except ImportError: - # Can't do this first because it will succeed, even in Jython - import locale - locale.setlocale(locale.LC_TIME, 'C') - now = time.time() - strftest(now) - verbose = 0 - # Try a bunch of dates and times, chosen to vary through time of - # day and daylight saving time - for j in range(-5, 5): - for i in range(25): - strftest(now + (i + j*100)*23*3603) +""" +Unittest for time.strftime +""" + +import calendar +import sys +import os +import re +from test import test_support +import time +import unittest + + +# helper functions +def fixasctime(s): + if s[8] == ' ': + s = s[:8] + '0' + s[9:] + return s def escapestr(text, ampm): - """Escape text to deal with possible locale values that have regex - syntax while allowing regex syntax used for the comparison.""" + """ + Escape text to deal with possible locale values that have regex + syntax while allowing regex syntax used for comparison. + """ new_text = re.escape(text) new_text = new_text.replace(re.escape(ampm), ampm) - new_text = new_text.replace("\%", "%") - new_text = new_text.replace("\:", ":") - new_text = new_text.replace("\?", "?") + new_text = new_text.replace('\%', '%') + new_text = new_text.replace('\:', ':') + new_text = new_text.replace('\?', '?') return new_text -def strftest(now): - if verbose: - print("strftime test for", time.ctime(now)) - nowsecs = str(int(now))[:-1] - gmt = time.gmtime(now) - now = time.localtime(now) - - if now[3] < 12: ampm='(AM|am)' - else: ampm='(PM|pm)' - - jan1 = time.localtime(time.mktime((now[0], 1, 1, 0, 0, 0, 0, 1, 0))) - - try: - if now[8]: tz = time.tzname[1] - else: tz = time.tzname[0] - except AttributeError: - tz = '' - - if now[3] > 12: clock12 = now[3] - 12 - elif now[3] > 0: clock12 = now[3] - else: clock12 = 12 - - # Make sure any characters that could be taken as regex syntax is - # escaped in escapestr() - expectations = ( - ('%a', calendar.day_abbr[now[6]], 'abbreviated weekday name'), - ('%A', calendar.day_name[now[6]], 'full weekday name'), - ('%b', calendar.month_abbr[now[1]], 'abbreviated month name'), - ('%B', calendar.month_name[now[1]], 'full month name'), - # %c see below - ('%d', '%02d' % now[2], 'day of month as number (00-31)'), - ('%H', '%02d' % now[3], 'hour (00-23)'), - ('%I', '%02d' % clock12, 'hour (01-12)'), - ('%j', '%03d' % now[7], 'julian day (001-366)'), - ('%m', '%02d' % now[1], 'month as number (01-12)'), - ('%M', '%02d' % now[4], 'minute, (00-59)'), - ('%p', ampm, 'AM or PM as appropriate'), - ('%S', '%02d' % now[5], 'seconds of current time (00-60)'), - ('%U', '%02d' % ((now[7] + jan1[6])//7), - 'week number of the year (Sun 1st)'), - ('%w', '0?%d' % ((1+now[6]) % 7), 'weekday as a number (Sun 1st)'), - ('%W', '%02d' % ((now[7] + (jan1[6] - 1)%7)//7), - 'week number of the year (Mon 1st)'), - # %x see below - ('%X', '%02d:%02d:%02d' % (now[3], now[4], now[5]), '%H:%M:%S'), - ('%y', '%02d' % (now[0]%100), 'year without century'), - ('%Y', '%d' % now[0], 'year with century'), - # %Z see below - ('%%', '%', 'single percent sign'), - ) - nonstandard_expectations = ( - # These are standard but don't have predictable output - ('%c', fixasctime(time.asctime(now)), 'near-asctime() format'), - ('%x', '%02d/%02d/%02d' % (now[1], now[2], (now[0]%100)), - '%m/%d/%y %H:%M:%S'), - ('%Z', '%s' % tz, 'time zone name'), - - # These are some platform specific extensions - ('%D', '%02d/%02d/%02d' % (now[1], now[2], (now[0]%100)), 'mm/dd/yy'), - ('%e', '%2d' % now[2], 'day of month as number, blank padded ( 0-31)'), - ('%h', calendar.month_abbr[now[1]], 'abbreviated month name'), - ('%k', '%2d' % now[3], 'hour, blank padded ( 0-23)'), - ('%n', '\n', 'newline character'), - ('%r', '%02d:%02d:%02d %s' % (clock12, now[4], now[5], ampm), - '%I:%M:%S %p'), - ('%R', '%02d:%02d' % (now[3], now[4]), '%H:%M'), - ('%s', nowsecs, 'seconds since the Epoch in UCT'), - ('%t', '\t', 'tab character'), - ('%T', '%02d:%02d:%02d' % (now[3], now[4], now[5]), '%H:%M:%S'), - ('%3y', '%03d' % (now[0]%100), - 'year without century rendered using fieldwidth'), - ) +class StrftimeTest(unittest.TestCase): - if verbose: - print("Strftime test, platform: %s, Python version: %s" % \ - (sys.platform, sys.version.split()[0])) + def _update_variables(self, now): + # we must update the local variables on every cycle + self.gmt = time.gmtime(now) + now = time.localtime(now) + + if now[3] < 12: self.ampm='(AM|am)' + else: self.ampm='(PM|pm)' + + self.jan1 = time.localtime(time.mktime((now[0], 1, 1, 0, 0, 0, 0, 1, 0))) - for e in expectations: try: - result = time.strftime(e[0], now) - except ValueError as error: - print("Standard '%s' format gave error:" % e[0], error) - continue - if re.match(escapestr(e[1], ampm), result): continue - if not result or result[0] == '%': - print("Does not support standard '%s' format (%s)" % (e[0], e[2])) - else: - print("Conflict for %s (%s):" % (e[0], e[2])) - print(" Expected %s, but got %s" % (e[1], result)) - - for e in nonstandard_expectations: + if now[8]: self.tz = time.tzname[1] + else: self.tz = time.tzname[0] + except AttributeError: + self.tz = '' + + if now[3] > 12: self.clock12 = now[3] - 12 + elif now[3] > 0: self.clock12 = now[3] + else: self.clock12 = 12 + + self.now = now + + def setUp(self): try: - result = time.strftime(e[0], now) - except ValueError as result: - if verbose: - print("Error for nonstandard '%s' format (%s): %s" % \ - (e[0], e[2], str(result))) - continue - if re.match(escapestr(e[1], ampm), result): - if verbose: - print("Supports nonstandard '%s' format (%s)" % (e[0], e[2])) - elif not result or result[0] == '%': - if verbose: - print("Does not appear to support '%s' format (%s)" % (e[0], - e[2])) - else: - if verbose: - print("Conflict for nonstandard '%s' format (%s):" % (e[0], - e[2])) + import java + java.util.Locale.setDefault(java.util.Locale.US) + except ImportError: + import locale + locale.setlocale(locale.LC_TIME, 'C') + + def test_strftime(self): + now = time.time() + self._update_variables(now) + self.strftest1(now) + self.strftest2(now) + + if test_support.verbose: + print("Strftime test, platform: %s, Python version: %s" % \ + (sys.platform, sys.version.split()[0])) + + for j in range(-5, 5): + for i in range(25): + arg = now + (i+j*100)*23*3603 + self._update_variables(arg) + self.strftest1(arg) + self.strftest2(arg) + + def strftest1(self, now): + if test_support.verbose: + print("strftime test for", time.ctime(now)) + now = self.now + # Make sure any characters that could be taken as regex syntax is + # escaped in escapestr() + expectations = ( + ('%a', calendar.day_abbr[now[6]], 'abbreviated weekday name'), + ('%A', calendar.day_name[now[6]], 'full weekday name'), + ('%b', calendar.month_abbr[now[1]], 'abbreviated month name'), + ('%B', calendar.month_name[now[1]], 'full month name'), + # %c see below + ('%d', '%02d' % now[2], 'day of month as number (00-31)'), + ('%H', '%02d' % now[3], 'hour (00-23)'), + ('%I', '%02d' % self.clock12, 'hour (01-12)'), + ('%j', '%03d' % now[7], 'julian day (001-366)'), + ('%m', '%02d' % now[1], 'month as number (01-12)'), + ('%M', '%02d' % now[4], 'minute, (00-59)'), + ('%p', self.ampm, 'AM or PM as appropriate'), + ('%S', '%02d' % now[5], 'seconds of current time (00-60)'), + ('%U', '%02d' % ((now[7] + self.jan1[6])//7), + 'week number of the year (Sun 1st)'), + ('%w', '0?%d' % ((1+now[6]) % 7), 'weekday as a number (Sun 1st)'), + ('%W', '%02d' % ((now[7] + (self.jan1[6] - 1)%7)//7), + 'week number of the year (Mon 1st)'), + # %x see below + ('%X', '%02d:%02d:%02d' % (now[3], now[4], now[5]), '%H:%M:%S'), + ('%y', '%02d' % (now[0]%100), 'year without century'), + ('%Y', '%d' % now[0], 'year with century'), + # %Z see below + ('%%', '%', 'single percent sign'), + ) + + for e in expectations: + # musn't raise a value error + try: + result = time.strftime(e[0], now) + except ValueError as error: + print("Standard '%s' format gaver error:" % (e[0], error)) + continue + if re.match(escapestr(e[1], self.ampm), result): + continue + if not result or result[0] == '%': + print("Does not support standard '%s' format (%s)" % \ + (e[0], e[2])) + else: + print("Conflict for %s (%s):" % (e[0], e[2])) print(" Expected %s, but got %s" % (e[1], result)) -def fixasctime(s): - if s[8] == ' ': - s = s[:8] + '0' + s[9:] - return s + def strftest2(self, now): + nowsecs = str(int(now))[:-1] + now = self.now + + nonstandard_expectations = ( + # These are standard but don't have predictable output + ('%c', fixasctime(time.asctime(now)), 'near-asctime() format'), + ('%x', '%02d/%02d/%02d' % (now[1], now[2], (now[0]%100)), + '%m/%d/%y %H:%M:%S'), + ('%Z', '%s' % self.tz, 'time zone name'), + + # These are some platform specific extensions + ('%D', '%02d/%02d/%02d' % (now[1], now[2], (now[0]%100)), 'mm/dd/yy'), + ('%e', '%2d' % now[2], 'day of month as number, blank padded ( 0-31)'), + ('%h', calendar.month_abbr[now[1]], 'abbreviated month name'), + ('%k', '%2d' % now[3], 'hour, blank padded ( 0-23)'), + ('%n', '\n', 'newline character'), + ('%r', '%02d:%02d:%02d %s' % (self.clock12, now[4], now[5], self.ampm), + '%I:%M:%S %p'), + ('%R', '%02d:%02d' % (now[3], now[4]), '%H:%M'), + ('%s', nowsecs, 'seconds since the Epoch in UCT'), + ('%t', '\t', 'tab character'), + ('%T', '%02d:%02d:%02d' % (now[3], now[4], now[5]), '%H:%M:%S'), + ('%3y', '%03d' % (now[0]%100), + 'year without century rendered using fieldwidth'), + ) + -main() + for e in nonstandard_expectations: + try: + result = time.strftime(e[0], now) + except ValueError as result: + msg = "Error for nonstandard '%s' format (%s): %s" % \ + (e[0], e[2], str(result)) + if test_support.verbose: + print(msg) + continue + if re.match(escapestr(e[1], self.ampm), result): + if test_support.verbose: + print("Supports nonstandard '%s' format (%s)" % (e[0], e[2])) + elif not result or result[0] == '%': + if test_support.verbose: + print("Does not appear to support '%s' format (%s)" % \ + (e[0], e[2])) + else: + if test_support.verbose: + print("Conflict for nonstandard '%s' format (%s):" % \ + (e[0], e[2])) + print(" Expected %s, but got %s" % (e[1], result)) + +def test_main(): + test_support.run_unittest(StrftimeTest) + +if __name__ == '__main__': + test_main() diff --git a/Lib/test/test_thread.py b/Lib/test/test_thread.py index c89c5a1..01d6655 100644 --- a/Lib/test/test_thread.py +++ b/Lib/test/test_thread.py @@ -9,10 +9,13 @@ import time NUMTASKS = 10 NUMTRIPS = 3 +_print_mutex = thread.allocate_lock() + def verbose_print(arg): """Helper function for printing out debugging output.""" if test_support.verbose: - print(arg) + with _print_mutex: + print(arg) class BasicThreadTest(unittest.TestCase): @@ -36,8 +39,8 @@ class ThreadRunningTests(BasicThreadTest): def task(self, ident): with self.random_mutex: - delay = random.random() * NUMTASKS - verbose_print("task %s will run for %s" % (ident, round(delay, 1))) + delay = random.random() / 10000.0 + verbose_print("task %s will run for %sus" % (ident, round(delay*1e6))) time.sleep(delay) verbose_print("task %s done" % ident) with self.running_mutex: @@ -136,11 +139,12 @@ class BarrierTest(BasicThreadTest): # give it a good chance to enter the next # barrier before the others are all out # of the current one - delay = 0.001 + delay = 0 else: with self.random_mutex: - delay = random.random() * NUMTASKS - verbose_print("task %s will run for %s" % (ident, round(delay, 1))) + delay = random.random() / 10000.0 + verbose_print("task %s will run for %sus" % + (ident, round(delay * 1e6))) time.sleep(delay) verbose_print("task %s entering %s" % (ident, i)) self.bar.enter() diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index 654bc11..dae250e 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -451,6 +451,15 @@ class TypesTests(unittest.TestCase): test(1.1234e20, 'e', '1.123400e+20') test(1.1234e20, 'E', '1.123400E+20') + # No format code means use g, but must have a decimal + # and a number after the decimal. This is tricky, because + # a totaly empty format specifier means something else. + # So, just use a sign flag + test(1e200, '+g', '+1e+200') + test(1e200, '+', '+1.0e+200') + test(1.1e200, '+g', '+1.1e+200') + test(1.1e200, '+', '+1.1e+200') + # % formatting test(-1.0, '%', '-100.000000%') diff --git a/Lib/test/test_winsound.py b/Lib/test/test_winsound.py index 0d6ddf9..7cdc275 100644 --- a/Lib/test/test_winsound.py +++ b/Lib/test/test_winsound.py @@ -27,8 +27,16 @@ class BeepTest(unittest.TestCase): winsound.Beep(37, 75) winsound.Beep(32767, 75) else: - self.assertRaises(RuntimeError, winsound.Beep, 37, 75) - self.assertRaises(RuntimeError, winsound.Beep, 32767, 75) + # The behaviour of winsound.Beep() seems to differ between + # different versions of Windows when there's either a) no + # sound card entirely, b) legacy beep driver has been disabled, + # or c) the legacy beep driver has been uninstalled. Sometimes + # RuntimeErrors are raised, sometimes they're not. Meh. + try: + winsound.Beep(37, 75) + winsound.Beep(32767, 75) + except RuntimeError: + pass def test_increasingfrequency(self): if _have_soundcard(): diff --git a/Lib/test/test_zlib.py b/Lib/test/test_zlib.py index 6b7d4a6..0adf507 100644 --- a/Lib/test/test_zlib.py +++ b/Lib/test/test_zlib.py @@ -48,6 +48,7 @@ class ChecksumTestCase(unittest.TestCase): + class ExceptionTestCase(unittest.TestCase): # make sure we generate some expected errors def test_badlevel(self): |