mirror of
https://github.com/python/cpython.git
synced 2025-08-24 10:45:53 +00:00
bpo-37903: IDLE: Shell sidebar with prompts (GH-22682)
The first followup will change shell indents to spaces. More are expected. Co-authored-by: Terry Jan Reedy <tjreedy@udel.edu>
This commit is contained in:
parent
103d5e420d
commit
15d3861856
14 changed files with 888 additions and 132 deletions
56
Lib/idlelib/idle_test/tkinter_testing_utils.py
Normal file
56
Lib/idlelib/idle_test/tkinter_testing_utils.py
Normal file
|
@ -0,0 +1,56 @@
|
|||
"""Utilities for testing with Tkinter"""
|
||||
import functools
|
||||
|
||||
|
||||
def run_in_tk_mainloop(test_method):
|
||||
"""Decorator for running a test method with a real Tk mainloop.
|
||||
|
||||
This starts a Tk mainloop before running the test, and stops it
|
||||
at the end. This is faster and more robust than the common
|
||||
alternative method of calling .update() and/or .update_idletasks().
|
||||
|
||||
Test methods using this must be written as generator functions,
|
||||
using "yield" to allow the mainloop to process events and "after"
|
||||
callbacks, and then continue the test from that point.
|
||||
|
||||
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
|
||||
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()
|
||||
|
||||
if exception:
|
||||
raise exception
|
||||
|
||||
return new_test_method
|
Loading…
Add table
Add a link
Reference in a new issue