Index: third_party/pylint/gui.py |
diff --git a/third_party/pylint/gui.py b/third_party/pylint/gui.py |
index fcc84e0038a5633b6f6d0509bd977e6044f2a7c0..2d8e81e76fa6baff911271ce11eeb675e1eb8d38 100644 |
--- a/third_party/pylint/gui.py |
+++ b/third_party/pylint/gui.py |
@@ -1,18 +1,3 @@ |
-# 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 |
@@ -23,7 +8,7 @@ from threading import Thread |
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) |
+ HORIZONTAL, DISABLED, NORMAL, W, E) |
from tkFileDialog import askopenfilename, askdirectory |
import pylint.lint |
@@ -36,15 +21,7 @@ COLORS = {'(I)':'lightblue', |
'(W)':'black', '(E)':'darkred', |
'(F)':'red'} |
- |
-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): |
+class BasicStream: |
''' |
used in gui reporter instead of writing to stdout, it is written to |
this stream and saved in contents |
@@ -56,37 +33,34 @@ class BasicStream(object): |
self.contents = [] |
self.outdict = {} |
self.currout = None |
- self.next_title = None |
+ self.nextTitle = 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.next_title) |
+ self.outdict[self.currout].remove(self.nextTitle) |
self.outdict[self.currout].pop() |
- self.currout = self.next_title |
+ self.currout = self.nextTitle |
self.outdict[self.currout] = [''] |
if text.strip(): |
- self.next_title = text.strip() |
+ self.nextTitle = text.strip() |
- if text.startswith(os.linesep): |
+ if text.startswith('\n'): |
self.contents.append('') |
- 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(): |
+ 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(): |
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: |
- num_empty = self.outdict[item].count('') |
- for _ in xrange(num_empty): |
+ numEmpty = self.outdict[item].count('') |
+ for i in range(numEmpty): |
self.outdict[item].remove('') |
if self.outdict[item]: |
self.outdict[item].pop(0) |
@@ -105,10 +79,10 @@ class BasicStream(object): |
self.contents = [] |
self.outdict = {} |
self.currout = None |
- self.next_title = None |
+ self.nextTitle = None |
-class LintGui(object): |
+class LintGui: |
"""Build and control a window to interact with pylint""" |
def __init__(self, root=None): |
@@ -120,13 +94,12 @@ class LintGui(object): |
#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.lb_messages = None |
+ self.lbMessages = None |
self.showhistory = None |
self.results = None |
self.btnRun = None |
@@ -163,34 +136,28 @@ class LintGui(object): |
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.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) |
+ 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) |
#History ListBoxes |
rightscrollbar2 = Scrollbar(history_frame) |
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) |
@@ -201,37 +168,36 @@ class LintGui(object): |
self.status = Label(self.root, text="", bd=1, relief=SUNKEN, anchor=W) |
self.status.pack(side=BOTTOM, fill=X) |
- #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) |
+ #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) |
Label(mid_frame, text='Recently Used:').pack(side=LEFT) |
Label(top_frame, text='Module or package').pack(side=LEFT) |
#file textbox |
- 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) |
+ self.txtModule = Entry(top_frame, background='white') |
+ self.txtModule.bind('<Return>', self.run_lint) |
+ self.txtModule.pack(side=LEFT, expand=True, fill=X) |
#results box |
rightscrollbar = Scrollbar(res_frame) |
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) |
#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) |
@@ -272,53 +238,42 @@ class LintGui(object): |
#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) |
- 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 = 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.select() |
report.grid(column=0, row=0, sticky=W) |
- raw_met.grid(column=1, row=0, sticky=W) |
+ rawMet.grid(column=1, row=0, sticky=W) |
dup.grid(column=2, row=0, sticky=W) |
- msg.grid(column=3, row=0, sticky=W) |
+ msg.grid(column=3, row=0, sticky=E) |
stat.grid(column=0, row=1, 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) |
+ msgCat.grid(column=1, row=1, sticky=W) |
+ ext.grid(column=2, row=1, columnspan=2, 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.txt_module.focus_set() |
+ self.txtModule.focus_set() |
def select_recent_file(self, event): |
@@ -329,21 +284,19 @@ class LintGui(object): |
selected = self.showhistory.curselection() |
item = self.showhistory.get(selected) |
#update module |
- self.txt_module.delete(0, END) |
- self.txt_module.insert(0, item) |
+ self.txtModule.delete(0, END) |
+ self.txtModule.insert(0, item) |
def refresh_msg_window(self): |
"""refresh the message window with current output""" |
#clear the window |
- self.lb_messages.delete(0, END) |
- self.visible_msgs = [] |
+ self.lbMessages.delete(0, END) |
for msg in self.msgs: |
- 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) |
+ if (self.msg_type_dict.get(msg[0])()): |
+ msg_str = self.convert_to_string(msg) |
+ self.lbMessages.insert(END, msg_str) |
fg_color = COLORS.get(msg_str[:3], 'black') |
- self.lb_messages.itemconfigure(END, fg=fg_color) |
+ self.lbMessages.itemconfigure(END, fg=fg_color) |
def refresh_results_window(self): |
"""refresh the results window with current output""" |
@@ -355,6 +308,13 @@ class LintGui(object): |
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(): |
@@ -368,12 +328,11 @@ class LintGui(object): |
self.msgs.append(msg) |
#displaying msg if message type is selected in check box |
- 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) |
+ if (self.msg_type_dict.get(msg[0])()): |
+ msg_str = self.convert_to_string(msg) |
+ self.lbMessages.insert(END, msg_str) |
fg_color = COLORS.get(msg_str[:3], 'black') |
- self.lb_messages.itemconfigure(END, fg=fg_color) |
+ self.lbMessages.itemconfigure(END, fg=fg_color) |
except Queue.Empty: |
pass |
@@ -402,22 +361,20 @@ class LintGui(object): |
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) |
if filename == (): |
return |
- self.txt_module.delete(0, END) |
- self.txt_module.insert(0, filename) |
+ self.txtModule.delete(0, END) |
+ self.txtModule.insert(0, filename) |
def update_filenames(self): |
"""update the list of recent filenames""" |
- filename = self.txt_module.get() |
+ filename = self.txtModule.get() |
if not filename: |
filename = os.getcwd() |
if filename+'\n' in self.filenames: |
@@ -450,14 +407,13 @@ class LintGui(object): |
self.update_filenames() |
self.root.configure(cursor='watch') |
self.reporter = GUIReporter(self, output=self.report_stream) |
- module = self.txt_module.get() |
+ module = self.txtModule.get() |
if not module: |
module = os.getcwd() |
#cleaning up msgs and windows |
self.msgs = [] |
- self.visible_msgs = [] |
- self.lb_messages.delete(0, END) |
+ self.lbMessages.delete(0, END) |
self.tabs = {} |
self.results.delete(0, END) |
self.btnRun.config(state=DISABLED) |
@@ -476,27 +432,11 @@ class LintGui(object): |
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)" |
- pylint.lint.Run(args=[module], reporter=reporter, exit=False) |
+ lint_obj = pylint.lint.Run(args=[module], reporter=reporter, exit=False) |
gui.msg_queue.put("DONE") |
@@ -504,10 +444,9 @@ def Run(args): |
"""launch pylint gui from args""" |
if args: |
print 'USAGE: pylint-gui\n launch a simple pylint gui using Tk' |
- sys.exit(1) |
+ return |
gui = LintGui() |
gui.mainloop() |
- sys.exit(0) |
if __name__ == '__main__': |
Run(sys.argv[1:]) |