diff options
author | csabella <cheryl.sabella@gmail.com> | 2017-06-27 06:41:08 (GMT) |
---|---|---|
committer | terryjreedy <tjreedy@udel.edu> | 2017-06-27 06:41:08 (GMT) |
commit | 65474b9d7a230943d4d3f1d7d51f77bb141240f0 (patch) | |
tree | e79ab8ae1b07edb6239a4f011158338ab09bbc28 /Lib | |
parent | 44913e584bcf4e2a0e1a6372c304c2d5ea521fc6 (diff) | |
download | cpython-65474b9d7a230943d4d3f1d7d51f77bb141240f0.zip cpython-65474b9d7a230943d4d3f1d7d51f77bb141240f0.tar.gz cpython-65474b9d7a230943d4d3f1d7d51f77bb141240f0.tar.bz2 |
bpo-30674: IDLE: add docstrings to grep.py (#2213)
Patch by Cheryl Sabella
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/idlelib/grep.py | 66 |
1 files changed, 54 insertions, 12 deletions
diff --git a/Lib/idlelib/grep.py b/Lib/idlelib/grep.py index 64ba28d..c55c48c 100644 --- a/Lib/idlelib/grep.py +++ b/Lib/idlelib/grep.py @@ -1,3 +1,8 @@ +"""Grep dialog for Find in Files functionality. + + Inherits from SearchDialogBase for GUI and uses searchengine + to prepare search pattern. +""" import fnmatch import os import sys @@ -11,7 +16,17 @@ from idlelib import searchengine # Importing OutputWindow here fails due to import loop # EditorWindow -> GrepDialop -> OutputWindow -> EditorWindow + def grep(text, io=None, flist=None): + """Create or find singleton GrepDialog instance. + + Args: + text: Text widget that contains the selected text for + default search phrase. + io: iomenu.IOBinding instance with default path to search. + flist: filelist.FileList instance for OutputWindow parent. + """ + root = text._root() engine = searchengine.get(root) if not hasattr(engine, "_grepdialog"): @@ -20,19 +35,32 @@ def grep(text, io=None, flist=None): searchphrase = text.get("sel.first", "sel.last") dialog.open(text, searchphrase, io) + class GrepDialog(SearchDialogBase): + "Dialog for searching multiple files." title = "Find in Files Dialog" icon = "Grep" needwrapbutton = 0 def __init__(self, root, engine, flist): + """Create search dialog for searching for a phrase in the file system. + + Uses SearchDialogBase as the basis for the GUI and a + searchengine instance to prepare the search. + + Attributes: + globvar: Value of Text Entry widget for path to search. + recvar: Boolean value of Checkbutton widget + for traversing through subdirectories. + """ SearchDialogBase.__init__(self, root, engine) self.flist = flist self.globvar = StringVar(root) self.recvar = BooleanVar(root) def open(self, text, searchphrase, io=None): + "Make dialog visible on top of others and ready to use." SearchDialogBase.open(self, text, searchphrase) if io: path = io.filename or "" @@ -45,20 +73,30 @@ class GrepDialog(SearchDialogBase): self.globvar.set(os.path.join(dir, "*" + tail)) def create_entries(self): + "Create base entry widgets and add widget for search path." SearchDialogBase.create_entries(self) self.globent = self.make_entry("In files:", self.globvar)[0] def create_other_buttons(self): + "Add check button to recurse down subdirectories." btn = Checkbutton( self.make_frame()[0], variable=self.recvar, text="Recurse down subdirectories") btn.pack(side="top", fill="both") def create_command_buttons(self): + "Create base command buttons and add button for search." SearchDialogBase.create_command_buttons(self) self.make_button("Search Files", self.default_command, 1) def default_command(self, event=None): + """Grep for search pattern in file path. The default command is bound + to <Return>. + + If entry values are populated, set OutputWindow as stdout + and perform search. The search dialog is closed automatically + when the search begins. + """ prog = self.engine.getprog() if not prog: return @@ -75,12 +113,19 @@ class GrepDialog(SearchDialogBase): sys.stdout = save def grep_it(self, prog, path): + """Search for prog within the lines of the files in path. + + For the each file in the path directory, open the file and + search each line for the matching pattern. If the pattern is + found, write the file and line information to stdout (which + is an OutputWindow). + """ dir, base = os.path.split(path) list = self.findfiles(dir, base, self.recvar.get()) list.sort() self.close() pat = self.engine.getpat() - print("Searching %r in %s ..." % (pat, path)) + print(f"Searching {pat!r} in {path} ...") hits = 0 try: for fn in list: @@ -90,20 +135,22 @@ class GrepDialog(SearchDialogBase): if line[-1:] == '\n': line = line[:-1] if prog.search(line): - sys.stdout.write("%s: %s: %s\n" % - (fn, lineno, line)) + sys.stdout.write(f"{fn}: {lineno}: {line}\n") 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.") + print(f"Hits found: {hits}\n(Hint: right-click to open locations.)" + 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): + """Return list of files in the dir that match the base pattern. + + If rec is True, recursively iterate through subdirectories. + """ try: names = os.listdir(dir or os.curdir) except OSError as msg: @@ -123,11 +170,6 @@ class GrepDialog(SearchDialogBase): list.extend(self.findfiles(subdir, base, rec)) return list - def close(self, event=None): - if self.top: - self.top.grab_release() - self.top.withdraw() - def _grep_dialog(parent): # htest # from tkinter import Toplevel, Text, SEL, END @@ -136,7 +178,7 @@ def _grep_dialog(parent): # htest # top = Toplevel(parent) top.title("Test GrepDialog") x, y = map(int, parent.geometry().split('+')[1:]) - top.geometry("+%d+%d" % (x, y + 175)) + top.geometry(f"+{x}+{y + 175}") flist = PyShellFileList(top) text = Text(top, height=5) |