summaryrefslogtreecommitdiffstats
path: root/Lib/idlelib/GrepDialog.py
diff options
context:
space:
mode:
authorTerry Jan Reedy <tjreedy@udel.edu>2014-06-10 06:49:35 (GMT)
committerTerry Jan Reedy <tjreedy@udel.edu>2014-06-10 06:49:35 (GMT)
commit4762382d6346abdef810cdf0a6101cbc1ec5952e (patch)
treecb040aa8cef53b45a0f352c27c8423d415c96908 /Lib/idlelib/GrepDialog.py
parent6ceca4e3d850ef2ba81d5f51aac3fe6c0c85284e (diff)
downloadcpython-4762382d6346abdef810cdf0a6101cbc1ec5952e.zip
cpython-4762382d6346abdef810cdf0a6101cbc1ec5952e.tar.gz
cpython-4762382d6346abdef810cdf0a6101cbc1ec5952e.tar.bz2
Issue #21695: Catch AttributeError created when user closes grep output window
while still being written to. With no console, this closed Idle. Also add missing import and a few other changes.
Diffstat (limited to 'Lib/idlelib/GrepDialog.py')
-rw-r--r--Lib/idlelib/GrepDialog.py49
1 files changed, 29 insertions, 20 deletions
diff --git a/Lib/idlelib/GrepDialog.py b/Lib/idlelib/GrepDialog.py
index 324c1a7f..38b6480 100644
--- a/Lib/idlelib/GrepDialog.py
+++ b/Lib/idlelib/GrepDialog.py
@@ -1,9 +1,14 @@
import os
import fnmatch
+import re # for htest
import sys
-from tkinter import *
+from tkinter import StringVar, BooleanVar, Checkbutton # for GrepDialog
+from tkinter import Tk, Text, Button, SEL, END # for htest
from idlelib import SearchEngine
+import itertools
from idlelib.SearchDialogBase import SearchDialogBase
+# Importing OutputWindow fails due to import loop
+# EditorWindow -> GrepDialop -> OutputWindow -> EditorWindow
def grep(text, io=None, flist=None):
root = text._root()
@@ -63,7 +68,7 @@ class GrepDialog(SearchDialogBase):
if not path:
self.top.bell()
return
- from idlelib.OutputWindow import OutputWindow
+ from idlelib.OutputWindow import OutputWindow # leave here!
save = sys.stdout
try:
sys.stdout = OutputWindow(self.flist)
@@ -79,21 +84,26 @@ class GrepDialog(SearchDialogBase):
pat = self.engine.getpat()
print("Searching %r in %s ..." % (pat, path))
hits = 0
- for fn in list:
- try:
- with open(fn, errors='replace') as f:
- for lineno, line in enumerate(f, 1):
- if line[-1:] == '\n':
- line = line[:-1]
- if prog.search(line):
- sys.stdout.write("%s: %s: %s\n" %
- (fn, lineno, line))
- hits += 1
- except OSError as msg:
- print(msg)
- print(("Hits found: %s\n"
- "(Hint: right-click to open locations.)"
- % hits) if hits else "No hits.")
+ try:
+ for fn in list:
+ try:
+ with open(fn, errors='replace') as f:
+ for lineno, line in enumerate(f, 1):
+ if line[-1:] == '\n':
+ line = line[:-1]
+ if prog.search(line):
+ sys.stdout.write("%s: %s: %s\n" %
+ (fn, lineno, line))
+ hits += 1
+ except OSError as msg:
+ print(msg)
+ print(("Hits found: %s\n"
+ "(Hint: right-click to open locations.)"
+ % hits) if hits else "No hits.")
+ except AttributeError:
+ # Tk window has been closed, OutputWindow.text = None,
+ # so in OW.write, OW.text.insert fails.
+ pass
def findfiles(self, dir, base, rec):
try:
@@ -120,7 +130,8 @@ class GrepDialog(SearchDialogBase):
self.top.grab_release()
self.top.withdraw()
-def _grep_dialog(parent):
+
+def _grep_dialog(parent): # for htest
from idlelib.PyShell import PyShellFileList
root = Tk()
root.title("Test GrepDialog")
@@ -141,8 +152,6 @@ def _grep_dialog(parent):
root.mainloop()
if __name__ == "__main__":
- # A human test is a bit tricky since EditorWindow() imports this module.
- # Hence Idle must be restarted after editing this file for a live test.
import unittest
unittest.main('idlelib.idle_test.test_grep', verbosity=2, exit=False)