bpo-30495: IDLE: Modernize textview.py with docstrings and PEP8 names (#1839) (#2102)

Patch by Cheryl Sabella.
(cherry picked from commit 0aa0a06e8b)
This commit is contained in:
terryjreedy 2017-06-11 04:16:55 -04:00 committed by GitHub
parent c0ef607c52
commit ccccf3156f
3 changed files with 61 additions and 41 deletions

View File

@ -45,10 +45,10 @@ class LiveDialogTest(unittest.TestCase):
button.invoke() button.invoke()
self.assertEqual( self.assertEqual(
printer._Printer__lines[0], printer._Printer__lines[0],
dialog._current_textview.textView.get('1.0', '1.end')) dialog._current_textview.text.get('1.0', '1.end'))
self.assertEqual( self.assertEqual(
printer._Printer__lines[1], printer._Printer__lines[1],
dialog._current_textview.textView.get('2.0', '2.end')) dialog._current_textview.text.get('2.0', '2.end'))
dialog._current_textview.destroy() dialog._current_textview.destroy()
def test_file_buttons(self): def test_file_buttons(self):
@ -64,10 +64,11 @@ class LiveDialogTest(unittest.TestCase):
with open(fn) as f: with open(fn) as f:
self.assertEqual( self.assertEqual(
f.readline().strip(), f.readline().strip(),
dialog._current_textview.textView.get('1.0', '1.end')) dialog._current_textview.text.get('1.0', '1.end'))
f.readline() f.readline()
self.assertEqual(f.readline().strip(), self.assertEqual(
dialog._current_textview.textView.get('3.0', '3.end')) f.readline().strip(),
dialog._current_textview.text.get('3.0', '3.end'))
dialog._current_textview.destroy() dialog._current_textview.destroy()

View File

@ -41,7 +41,7 @@ class TV(tv.TextViewer): # Used in TextViewTest.
# Call wrapper class with mock wait_window. # Call wrapper class with mock wait_window.
class TextViewTest(unittest.TestCase): class TextViewTest(unittest.TestCase):
def setUp(self): def setUp(self):
TV.transient.__init__() TV.transient.__init__()
TV.grab_set.__init__() TV.grab_set.__init__()
@ -52,19 +52,19 @@ class TextViewTest(unittest.TestCase):
self.assertTrue(TV.transient.called) self.assertTrue(TV.transient.called)
self.assertTrue(TV.grab_set.called) self.assertTrue(TV.grab_set.called)
self.assertTrue(TV.wait_window.called) self.assertTrue(TV.wait_window.called)
view.Ok() view.ok()
def test_init_nonmodal(self): def test_init_nonmodal(self):
view = TV(root, 'Title', 'test text', modal=False) view = TV(root, 'Title', 'test text', modal=False)
self.assertFalse(TV.transient.called) self.assertFalse(TV.transient.called)
self.assertFalse(TV.grab_set.called) self.assertFalse(TV.grab_set.called)
self.assertFalse(TV.wait_window.called) self.assertFalse(TV.wait_window.called)
view.Ok() view.ok()
def test_ok(self): def test_ok(self):
view = TV(root, 'Title', 'test text', modal=False) view = TV(root, 'Title', 'test text', modal=False)
view.destroy = Func() view.destroy = Func()
view.Ok() view.ok()
self.assertTrue(view.destroy.called) self.assertTrue(view.destroy.called)
del view.destroy # Unmask real function. del view.destroy # Unmask real function.
view.destroy() view.destroy()
@ -86,13 +86,13 @@ class ViewFunctionTest(unittest.TestCase):
def test_view_text(self): def test_view_text(self):
view = tv.view_text(root, 'Title', 'test text', modal=False) view = tv.view_text(root, 'Title', 'test text', modal=False)
self.assertIsInstance(view, tv.TextViewer) self.assertIsInstance(view, tv.TextViewer)
view.Ok() view.ok()
def test_view_file(self): def test_view_file(self):
view = tv.view_file(root, 'Title', __file__, modal=False) view = tv.view_file(root, 'Title', __file__, modal=False)
self.assertIsInstance(view, tv.TextViewer) self.assertIsInstance(view, tv.TextViewer)
self.assertIn('Test', view.textView.get('1.0', '1.end')) self.assertIn('Test', view.text.get('1.0', '1.end'))
view.Ok() view.ok()
def test_bad_file(self): def test_bad_file(self):
# Mock showerror will be used; view_file will return None. # Mock showerror will be used; view_file will return None.
@ -131,7 +131,7 @@ class ButtonClickTest(unittest.TestCase):
self.assertEqual(self.called, True) self.assertEqual(self.called, True)
self.assertEqual(self.view.title(), 'TITLE_TEXT') self.assertEqual(self.view.title(), 'TITLE_TEXT')
self.assertEqual(self.view.textView.get('1.0', '1.end'), 'COMMAND') self.assertEqual(self.view.text.get('1.0', '1.end'), 'COMMAND')
def test_view_file_bind_with_button(self): def test_view_file_bind_with_button(self):
def _command(): def _command():
@ -144,10 +144,10 @@ class ButtonClickTest(unittest.TestCase):
self.assertEqual(self.called, True) self.assertEqual(self.called, True)
self.assertEqual(self.view.title(), 'TITLE_FILE') self.assertEqual(self.view.title(), 'TITLE_FILE')
with open(__file__) as f: with open(__file__) as f:
self.assertEqual(self.view.textView.get('1.0', '1.end'), self.assertEqual(self.view.text.get('1.0', '1.end'),
f.readline().strip()) f.readline().strip())
f.readline() f.readline()
self.assertEqual(self.view.textView.get('3.0', '3.end'), self.assertEqual(self.view.text.get('3.0', '3.end'),
f.readline().strip()) f.readline().strip())

View File

@ -1,7 +1,9 @@
"""Simple text browser for IDLE """Simple text browser for IDLE
""" """
from tkinter import * from tkinter import Toplevel, Frame, Button, Text
from tkinter import DISABLED, SUNKEN, VERTICAL, WORD
from tkinter import RIGHT, LEFT, TOP, BOTTOM, BOTH, X, Y
from tkinter.ttk import Scrollbar from tkinter.ttk import Scrollbar
from tkinter.messagebox import showerror from tkinter.messagebox import showerror
@ -16,6 +18,9 @@ class TextViewer(Toplevel):
If modal is left True, users cannot interact with other windows If modal is left True, users cannot interact with other windows
until the textview window is closed. until the textview window is closed.
parent - parent of this dialog
title - string which is title of popup dialog
text - text to display in dialog
_htest - bool; change box location when running htest. _htest - bool; change box location when running htest.
_utest - bool; don't wait_window when running unittest. _utest - bool; don't wait_window when running unittest.
""" """
@ -29,16 +34,16 @@ class TextViewer(Toplevel):
self.bg = '#ffffff' self.bg = '#ffffff'
self.fg = '#000000' self.fg = '#000000'
self.CreateWidgets() self.create_widgets()
self.title(title) self.title(title)
self.protocol("WM_DELETE_WINDOW", self.Ok) self.protocol("WM_DELETE_WINDOW", self.ok)
self.parent = parent self.parent = parent
self.textView.focus_set() self.text.focus_set()
# Bind keys for closing this dialog. # Bind keys for closing this dialog.
self.bind('<Return>',self.Ok) self.bind('<Return>', self.ok)
self.bind('<Escape>',self.Ok) self.bind('<Escape>', self.ok)
self.textView.insert(0.0, text) self.text.insert(0.0, text)
self.textView.config(state=DISABLED) self.text.config(state=DISABLED)
if modal: if modal:
self.transient(parent) self.transient(parent)
@ -46,34 +51,48 @@ class TextViewer(Toplevel):
if not _utest: if not _utest:
self.wait_window() self.wait_window()
def CreateWidgets(self): def create_widgets(self):
"Create Frame with Text (with vertical Scrollbar) and Button." "Create Frame with Text (with vertical Scrollbar) and Button."
frameText = Frame(self, relief=SUNKEN, height=700) frame = Frame(self, relief=SUNKEN, height=700)
frameButtons = Frame(self) frame_buttons = Frame(self)
self.buttonOk = Button(frameButtons, text='Close', self.button_ok = Button(frame_buttons, text='Close',
command=self.Ok, takefocus=FALSE) command=self.ok, takefocus=False)
self.scrollbarView = Scrollbar(frameText, orient=VERTICAL, self.scrollbar = Scrollbar(frame, orient=VERTICAL, takefocus=False)
takefocus=FALSE) self.text = Text(frame, wrap=WORD, highlightthickness=0,
self.textView = Text(frameText, wrap=WORD, highlightthickness=0,
fg=self.fg, bg=self.bg) fg=self.fg, bg=self.bg)
self.scrollbarView.config(command=self.textView.yview) self.scrollbar.config(command=self.text.yview)
self.textView.config(yscrollcommand=self.scrollbarView.set) self.text.config(yscrollcommand=self.scrollbar.set)
self.buttonOk.pack()
self.scrollbarView.pack(side=RIGHT,fill=Y) self.button_ok.pack()
self.textView.pack(side=LEFT,expand=TRUE,fill=BOTH) self.scrollbar.pack(side=RIGHT, fill=Y)
frameButtons.pack(side=BOTTOM,fill=X) self.text.pack(side=LEFT, expand=True, fill=BOTH)
frameText.pack(side=TOP,expand=TRUE,fill=BOTH) frame_buttons.pack(side=BOTTOM, fill=X)
frame.pack(side=TOP, expand=True, fill=BOTH)
def Ok(self, event=None): def ok(self, event=None):
"""Dismiss text viewer dialog."""
self.destroy() self.destroy()
def view_text(parent, title, text, modal=True, _utest=False): def view_text(parent, title, text, modal=True, _utest=False):
"Display text in a TextViewer." """Create TextViewer for given text.
parent - parent of this dialog
title - string which is the title of popup dialog
text - text to display in this dialog
modal - controls if users can interact with other windows while this
dialog is displayed
_utest - bool; controls wait_window on unittest
"""
return TextViewer(parent, title, text, modal, _utest=_utest) return TextViewer(parent, title, text, modal, _utest=_utest)
def view_file(parent, title, filename, encoding=None, modal=True, _utest=False): def view_file(parent, title, filename, encoding=None, modal=True, _utest=False):
"Display file in a TextViever or show error message." """Create TextViewer for text in filename.
Return error message if file cannot be read. Otherwise calls view_text
with contents of the file.
"""
try: try:
with open(filename, 'r', encoding=encoding) as file: with open(filename, 'r', encoding=encoding) as file:
contents = file.read() contents = file.read()