Commit 49a5fe10 authored by Kurt B. Kaiser's avatar Kurt B. Kaiser

Redirect the warning stream to the shell during the ScriptBinding check of user code

and format the warning similarly to an exception for both that check and for
warnings raised in the subprocess.

M NEWS.txt
M Pyshell.py
M ScriptBinding.py
M run.py
parent 9ec3e3b6
...@@ -3,6 +3,10 @@ What's New in IDLE 1.1a0? ...@@ -3,6 +3,10 @@ What's New in IDLE 1.1a0?
*Release date: XX-XXX-2004* *Release date: XX-XXX-2004*
- Redirect the warning stream to the shell during the ScriptBinding check of
user code and format the warning similarly to an exception for both that
check and for runtime warnings raised in the subprocess.
- CodeContext hint pane visibility state is now persistent across sessions. - CodeContext hint pane visibility state is now persistent across sessions.
The pane no longer appears in the shell window. Added capability to limit The pane no longer appears in the shell window. Added capability to limit
extensions to shell window or editor windows. Noam Raphael addition extensions to shell window or editor windows. Noam Raphael addition
......
...@@ -44,16 +44,34 @@ try: ...@@ -44,16 +44,34 @@ try:
except ImportError: except ImportError:
SIGTERM = 15 SIGTERM = 15
# Change warnings module to write to sys.__stderr__ # Override warnings module to write to warning_stream. Initialize to send IDLE
# internal warnings to the console. ScriptBinding.check_syntax() will
# temporarily redirect the stream to the shell window to display warnings when
# checking user's code.
global warning_stream
warning_stream = sys.__stderr__
try: try:
import warnings import warnings
except ImportError: except ImportError:
pass pass
else: else:
def idle_showwarning(message, category, filename, lineno): def idle_showwarning(message, category, filename, lineno):
file = sys.__stderr__ file = warning_stream
file.write(warnings.formatwarning(message, category, filename, lineno)) try:
file.write(warnings.formatwarning(message, category, filename, lineno))
except IOError:
pass ## file (probably __stderr__) is invalid, warning dropped.
warnings.showwarning = idle_showwarning warnings.showwarning = idle_showwarning
def idle_formatwarning(message, category, filename, lineno):
"""Format warnings the IDLE way"""
s = "\nWarning (from warnings module):\n"
s += ' File \"%s\", line %s\n' % (filename, lineno)
line = linecache.getline(filename, lineno).strip()
if line:
s += " %s\n" % line
s += "%s: %s\n>>> " % (category.__name__, message)
return s
warnings.formatwarning = idle_formatwarning
def extended_linecache_checkcache(orig_checkcache=linecache.checkcache): def extended_linecache_checkcache(orig_checkcache=linecache.checkcache):
"""Extend linecache.checkcache to preserve the <pyshell#...> entries """Extend linecache.checkcache to preserve the <pyshell#...> entries
...@@ -815,6 +833,13 @@ class PyShell(OutputWindow): ...@@ -815,6 +833,13 @@ class PyShell(OutputWindow):
endoffile = False endoffile = False
closing = False closing = False
def set_warning_stream(self, stream):
global warning_stream
warning_stream = stream
def get_warning_stream(self):
return warning_stream
def toggle_debugger(self, event=None): def toggle_debugger(self, event=None):
if self.executing: if self.executing:
tkMessageBox.showerror("Don't debug now", tkMessageBox.showerror("Don't debug now",
......
...@@ -82,6 +82,9 @@ class ScriptBinding: ...@@ -82,6 +82,9 @@ class ScriptBinding:
return True return True
def checksyntax(self, filename): def checksyntax(self, filename):
self.shell = shell = self.flist.open_shell()
saved_stream = shell.get_warning_stream()
shell.set_warning_stream(shell.stderr)
f = open(filename, 'r') f = open(filename, 'r')
source = f.read() source = f.read()
f.close() f.close()
...@@ -92,20 +95,23 @@ class ScriptBinding: ...@@ -92,20 +95,23 @@ class ScriptBinding:
text = self.editwin.text text = self.editwin.text
text.tag_remove("ERROR", "1.0", "end") text.tag_remove("ERROR", "1.0", "end")
try: try:
# If successful, return the compiled code
return compile(source, filename, "exec")
except (SyntaxError, OverflowError), err:
try: try:
msg, (errorfilename, lineno, offset, line) = err # If successful, return the compiled code
if not errorfilename: return compile(source, filename, "exec")
err.args = msg, (filename, lineno, offset, line) except (SyntaxError, OverflowError), err:
err.filename = filename try:
self.colorize_syntax_error(msg, lineno, offset) msg, (errorfilename, lineno, offset, line) = err
except: if not errorfilename:
msg = "*** " + str(err) err.args = msg, (filename, lineno, offset, line)
self.errorbox("Syntax error", err.filename = filename
"There's an error in your program:\n" + msg) self.colorize_syntax_error(msg, lineno, offset)
return False except:
msg = "*** " + str(err)
self.errorbox("Syntax error",
"There's an error in your program:\n" + msg)
return False
finally:
shell.set_warning_stream(saved_stream)
def colorize_syntax_error(self, msg, lineno, offset): def colorize_syntax_error(self, msg, lineno, offset):
text = self.editwin.text text = self.editwin.text
...@@ -135,10 +141,7 @@ class ScriptBinding: ...@@ -135,10 +141,7 @@ class ScriptBinding:
code = self.checksyntax(filename) code = self.checksyntax(filename)
if not code: if not code:
return return
flist = self.editwin.flist shell = self.shell
shell = flist.open_shell()
if not shell:
return # couldn't open the shell
interp = shell.interp interp = shell.interp
if PyShell.use_subprocess: if PyShell.use_subprocess:
shell.restart_shell() shell.restart_shell()
...@@ -156,6 +159,9 @@ class ScriptBinding: ...@@ -156,6 +159,9 @@ class ScriptBinding:
del _filename, _sys, _basename, _os del _filename, _sys, _basename, _os
\n""" % (filename, dirname)) \n""" % (filename, dirname))
interp.prepend_syspath(filename) interp.prepend_syspath(filename)
# XXX KBK 03Jul04 When run w/o subprocess, runtime warnings still
# go to __stderr__. With subprocess, they go to the shell.
# Need to change streams in PyShell.ModifiedInterpreter.
interp.runcode(code) interp.runcode(code)
def getfilename(self): def getfilename(self):
......
import sys import sys
import os import os
import linecache
import time import time
import socket import socket
import traceback import traceback
...@@ -17,6 +18,22 @@ import __main__ ...@@ -17,6 +18,22 @@ import __main__
LOCALHOST = '127.0.0.1' LOCALHOST = '127.0.0.1'
try:
import warnings
except ImportError:
pass
else:
def idle_formatwarning_subproc(message, category, filename, lineno):
"""Format warnings the IDLE way"""
s = "\nWarning (from warnings module):\n"
s += ' File \"%s\", line %s\n' % (filename, lineno)
line = linecache.getline(filename, lineno).strip()
if line:
s += " %s\n" % line
s += "%s: %s\n" % (category.__name__, message)
return s
warnings.formatwarning = idle_formatwarning_subproc
# Thread shared globals: Establish a queue between a subthread (which handles # Thread shared globals: Establish a queue between a subthread (which handles
# the socket) and the main thread (which runs user code), plus global # the socket) and the main thread (which runs user code), plus global
# completion and exit flags: # completion and exit flags:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment