mirror of https://github.com/python/cpython
Merge with 3.3
This commit is contained in:
commit
a92bfa457c
|
@ -45,35 +45,55 @@ PORT = 0 # someday pass in host, port for remote debug capability
|
||||||
# internal warnings to the console. ScriptBinding.check_syntax() will
|
# internal warnings to the console. ScriptBinding.check_syntax() will
|
||||||
# temporarily redirect the stream to the shell window to display warnings when
|
# temporarily redirect the stream to the shell window to display warnings when
|
||||||
# checking user's code.
|
# checking user's code.
|
||||||
global warning_stream
|
warning_stream = sys.__stderr__ # None, at least on Windows, if no console.
|
||||||
warning_stream = sys.__stderr__
|
import warnings
|
||||||
try:
|
|
||||||
import warnings
|
def idle_formatwarning(message, category, filename, lineno, line=None):
|
||||||
except ImportError:
|
"""Format warnings the IDLE way."""
|
||||||
pass
|
|
||||||
else:
|
s = "\nWarning (from warnings module):\n"
|
||||||
def idle_showwarning(message, category, filename, lineno,
|
s += ' File \"%s\", line %s\n' % (filename, lineno)
|
||||||
file=None, line=None):
|
if line is None:
|
||||||
if file is None:
|
line = linecache.getline(filename, lineno)
|
||||||
file = warning_stream
|
line = line.strip()
|
||||||
try:
|
if line:
|
||||||
file.write(warnings.formatwarning(message, category, filename,
|
s += " %s\n" % line
|
||||||
lineno, line=line))
|
s += "%s: %s\n" % (category.__name__, message)
|
||||||
except OSError:
|
return s
|
||||||
pass ## file (probably __stderr__) is invalid, warning dropped.
|
|
||||||
warnings.showwarning = idle_showwarning
|
def idle_showwarning(
|
||||||
def idle_formatwarning(message, category, filename, lineno, line=None):
|
message, category, filename, lineno, file=None, line=None):
|
||||||
"""Format warnings the IDLE way"""
|
"""Show Idle-format warning (after replacing warnings.showwarning).
|
||||||
s = "\nWarning (from warnings module):\n"
|
|
||||||
s += ' File \"%s\", line %s\n' % (filename, lineno)
|
The differences are the formatter called, the file=None replacement,
|
||||||
if line is None:
|
which can be None, the capture of the consequence AttributeError,
|
||||||
line = linecache.getline(filename, lineno)
|
and the output of a hard-coded prompt.
|
||||||
line = line.strip()
|
"""
|
||||||
if line:
|
if file is None:
|
||||||
s += " %s\n" % line
|
file = warning_stream
|
||||||
s += "%s: %s\n>>> " % (category.__name__, message)
|
try:
|
||||||
return s
|
file.write(idle_formatwarning(
|
||||||
warnings.formatwarning = idle_formatwarning
|
message, category, filename, lineno, line=line))
|
||||||
|
file.write(">>> ")
|
||||||
|
except (AttributeError, OSError):
|
||||||
|
pass # if file (probably __stderr__) is invalid, skip warning.
|
||||||
|
|
||||||
|
_warnings_showwarning = None
|
||||||
|
|
||||||
|
def capture_warnings(capture):
|
||||||
|
"Replace warning.showwarning with idle_showwarning, or reverse."
|
||||||
|
|
||||||
|
global _warnings_showwarning
|
||||||
|
if capture:
|
||||||
|
if _warnings_showwarning is None:
|
||||||
|
_warnings_showwarning = warnings.showwarning
|
||||||
|
warnings.showwarning = idle_showwarning
|
||||||
|
else:
|
||||||
|
if _warnings_showwarning is not None:
|
||||||
|
warnings.showwarning = _warnings_showwarning
|
||||||
|
_warnings_showwarning = None
|
||||||
|
|
||||||
|
capture_warnings(True)
|
||||||
|
|
||||||
def extended_linecache_checkcache(filename=None,
|
def extended_linecache_checkcache(filename=None,
|
||||||
orig_checkcache=linecache.checkcache):
|
orig_checkcache=linecache.checkcache):
|
||||||
|
@ -1425,6 +1445,7 @@ echo "import sys; print(sys.argv)" | idle - "foobar"
|
||||||
def main():
|
def main():
|
||||||
global flist, root, use_subprocess
|
global flist, root, use_subprocess
|
||||||
|
|
||||||
|
capture_warnings(True)
|
||||||
use_subprocess = True
|
use_subprocess = True
|
||||||
enable_shell = False
|
enable_shell = False
|
||||||
enable_edit = False
|
enable_edit = False
|
||||||
|
@ -1559,7 +1580,10 @@ def main():
|
||||||
while flist.inversedict: # keep IDLE running while files are open.
|
while flist.inversedict: # keep IDLE running while files are open.
|
||||||
root.mainloop()
|
root.mainloop()
|
||||||
root.destroy()
|
root.destroy()
|
||||||
|
capture_warnings(False)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
sys.modules['PyShell'] = sys.modules['__main__']
|
sys.modules['PyShell'] = sys.modules['__main__']
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
capture_warnings(False) # Make sure turned off; see issue 18081
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
'''Test warnings replacement in PyShell.py and run.py.
|
||||||
|
|
||||||
|
This file could be expanded to include traceback overrides
|
||||||
|
(in same two modules). If so, change name.
|
||||||
|
Revise if output destination changes (http://bugs.python.org/issue18318).
|
||||||
|
Make sure warnings module is left unaltered (http://bugs.python.org/issue18081).
|
||||||
|
'''
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
from test.support import captured_stderr
|
||||||
|
|
||||||
|
import warnings
|
||||||
|
# Try to capture default showwarning before Idle modules are imported.
|
||||||
|
showwarning = warnings.showwarning
|
||||||
|
# But if we run this file within idle, we are in the middle of the run.main loop
|
||||||
|
# and default showwarnings has already been replaced.
|
||||||
|
running_in_idle = 'idle' in showwarning.__name__
|
||||||
|
|
||||||
|
from idlelib import run
|
||||||
|
from idlelib import PyShell as shell
|
||||||
|
|
||||||
|
# The following was generated from PyShell.idle_formatwarning
|
||||||
|
# and checked as matching expectation.
|
||||||
|
idlemsg = '''
|
||||||
|
Warning (from warnings module):
|
||||||
|
File "test_warning.py", line 99
|
||||||
|
Line of code
|
||||||
|
UserWarning: Test
|
||||||
|
'''
|
||||||
|
shellmsg = idlemsg + ">>> "
|
||||||
|
|
||||||
|
class RunWarnTest(unittest.TestCase):
|
||||||
|
|
||||||
|
@unittest.skipIf(running_in_idle, "Does not work when run within Idle.")
|
||||||
|
def test_showwarnings(self):
|
||||||
|
self.assertIs(warnings.showwarning, showwarning)
|
||||||
|
run.capture_warnings(True)
|
||||||
|
self.assertIs(warnings.showwarning, run.idle_showwarning_subproc)
|
||||||
|
run.capture_warnings(False)
|
||||||
|
self.assertIs(warnings.showwarning, showwarning)
|
||||||
|
|
||||||
|
def test_run_show(self):
|
||||||
|
with captured_stderr() as f:
|
||||||
|
run.idle_showwarning_subproc(
|
||||||
|
'Test', UserWarning, 'test_warning.py', 99, f, 'Line of code')
|
||||||
|
# The following uses .splitlines to erase line-ending differences
|
||||||
|
self.assertEqual(idlemsg.splitlines(), f.getvalue().splitlines())
|
||||||
|
|
||||||
|
class ShellWarnTest(unittest.TestCase):
|
||||||
|
|
||||||
|
@unittest.skipIf(running_in_idle, "Does not work when run within Idle.")
|
||||||
|
def test_showwarnings(self):
|
||||||
|
self.assertIs(warnings.showwarning, showwarning)
|
||||||
|
shell.capture_warnings(True)
|
||||||
|
self.assertIs(warnings.showwarning, shell.idle_showwarning)
|
||||||
|
shell.capture_warnings(False)
|
||||||
|
self.assertIs(warnings.showwarning, showwarning)
|
||||||
|
|
||||||
|
def test_idle_formatter(self):
|
||||||
|
# Will fail if format changed without regenerating idlemsg
|
||||||
|
s = shell.idle_formatwarning(
|
||||||
|
'Test', UserWarning, 'test_warning.py', 99, 'Line of code')
|
||||||
|
self.assertEqual(idlemsg, s)
|
||||||
|
|
||||||
|
def test_shell_show(self):
|
||||||
|
with captured_stderr() as f:
|
||||||
|
shell.idle_showwarning(
|
||||||
|
'Test', UserWarning, 'test_warning.py', 99, f, 'Line of code')
|
||||||
|
self.assertEqual(shellmsg.splitlines(), f.getvalue().splitlines())
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main(verbosity=2, exit=False)
|
|
@ -23,36 +23,46 @@ import __main__
|
||||||
|
|
||||||
LOCALHOST = '127.0.0.1'
|
LOCALHOST = '127.0.0.1'
|
||||||
|
|
||||||
try:
|
import warnings
|
||||||
import warnings
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
def idle_formatwarning_subproc(message, category, filename, lineno,
|
|
||||||
line=None):
|
|
||||||
"""Format warnings the IDLE way"""
|
|
||||||
s = "\nWarning (from warnings module):\n"
|
|
||||||
s += ' File \"%s\", line %s\n' % (filename, lineno)
|
|
||||||
if line is None:
|
|
||||||
line = linecache.getline(filename, lineno)
|
|
||||||
line = line.strip()
|
|
||||||
if line:
|
|
||||||
s += " %s\n" % line
|
|
||||||
s += "%s: %s\n" % (category.__name__, message)
|
|
||||||
return s
|
|
||||||
warnings.formatwarning = idle_formatwarning_subproc
|
|
||||||
|
|
||||||
|
def idle_showwarning_subproc(
|
||||||
|
message, category, filename, lineno, file=None, line=None):
|
||||||
|
"""Show Idle-format warning after replacing warnings.showwarning.
|
||||||
|
|
||||||
|
The only difference is the formatter called.
|
||||||
|
"""
|
||||||
|
if file is None:
|
||||||
|
file = sys.stderr
|
||||||
|
try:
|
||||||
|
file.write(PyShell.idle_formatwarning(
|
||||||
|
message, category, filename, lineno, line))
|
||||||
|
except IOError:
|
||||||
|
pass # the file (probably stderr) is invalid - this warning gets lost.
|
||||||
|
|
||||||
|
_warnings_showwarning = None
|
||||||
|
|
||||||
|
def capture_warnings(capture):
|
||||||
|
"Replace warning.showwarning with idle_showwarning_subproc, or reverse."
|
||||||
|
|
||||||
|
global _warnings_showwarning
|
||||||
|
if capture:
|
||||||
|
if _warnings_showwarning is None:
|
||||||
|
_warnings_showwarning = warnings.showwarning
|
||||||
|
warnings.showwarning = idle_showwarning_subproc
|
||||||
|
else:
|
||||||
|
if _warnings_showwarning is not None:
|
||||||
|
warnings.showwarning = _warnings_showwarning
|
||||||
|
_warnings_showwarning = None
|
||||||
|
|
||||||
|
capture_warnings(True)
|
||||||
tcl = tkinter.Tcl()
|
tcl = tkinter.Tcl()
|
||||||
|
|
||||||
|
|
||||||
def handle_tk_events(tcl=tcl):
|
def handle_tk_events(tcl=tcl):
|
||||||
"""Process any tk events that are ready to be dispatched if tkinter
|
"""Process any tk events that are ready to be dispatched if tkinter
|
||||||
has been imported, a tcl interpreter has been created and tk has been
|
has been imported, a tcl interpreter has been created and tk has been
|
||||||
loaded."""
|
loaded."""
|
||||||
tcl.eval("update")
|
tcl.eval("update")
|
||||||
|
|
||||||
|
|
||||||
# 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, exit and interruptable (the main thread) flags:
|
# completion, exit and interruptable (the main thread) flags:
|
||||||
|
@ -91,6 +101,8 @@ def main(del_exitfunc=False):
|
||||||
print("IDLE Subprocess: no IP port passed in sys.argv.",
|
print("IDLE Subprocess: no IP port passed in sys.argv.",
|
||||||
file=sys.__stderr__)
|
file=sys.__stderr__)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
capture_warnings(True)
|
||||||
sys.argv[:] = [""]
|
sys.argv[:] = [""]
|
||||||
sockthread = threading.Thread(target=manage_socket,
|
sockthread = threading.Thread(target=manage_socket,
|
||||||
name='SockThread',
|
name='SockThread',
|
||||||
|
@ -118,6 +130,7 @@ def main(del_exitfunc=False):
|
||||||
exit_now = True
|
exit_now = True
|
||||||
continue
|
continue
|
||||||
except SystemExit:
|
except SystemExit:
|
||||||
|
capture_warnings(False)
|
||||||
raise
|
raise
|
||||||
except:
|
except:
|
||||||
type, value, tb = sys.exc_info()
|
type, value, tb = sys.exc_info()
|
||||||
|
@ -247,6 +260,7 @@ def exit():
|
||||||
if no_exitfunc:
|
if no_exitfunc:
|
||||||
import atexit
|
import atexit
|
||||||
atexit._clear()
|
atexit._clear()
|
||||||
|
capture_warnings(False)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
class MyRPCServer(rpc.RPCServer):
|
class MyRPCServer(rpc.RPCServer):
|
||||||
|
@ -386,3 +400,5 @@ class Executive(object):
|
||||||
sys.last_value = val
|
sys.last_value = val
|
||||||
item = StackViewer.StackTreeItem(flist, tb)
|
item = StackViewer.StackTreeItem(flist, tb)
|
||||||
return RemoteObjectBrowser.remote_object_tree_item(item)
|
return RemoteObjectBrowser.remote_object_tree_item(item)
|
||||||
|
|
||||||
|
capture_warnings(False) # Make sure turned off; see issue 18081
|
||||||
|
|
Loading…
Reference in New Issue