Skip to content

Commit 4762382

Browse files
committed
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.
1 parent 6ceca4e commit 4762382

File tree

1 file changed

+29
-20
lines changed

1 file changed

+29
-20
lines changed

Lib/idlelib/GrepDialog.py

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
import os
22
import fnmatch
3+
import re # for htest
34
import sys
4-
from tkinter import *
5+
from tkinter import StringVar, BooleanVar, Checkbutton # for GrepDialog
6+
from tkinter import Tk, Text, Button, SEL, END # for htest
57
from idlelib import SearchEngine
8+
import itertools
69
from idlelib.SearchDialogBase import SearchDialogBase
10+
# Importing OutputWindow fails due to import loop
11+
# EditorWindow -> GrepDialop -> OutputWindow -> EditorWindow
712

813
def grep(text, io=None, flist=None):
914
root = text._root()
@@ -63,7 +68,7 @@ def default_command(self, event=None):
6368
if not path:
6469
self.top.bell()
6570
return
66-
from idlelib.OutputWindow import OutputWindow
71+
from idlelib.OutputWindow import OutputWindow # leave here!
6772
save = sys.stdout
6873
try:
6974
sys.stdout = OutputWindow(self.flist)
@@ -79,21 +84,26 @@ def grep_it(self, prog, path):
7984
pat = self.engine.getpat()
8085
print("Searching %r in %s ..." % (pat, path))
8186
hits = 0
82-
for fn in list:
83-
try:
84-
with open(fn, errors='replace') as f:
85-
for lineno, line in enumerate(f, 1):
86-
if line[-1:] == '\n':
87-
line = line[:-1]
88-
if prog.search(line):
89-
sys.stdout.write("%s: %s: %s\n" %
90-
(fn, lineno, line))
91-
hits += 1
92-
except OSError as msg:
93-
print(msg)
94-
print(("Hits found: %s\n"
95-
"(Hint: right-click to open locations.)"
96-
% hits) if hits else "No hits.")
87+
try:
88+
for fn in list:
89+
try:
90+
with open(fn, errors='replace') as f:
91+
for lineno, line in enumerate(f, 1):
92+
if line[-1:] == '\n':
93+
line = line[:-1]
94+
if prog.search(line):
95+
sys.stdout.write("%s: %s: %s\n" %
96+
(fn, lineno, line))
97+
hits += 1
98+
except OSError as msg:
99+
print(msg)
100+
print(("Hits found: %s\n"
101+
"(Hint: right-click to open locations.)"
102+
% hits) if hits else "No hits.")
103+
except AttributeError:
104+
# Tk window has been closed, OutputWindow.text = None,
105+
# so in OW.write, OW.text.insert fails.
106+
pass
97107

98108
def findfiles(self, dir, base, rec):
99109
try:
@@ -120,7 +130,8 @@ def close(self, event=None):
120130
self.top.grab_release()
121131
self.top.withdraw()
122132

123-
def _grep_dialog(parent):
133+
134+
def _grep_dialog(parent): # for htest
124135
from idlelib.PyShell import PyShellFileList
125136
root = Tk()
126137
root.title("Test GrepDialog")
@@ -141,8 +152,6 @@ def show_grep_dialog():
141152
root.mainloop()
142153

143154
if __name__ == "__main__":
144-
# A human test is a bit tricky since EditorWindow() imports this module.
145-
# Hence Idle must be restarted after editing this file for a live test.
146155
import unittest
147156
unittest.main('idlelib.idle_test.test_grep', verbosity=2, exit=False)
148157

0 commit comments

Comments
 (0)