cpython: d7a64e095930 (original) (raw)
--- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -550,16 +550,7 @@ def main(tests=None, testdir=None, verbo from subprocess import Popen, PIPE debug_output_pat = re.compile(r"[\d+ refs]$") output = Queue()
def tests_and_args():[](#l1.7)
for test in tests:[](#l1.8)
args_tuple = ([](#l1.9)
(test, verbose, quiet),[](#l1.10)
dict(huntrleaks=huntrleaks, use_resources=use_resources,[](#l1.11)
debug=debug, output_on_failure=verbose3,[](#l1.12)
failfast=failfast, match_tests=match_tests)[](#l1.13)
)[](#l1.14)
yield (test, args_tuple)[](#l1.15)
pending = tests_and_args()[](#l1.16)
pending = MultiprocessTests(tests)[](#l1.17) opt_args = support.args_from_interpreter_flags()[](#l1.18) base_cmd = [sys.executable] + opt_args + ['-m', 'test.regrtest'][](#l1.19) def work():[](#l1.20)
@@ -567,10 +558,16 @@ def main(tests=None, testdir=None, verbo try: while True: try:
test, args_tuple = next(pending)[](#l1.25)
test = next(pending)[](#l1.26) except StopIteration:[](#l1.27) output.put((None, None, None, None))[](#l1.28) return[](#l1.29)
args_tuple = ([](#l1.30)
(test, verbose, quiet),[](#l1.31)
dict(huntrleaks=huntrleaks, use_resources=use_resources,[](#l1.32)
debug=debug, output_on_failure=verbose3,[](#l1.33)
failfast=failfast, match_tests=match_tests)[](#l1.34)
)[](#l1.35) # -E is needed by some tests, e.g. test_import[](#l1.36) # Running the child from the same working directory ensures[](#l1.37) # that TEMPDIR for the child is the same when[](#l1.38)
@@ -622,7 +619,7 @@ def main(tests=None, testdir=None, verbo test_index += 1 except KeyboardInterrupt: interrupted = True
pending.close()[](#l1.43)
else: @@ -766,6 +763,25 @@ def findtests(testdir=None, stdtests=STD tests.append(modname) return stdtests + sorted(tests) +# We do not use a generator so multiple threads can call next(). +class MultiprocessTests(object): +pending.interrupted = True[](#l1.44) for worker in workers:[](#l1.45) worker.join()[](#l1.46)
- """A thread-safe iterator over tests for multiprocess mode."""
- def init(self, tests):
self.interrupted = False[](#l1.58)
self.lock = threading.Lock()[](#l1.59)
self.tests = tests[](#l1.60)
- def next(self):
with self.lock:[](#l1.66)
if self.interrupted:[](#l1.67)
raise StopIteration('tests interrupted')[](#l1.68)
return next(self.tests)[](#l1.69)
+ def replace_stdout(): """Set stdout encoder error handler to backslashreplace (as stderr error handler) to avoid UnicodeEncodeError when printing a traceback"""
--- a/Misc/NEWS +++ b/Misc/NEWS @@ -378,6 +378,9 @@ Extension Modules Tests ----- +- Issue #15320: Make iterating the list of tests thread-safe when running