mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
bpo-44282: Fix occasional test_incremental_editing failures on buildbots (GH-26491)
Signed-off-by: Tal Einat <532281+taleinat@users.noreply.github.com>
This commit is contained in:
parent
320eaa7f42
commit
adef445dc3
3 changed files with 47 additions and 41 deletions
|
@ -2,7 +2,7 @@
|
|||
import functools
|
||||
|
||||
|
||||
def run_in_tk_mainloop(test_method):
|
||||
def run_in_tk_mainloop(delay=1):
|
||||
"""Decorator for running a test method with a real Tk mainloop.
|
||||
|
||||
This starts a Tk mainloop before running the test, and stops it
|
||||
|
@ -13,44 +13,50 @@ def run_in_tk_mainloop(test_method):
|
|||
using "yield" to allow the mainloop to process events and "after"
|
||||
callbacks, and then continue the test from that point.
|
||||
|
||||
The delay argument is passed into root.after(...) calls as the number
|
||||
of ms to wait before passing execution back to the generator function.
|
||||
|
||||
This also assumes that the test class has a .root attribute,
|
||||
which is a tkinter.Tk object.
|
||||
|
||||
For example (from test_sidebar.py):
|
||||
|
||||
@run_test_with_tk_mainloop
|
||||
@run_test_with_tk_mainloop()
|
||||
def test_single_empty_input(self):
|
||||
self.do_input('\n')
|
||||
yield
|
||||
self.assert_sidebar_lines_end_with(['>>>', '>>>'])
|
||||
"""
|
||||
@functools.wraps(test_method)
|
||||
def new_test_method(self):
|
||||
test_generator = test_method(self)
|
||||
root = self.root
|
||||
# Exceptions raised by self.assert...() need to be raised
|
||||
# outside of the after() callback in order for the test
|
||||
# harness to capture them.
|
||||
exception = None
|
||||
def after_callback():
|
||||
nonlocal exception
|
||||
try:
|
||||
next(test_generator)
|
||||
except StopIteration:
|
||||
root.quit()
|
||||
except Exception as exc:
|
||||
exception = exc
|
||||
root.quit()
|
||||
else:
|
||||
# Schedule the Tk mainloop to call this function again,
|
||||
# using a robust method of ensuring that it gets a
|
||||
# chance to process queued events before doing so.
|
||||
# See: https://stackoverflow.com/q/18499082#comment65004099_38817470
|
||||
root.after(1, root.after_idle, after_callback)
|
||||
root.after(0, root.after_idle, after_callback)
|
||||
root.mainloop()
|
||||
def decorator(test_method):
|
||||
@functools.wraps(test_method)
|
||||
def new_test_method(self):
|
||||
test_generator = test_method(self)
|
||||
root = self.root
|
||||
# Exceptions raised by self.assert...() need to be raised
|
||||
# outside of the after() callback in order for the test
|
||||
# harness to capture them.
|
||||
exception = None
|
||||
def after_callback():
|
||||
nonlocal exception
|
||||
try:
|
||||
next(test_generator)
|
||||
except StopIteration:
|
||||
root.quit()
|
||||
except Exception as exc:
|
||||
exception = exc
|
||||
root.quit()
|
||||
else:
|
||||
# Schedule the Tk mainloop to call this function again,
|
||||
# using a robust method of ensuring that it gets a
|
||||
# chance to process queued events before doing so.
|
||||
# See: https://stackoverflow.com/q/18499082#comment65004099_38817470
|
||||
root.after(delay, root.after_idle, after_callback)
|
||||
root.after(0, root.after_idle, after_callback)
|
||||
root.mainloop()
|
||||
|
||||
if exception:
|
||||
raise exception
|
||||
if exception:
|
||||
raise exception
|
||||
|
||||
return new_test_method
|
||||
return new_test_method
|
||||
|
||||
return decorator
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue