Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8c95c27

Browse files
committed
Added a new command: Check module (Alt-F5) It does a full syntax check
of the current module. It also runs the tabnanny to catch any inconsistent tabs. Also did a little bit of refactoring: added an errorbox() method to simplify the display of error dialogs.
1 parent 772dd41 commit 8c95c27

1 file changed

Lines changed: 82 additions & 9 deletions

File tree

Tools/idle/ScriptBinding.py

Lines changed: 82 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
"""Extension to execute code outside the Python shell window.
22
3-
This adds two commands (to the Edit menu, until there's a separate
4-
Python menu):
3+
This adds the following commands (to the Edit menu, until there's a
4+
separate Python menu):
5+
6+
- Check module (Alt-F5) does a full syntax check of the current module.
7+
It also runs the tabnanny to catch any inconsistent tabs.
58
69
- Import module (F5) is equivalent to either import or reload of the
710
current module. The window must have been saved previously. The
@@ -18,16 +21,29 @@
1821
import imp
1922
import tkMessageBox
2023

24+
indent_message = """Error: Inconsistent indentation detected!
25+
26+
This means that either:
27+
28+
(1) your indentation is outright incorrect (easy to fix), or
29+
30+
(2) your indentation mixes tabs and spaces in a way that depends on \
31+
how many spaces a tab is worth.
32+
33+
To fix case 2, change all tabs to spaces by using Select All followed \
34+
by Untabify Region (both in the Edit menu)."""
2135

2236
class ScriptBinding:
2337

2438
keydefs = {
39+
'<<check-module>>': ['<Alt-F5>', '<Meta-F5>'],
2540
'<<import-module>>': ['<F5>'],
2641
'<<run-script>>': ['<Control-F5>'],
2742
}
2843

2944
menudefs = [
3045
('edit', [None,
46+
('Check module', '<<check-module>>'),
3147
('Import module', '<<import-module>>'),
3248
('Run script', '<<run-script>>'),
3349
]
@@ -41,6 +57,59 @@ def __init__(self, editwin):
4157
self.flist = self.editwin.flist
4258
self.root = self.flist.root
4359

60+
def check_module_event(self, event):
61+
filename = self.getfilename()
62+
if not filename:
63+
return
64+
if not self.tabnanny(filename):
65+
return
66+
if not self.checksyntax(filename):
67+
return
68+
69+
def tabnanny(self, filename):
70+
import tabnanny
71+
import tokenize
72+
tabnanny.reset_globals()
73+
f = open(filename, 'r')
74+
try:
75+
tokenize.tokenize(f.readline, tabnanny.tokeneater)
76+
except tokenize.TokenError, msg:
77+
self.errorbox("Token error",
78+
"Token error:\n%s" % str(msg))
79+
return 0
80+
except tabnanny.NannyNag, nag:
81+
# The error messages from tabnanny are too confusing...
82+
self.editwin.gotoline(nag.get_lineno())
83+
self.errorbox("Tab/space error", indent_message)
84+
return 0
85+
return 1
86+
87+
def checksyntax(self, filename):
88+
f = open(filename, 'r')
89+
source = f.read()
90+
f.close()
91+
if '\r' in source:
92+
import re
93+
source = re.sub(r"\r\n", "\n", source)
94+
if source and source[-1] != '\n':
95+
source = source + '\n'
96+
try:
97+
compile(source, filename, "exec")
98+
except (SyntaxError, OverflowError), err:
99+
try:
100+
msg, (errorfilename, lineno, offset, line) = err
101+
if not errorfilename:
102+
err.args = msg, (filename, lineno, offset, line)
103+
err.filename = filename
104+
except:
105+
lineno = None
106+
msg = "*** " + str(err)
107+
if lineno:
108+
self.editwin.gotoline(lineno)
109+
self.errorbox("Syntax error",
110+
"There's an error in your program:\n" + msg)
111+
return 1
112+
44113
def import_module_event(self, event):
45114
filename = self.getfilename()
46115
if not filename:
@@ -75,22 +144,26 @@ def run_script_event(self, event):
75144
interp = shell.interp
76145
if (not sys.argv or
77146
os.path.basename(sys.argv[0]) != os.path.basename(filename)):
147+
# XXX Too often this discards arguments the user just set...
78148
sys.argv = [filename]
79149
interp.execfile(filename)
80150

81151
def getfilename(self):
82152
# Logic to make sure we have a saved filename
153+
# XXX Better logic would offer to save!
83154
if not self.editwin.get_saved():
84-
tkMessageBox.showerror("Not saved",
85-
"Please save first!",
86-
master=self.editwin.text)
155+
self.errorbox("Not saved",
156+
"Please save first!")
87157
self.editwin.text.focus_set()
88158
return
89159
filename = self.editwin.io.filename
90160
if not filename:
91-
tkMessageBox.showerror("No file name",
92-
"This window has no file name",
93-
master=self.editwin.text)
94-
self.editwin.text.focus_set()
161+
self.errorbox("No file name",
162+
"This window has no file name")
95163
return
96164
return filename
165+
166+
def errorbox(self, title, message):
167+
# XXX This should really be a function of EditorWindow...
168+
tkMessageBox.showerror(title, message, master=self.editwin.text)
169+
self.editwin.text.focus_set()

0 commit comments

Comments
 (0)