Skip to content

Commit 65474b9

Browse files
csabellaterryjreedy
authored andcommitted
bpo-30674: IDLE: add docstrings to grep.py (#2213)
Patch by Cheryl Sabella
1 parent 44913e5 commit 65474b9

File tree

2 files changed

+55
-12
lines changed

2 files changed

+55
-12
lines changed

Lib/idlelib/grep.py

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
"""Grep dialog for Find in Files functionality.
2+
3+
Inherits from SearchDialogBase for GUI and uses searchengine
4+
to prepare search pattern.
5+
"""
16
import fnmatch
27
import os
38
import sys
@@ -11,7 +16,17 @@
1116
# Importing OutputWindow here fails due to import loop
1217
# EditorWindow -> GrepDialop -> OutputWindow -> EditorWindow
1318

19+
1420
def grep(text, io=None, flist=None):
21+
"""Create or find singleton GrepDialog instance.
22+
23+
Args:
24+
text: Text widget that contains the selected text for
25+
default search phrase.
26+
io: iomenu.IOBinding instance with default path to search.
27+
flist: filelist.FileList instance for OutputWindow parent.
28+
"""
29+
1530
root = text._root()
1631
engine = searchengine.get(root)
1732
if not hasattr(engine, "_grepdialog"):
@@ -20,19 +35,32 @@ def grep(text, io=None, flist=None):
2035
searchphrase = text.get("sel.first", "sel.last")
2136
dialog.open(text, searchphrase, io)
2237

38+
2339
class GrepDialog(SearchDialogBase):
40+
"Dialog for searching multiple files."
2441

2542
title = "Find in Files Dialog"
2643
icon = "Grep"
2744
needwrapbutton = 0
2845

2946
def __init__(self, root, engine, flist):
47+
"""Create search dialog for searching for a phrase in the file system.
48+
49+
Uses SearchDialogBase as the basis for the GUI and a
50+
searchengine instance to prepare the search.
51+
52+
Attributes:
53+
globvar: Value of Text Entry widget for path to search.
54+
recvar: Boolean value of Checkbutton widget
55+
for traversing through subdirectories.
56+
"""
3057
SearchDialogBase.__init__(self, root, engine)
3158
self.flist = flist
3259
self.globvar = StringVar(root)
3360
self.recvar = BooleanVar(root)
3461

3562
def open(self, text, searchphrase, io=None):
63+
"Make dialog visible on top of others and ready to use."
3664
SearchDialogBase.open(self, text, searchphrase)
3765
if io:
3866
path = io.filename or ""
@@ -45,20 +73,30 @@ def open(self, text, searchphrase, io=None):
4573
self.globvar.set(os.path.join(dir, "*" + tail))
4674

4775
def create_entries(self):
76+
"Create base entry widgets and add widget for search path."
4877
SearchDialogBase.create_entries(self)
4978
self.globent = self.make_entry("In files:", self.globvar)[0]
5079

5180
def create_other_buttons(self):
81+
"Add check button to recurse down subdirectories."
5282
btn = Checkbutton(
5383
self.make_frame()[0], variable=self.recvar,
5484
text="Recurse down subdirectories")
5585
btn.pack(side="top", fill="both")
5686

5787
def create_command_buttons(self):
88+
"Create base command buttons and add button for search."
5889
SearchDialogBase.create_command_buttons(self)
5990
self.make_button("Search Files", self.default_command, 1)
6091

6192
def default_command(self, event=None):
93+
"""Grep for search pattern in file path. The default command is bound
94+
to <Return>.
95+
96+
If entry values are populated, set OutputWindow as stdout
97+
and perform search. The search dialog is closed automatically
98+
when the search begins.
99+
"""
62100
prog = self.engine.getprog()
63101
if not prog:
64102
return
@@ -75,12 +113,19 @@ def default_command(self, event=None):
75113
sys.stdout = save
76114

77115
def grep_it(self, prog, path):
116+
"""Search for prog within the lines of the files in path.
117+
118+
For the each file in the path directory, open the file and
119+
search each line for the matching pattern. If the pattern is
120+
found, write the file and line information to stdout (which
121+
is an OutputWindow).
122+
"""
78123
dir, base = os.path.split(path)
79124
list = self.findfiles(dir, base, self.recvar.get())
80125
list.sort()
81126
self.close()
82127
pat = self.engine.getpat()
83-
print("Searching %r in %s ..." % (pat, path))
128+
print(f"Searching {pat!r} in {path} ...")
84129
hits = 0
85130
try:
86131
for fn in list:
@@ -90,20 +135,22 @@ def grep_it(self, prog, path):
90135
if line[-1:] == '\n':
91136
line = line[:-1]
92137
if prog.search(line):
93-
sys.stdout.write("%s: %s: %s\n" %
94-
(fn, lineno, line))
138+
sys.stdout.write(f"{fn}: {lineno}: {line}\n")
95139
hits += 1
96140
except OSError as msg:
97141
print(msg)
98-
print(("Hits found: %s\n"
99-
"(Hint: right-click to open locations.)"
100-
% hits) if hits else "No hits.")
142+
print(f"Hits found: {hits}\n(Hint: right-click to open locations.)"
143+
if hits else "No hits.")
101144
except AttributeError:
102145
# Tk window has been closed, OutputWindow.text = None,
103146
# so in OW.write, OW.text.insert fails.
104147
pass
105148

106149
def findfiles(self, dir, base, rec):
150+
"""Return list of files in the dir that match the base pattern.
151+
152+
If rec is True, recursively iterate through subdirectories.
153+
"""
107154
try:
108155
names = os.listdir(dir or os.curdir)
109156
except OSError as msg:
@@ -123,11 +170,6 @@ def findfiles(self, dir, base, rec):
123170
list.extend(self.findfiles(subdir, base, rec))
124171
return list
125172

126-
def close(self, event=None):
127-
if self.top:
128-
self.top.grab_release()
129-
self.top.withdraw()
130-
131173

132174
def _grep_dialog(parent): # htest #
133175
from tkinter import Toplevel, Text, SEL, END
@@ -136,7 +178,7 @@ def _grep_dialog(parent): # htest #
136178
top = Toplevel(parent)
137179
top.title("Test GrepDialog")
138180
x, y = map(int, parent.geometry().split('+')[1:])
139-
top.geometry("+%d+%d" % (x, y + 175))
181+
top.geometry(f"+{x}+{y + 175}")
140182

141183
flist = PyShellFileList(top)
142184
text = Text(top, height=5)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
IDLE: add docstrings to grep module. Patch by Cheryl Sabella

0 commit comments

Comments
 (0)