Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(187)

Unified Diff: third_party/pylint/gui.py

Issue 739393004: Revert "Revert "pylint: upgrade to 1.3.1"" (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools/
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/pylint/epylint.py ('k') | third_party/pylint/interfaces.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/pylint/gui.py
===================================================================
--- third_party/pylint/gui.py (revision 293047)
+++ third_party/pylint/gui.py (working copy)
@@ -1,3 +1,18 @@
+# Copyright (c) 2003-2013 LOGILAB S.A. (Paris, FRANCE).
+# http://www.logilab.fr/ -- mailto:contact@logilab.fr
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any later
+# version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
"""Tkinker gui for pylint"""
import os
@@ -8,7 +23,7 @@
from Tkinter import (Tk, Frame, Listbox, Entry, Label, Button, Scrollbar,
Checkbutton, Radiobutton, IntVar, StringVar)
from Tkinter import (TOP, LEFT, RIGHT, BOTTOM, END, X, Y, BOTH, SUNKEN, W,
- HORIZONTAL, DISABLED, NORMAL, W, E)
+ HORIZONTAL, DISABLED, NORMAL, W)
from tkFileDialog import askopenfilename, askdirectory
import pylint.lint
@@ -21,7 +36,15 @@
'(W)':'black', '(E)':'darkred',
'(F)':'red'}
-class BasicStream:
+
+def convert_to_string(msg):
+ """make a string representation of a message"""
+ module_object = msg.module
+ if msg.obj:
+ module_object += ".%s" % msg.obj
+ return "(%s) %s [%d]: %s" % (msg.C, module_object, msg.line, msg.msg)
+
+class BasicStream(object):
'''
used in gui reporter instead of writing to stdout, it is written to
this stream and saved in contents
@@ -33,34 +56,37 @@
self.contents = []
self.outdict = {}
self.currout = None
- self.nextTitle = None
+ self.next_title = None
def write(self, text):
"""write text to the stream"""
if re.match('^--+$', text.strip()) or re.match('^==+$', text.strip()):
if self.currout:
- self.outdict[self.currout].remove(self.nextTitle)
+ self.outdict[self.currout].remove(self.next_title)
self.outdict[self.currout].pop()
- self.currout = self.nextTitle
+ self.currout = self.next_title
self.outdict[self.currout] = ['']
if text.strip():
- self.nextTitle = text.strip()
+ self.next_title = text.strip()
- if text.startswith('\n'):
+ if text.startswith(os.linesep):
self.contents.append('')
- if self.currout: self.outdict[self.currout].append('')
- self.contents[-1] += text.strip('\n')
- if self.currout: self.outdict[self.currout][-1] += text.strip('\n')
- if text.endswith('\n') and text.strip():
+ if self.currout:
+ self.outdict[self.currout].append('')
+ self.contents[-1] += text.strip(os.linesep)
+ if self.currout:
+ self.outdict[self.currout][-1] += text.strip(os.linesep)
+ if text.endswith(os.linesep) and text.strip():
self.contents.append('')
- if self.currout: self.outdict[self.currout].append('')
+ if self.currout:
+ self.outdict[self.currout].append('')
def fix_contents(self):
"""finalize what the contents of the dict should look like before output"""
for item in self.outdict:
- numEmpty = self.outdict[item].count('')
- for i in range(numEmpty):
+ num_empty = self.outdict[item].count('')
+ for _ in xrange(num_empty):
self.outdict[item].remove('')
if self.outdict[item]:
self.outdict[item].pop(0)
@@ -79,10 +105,10 @@
self.contents = []
self.outdict = {}
self.currout = None
- self.nextTitle = None
+ self.next_title = None
-class LintGui:
+class LintGui(object):
"""Build and control a window to interact with pylint"""
def __init__(self, root=None):
@@ -94,12 +120,13 @@
#message queue for output from reporter
self.msg_queue = Queue.Queue()
self.msgs = []
+ self.visible_msgs = []
self.filenames = []
self.rating = StringVar()
self.tabs = {}
self.report_stream = BasicStream(self)
#gui objects
- self.lbMessages = None
+ self.lb_messages = None
self.showhistory = None
self.results = None
self.btnRun = None
@@ -136,18 +163,23 @@
msg_frame.pack(side=TOP, fill=BOTH, expand=True)
btn_frame.pack(side=TOP, fill=X)
+ # Binding F5 application-wide to run lint
+ self.root.bind('<F5>', self.run_lint)
+
#Message ListBox
rightscrollbar = Scrollbar(msg_frame)
rightscrollbar.pack(side=RIGHT, fill=Y)
bottomscrollbar = Scrollbar(msg_frame, orient=HORIZONTAL)
bottomscrollbar.pack(side=BOTTOM, fill=X)
- self.lbMessages = Listbox(msg_frame,
- yscrollcommand=rightscrollbar.set,
- xscrollcommand=bottomscrollbar.set,
- bg="white")
- self.lbMessages.pack(expand=True, fill=BOTH)
- rightscrollbar.config(command=self.lbMessages.yview)
- bottomscrollbar.config(command=self.lbMessages.xview)
+ self.lb_messages = Listbox(
+ msg_frame,
+ yscrollcommand=rightscrollbar.set,
+ xscrollcommand=bottomscrollbar.set,
+ bg="white")
+ self.lb_messages.bind("<Double-Button-1>", self.show_sourcefile)
+ self.lb_messages.pack(expand=True, fill=BOTH)
+ rightscrollbar.config(command=self.lb_messages.yview)
+ bottomscrollbar.config(command=self.lb_messages.xview)
#History ListBoxes
rightscrollbar2 = Scrollbar(history_frame)
@@ -154,10 +186,11 @@
rightscrollbar2.pack(side=RIGHT, fill=Y)
bottomscrollbar2 = Scrollbar(history_frame, orient=HORIZONTAL)
bottomscrollbar2.pack(side=BOTTOM, fill=X)
- self.showhistory = Listbox(history_frame,
- yscrollcommand=rightscrollbar2.set,
- xscrollcommand=bottomscrollbar2.set,
- bg="white")
+ self.showhistory = Listbox(
+ history_frame,
+ yscrollcommand=rightscrollbar2.set,
+ xscrollcommand=bottomscrollbar2.set,
+ bg="white")
self.showhistory.pack(expand=True, fill=BOTH)
rightscrollbar2.config(command=self.showhistory.yview)
bottomscrollbar2.config(command=self.showhistory.xview)
@@ -168,18 +201,18 @@
self.status = Label(self.root, text="", bd=1, relief=SUNKEN, anchor=W)
self.status.pack(side=BOTTOM, fill=X)
- #labels
- self.lblRatingLabel = Label(rating_frame, text='Rating:')
- self.lblRatingLabel.pack(side=LEFT)
- self.lblRating = Label(rating_frame, textvariable=self.rating)
- self.lblRating.pack(side=LEFT)
+ #labelbl_ratingls
+ lbl_rating_label = Label(rating_frame, text='Rating:')
+ lbl_rating_label.pack(side=LEFT)
+ lbl_rating = Label(rating_frame, textvariable=self.rating)
+ lbl_rating.pack(side=LEFT)
Label(mid_frame, text='Recently Used:').pack(side=LEFT)
Label(top_frame, text='Module or package').pack(side=LEFT)
#file textbox
- self.txtModule = Entry(top_frame, background='white')
- self.txtModule.bind('<Return>', self.run_lint)
- self.txtModule.pack(side=LEFT, expand=True, fill=X)
+ self.txt_module = Entry(top_frame, background='white')
+ self.txt_module.bind('<Return>', self.run_lint)
+ self.txt_module.pack(side=LEFT, expand=True, fill=X)
#results box
rightscrollbar = Scrollbar(res_frame)
@@ -186,10 +219,11 @@
rightscrollbar.pack(side=RIGHT, fill=Y)
bottomscrollbar = Scrollbar(res_frame, orient=HORIZONTAL)
bottomscrollbar.pack(side=BOTTOM, fill=X)
- self.results = Listbox(res_frame,
- yscrollcommand=rightscrollbar.set,
- xscrollcommand=bottomscrollbar.set,
- bg="white", font="Courier")
+ self.results = Listbox(
+ res_frame,
+ yscrollcommand=rightscrollbar.set,
+ xscrollcommand=bottomscrollbar.set,
+ bg="white", font="Courier")
self.results.pack(expand=True, fill=BOTH, side=BOTTOM)
rightscrollbar.config(command=self.results.yview)
bottomscrollbar.config(command=self.results.xview)
@@ -196,8 +230,8 @@
#buttons
Button(top_frame, text='Open', command=self.file_open).pack(side=LEFT)
- Button(top_frame, text='Open Package',
- command=(lambda : self.file_open(package=True))).pack(side=LEFT)
+ Button(top_frame, text='Open Package',
+ command=(lambda: self.file_open(package=True))).pack(side=LEFT)
self.btnRun = Button(top_frame, text='Run', command=self.run_lint)
self.btnRun.pack(side=LEFT)
@@ -238,42 +272,53 @@
#check boxes
self.box = StringVar()
# XXX should be generated
- report = Radiobutton(radio_frame, text="Report", variable=self.box,
- value="Report", command=self.refresh_results_window)
- rawMet = Radiobutton(radio_frame, text="Raw metrics", variable=self.box,
- value="Raw metrics", command=self.refresh_results_window)
- dup = Radiobutton(radio_frame, text="Duplication", variable=self.box,
- value="Duplication", command=self.refresh_results_window)
- ext = Radiobutton(radio_frame, text="External dependencies",
- variable=self.box, value="External dependencies",
- command=self.refresh_results_window)
- stat = Radiobutton(radio_frame, text="Statistics by type",
- variable=self.box, value="Statistics by type",
- command=self.refresh_results_window)
- msgCat = Radiobutton(radio_frame, text="Messages by category",
- variable=self.box, value="Messages by category",
- command=self.refresh_results_window)
- msg = Radiobutton(radio_frame, text="Messages", variable=self.box,
- value="Messages", command=self.refresh_results_window)
+ report = Radiobutton(
+ radio_frame, text="Report", variable=self.box,
+ value="Report", command=self.refresh_results_window)
+ raw_met = Radiobutton(
+ radio_frame, text="Raw metrics", variable=self.box,
+ value="Raw metrics", command=self.refresh_results_window)
+ dup = Radiobutton(
+ radio_frame, text="Duplication", variable=self.box,
+ value="Duplication", command=self.refresh_results_window)
+ ext = Radiobutton(
+ radio_frame, text="External dependencies",
+ variable=self.box, value="External dependencies",
+ command=self.refresh_results_window)
+ stat = Radiobutton(
+ radio_frame, text="Statistics by type",
+ variable=self.box, value="Statistics by type",
+ command=self.refresh_results_window)
+ msg_cat = Radiobutton(
+ radio_frame, text="Messages by category",
+ variable=self.box, value="Messages by category",
+ command=self.refresh_results_window)
+ msg = Radiobutton(
+ radio_frame, text="Messages", variable=self.box,
+ value="Messages", command=self.refresh_results_window)
+ source_file = Radiobutton(
+ radio_frame, text="Source File", variable=self.box,
+ value="Source File", command=self.refresh_results_window)
report.select()
report.grid(column=0, row=0, sticky=W)
- rawMet.grid(column=1, row=0, sticky=W)
+ raw_met.grid(column=1, row=0, sticky=W)
dup.grid(column=2, row=0, sticky=W)
- msg.grid(column=3, row=0, sticky=E)
+ msg.grid(column=3, row=0, sticky=W)
stat.grid(column=0, row=1, sticky=W)
- msgCat.grid(column=1, row=1, sticky=W)
- ext.grid(column=2, row=1, columnspan=2, sticky=W)
+ msg_cat.grid(column=1, row=1, sticky=W)
+ ext.grid(column=2, row=1, sticky=W)
+ source_file.grid(column=3, row=1, sticky=W)
#dictionary for check boxes and associated error term
self.msg_type_dict = {
- 'I' : lambda : self.information_box.get() == 1,
- 'C' : lambda : self.convention_box.get() == 1,
- 'R' : lambda : self.refactor_box.get() == 1,
- 'E' : lambda : self.error_box.get() == 1,
- 'W' : lambda : self.warning_box.get() == 1,
- 'F' : lambda : self.fatal_box.get() == 1
+ 'I': lambda: self.information_box.get() == 1,
+ 'C': lambda: self.convention_box.get() == 1,
+ 'R': lambda: self.refactor_box.get() == 1,
+ 'E': lambda: self.error_box.get() == 1,
+ 'W': lambda: self.warning_box.get() == 1,
+ 'F': lambda: self.fatal_box.get() == 1
}
- self.txtModule.focus_set()
+ self.txt_module.focus_set()
def select_recent_file(self, event):
@@ -284,19 +329,21 @@
selected = self.showhistory.curselection()
item = self.showhistory.get(selected)
#update module
- self.txtModule.delete(0, END)
- self.txtModule.insert(0, item)
+ self.txt_module.delete(0, END)
+ self.txt_module.insert(0, item)
def refresh_msg_window(self):
"""refresh the message window with current output"""
#clear the window
- self.lbMessages.delete(0, END)
+ self.lb_messages.delete(0, END)
+ self.visible_msgs = []
for msg in self.msgs:
- if (self.msg_type_dict.get(msg[0])()):
- msg_str = self.convert_to_string(msg)
- self.lbMessages.insert(END, msg_str)
+ if self.msg_type_dict.get(msg.C)():
+ self.visible_msgs.append(msg)
+ msg_str = convert_to_string(msg)
+ self.lb_messages.insert(END, msg_str)
fg_color = COLORS.get(msg_str[:3], 'black')
- self.lbMessages.itemconfigure(END, fg=fg_color)
+ self.lb_messages.itemconfigure(END, fg=fg_color)
def refresh_results_window(self):
"""refresh the results window with current output"""
@@ -308,13 +355,6 @@
except:
pass
- def convert_to_string(self, msg):
- """make a string representation of a message"""
- if (msg[2] != ""):
- return "(" + msg[0] + ") " + msg[1] + "." + msg[2] + " [" + msg[3] + "]: " + msg[4]
- else:
- return "(" + msg[0] + ") " + msg[1] + " [" + msg[3] + "]: " + msg[4]
-
def process_incoming(self):
"""process the incoming messages from running pylint"""
while self.msg_queue.qsize():
@@ -328,11 +368,12 @@
self.msgs.append(msg)
#displaying msg if message type is selected in check box
- if (self.msg_type_dict.get(msg[0])()):
- msg_str = self.convert_to_string(msg)
- self.lbMessages.insert(END, msg_str)
+ if self.msg_type_dict.get(msg.C)():
+ self.visible_msgs.append(msg)
+ msg_str = convert_to_string(msg)
+ self.lb_messages.insert(END, msg_str)
fg_color = COLORS.get(msg_str[:3], 'black')
- self.lbMessages.itemconfigure(END, fg=fg_color)
+ self.lb_messages.itemconfigure(END, fg=fg_color)
except Queue.Empty:
pass
@@ -361,8 +402,10 @@
def file_open(self, package=False, _=None):
"""launch a file browser"""
if not package:
- filename = askopenfilename(parent=self.root, filetypes=[('pythonfiles', '*.py'),
- ('allfiles', '*')], title='Select Module')
+ filename = askopenfilename(parent=self.root,
+ filetypes=[('pythonfiles', '*.py'),
+ ('allfiles', '*')],
+ title='Select Module')
else:
filename = askdirectory(title="Select A Folder", mustexist=1)
@@ -369,12 +412,12 @@
if filename == ():
return
- self.txtModule.delete(0, END)
- self.txtModule.insert(0, filename)
+ self.txt_module.delete(0, END)
+ self.txt_module.insert(0, filename)
def update_filenames(self):
"""update the list of recent filenames"""
- filename = self.txtModule.get()
+ filename = self.txt_module.get()
if not filename:
filename = os.getcwd()
if filename+'\n' in self.filenames:
@@ -407,13 +450,14 @@
self.update_filenames()
self.root.configure(cursor='watch')
self.reporter = GUIReporter(self, output=self.report_stream)
- module = self.txtModule.get()
+ module = self.txt_module.get()
if not module:
module = os.getcwd()
#cleaning up msgs and windows
self.msgs = []
- self.lbMessages.delete(0, END)
+ self.visible_msgs = []
+ self.lb_messages.delete(0, END)
self.tabs = {}
self.results.delete(0, END)
self.btnRun.config(state=DISABLED)
@@ -432,11 +476,27 @@
self.root.configure(cursor='')
+ def show_sourcefile(self, event=None):
+ selected = self.lb_messages.curselection()
+ if not selected:
+ return
+ msg = self.visible_msgs[int(selected[0])]
+ scroll = msg.line - 3
+ if scroll < 0:
+ scroll = 0
+
+ self.tabs["Source File"] = open(msg.path, "r").readlines()
+ self.box.set("Source File")
+ self.refresh_results_window()
+ self.results.yview(scroll)
+ self.results.select_set(msg.line - 1)
+
+
def lint_thread(module, reporter, gui):
"""thread for pylint"""
gui.status.text = "processing module(s)"
- lint_obj = pylint.lint.Run(args=[module], reporter=reporter, exit=False)
+ pylint.lint.Run(args=[module], reporter=reporter, exit=False)
gui.msg_queue.put("DONE")
@@ -444,9 +504,10 @@
"""launch pylint gui from args"""
if args:
print 'USAGE: pylint-gui\n launch a simple pylint gui using Tk'
- return
+ sys.exit(1)
gui = LintGui()
gui.mainloop()
+ sys.exit(0)
if __name__ == '__main__':
Run(sys.argv[1:])
« no previous file with comments | « third_party/pylint/epylint.py ('k') | third_party/pylint/interfaces.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698