Changeset 391 for python/trunk/Lib/idlelib/PyShell.py
- Timestamp:
- Mar 19, 2014, 11:31:01 PM (11 years ago)
- Location:
- python/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
python/trunk
-
Property svn:mergeinfo
set to
/python/vendor/Python-2.7.6 merged eligible /python/vendor/current merged eligible
-
Property svn:mergeinfo
set to
-
python/trunk/Lib/idlelib/PyShell.py
r2 r391 12 12 import traceback 13 13 import types 14 import macosxSupport14 import io 15 15 16 16 import linecache 17 17 from code import InteractiveInterpreter 18 from platform import python_version 18 19 19 20 try: … … 25 26 import tkMessageBox 26 27 27 from EditorWindow import EditorWindow, fixwordbreaks28 from FileList import FileList29 from ColorDelegator import ColorDelegator30 from UndoDelegator import UndoDelegator31 from OutputWindow import OutputWindow32 from configHandler import idleConf33 import idlever34 35 import rpc 36 importDebugger37 import RemoteDebugger 28 from idlelib.EditorWindow import EditorWindow, fixwordbreaks 29 from idlelib.FileList import FileList 30 from idlelib.ColorDelegator import ColorDelegator 31 from idlelib.UndoDelegator import UndoDelegator 32 from idlelib.OutputWindow import OutputWindow 33 from idlelib.configHandler import idleConf 34 from idlelib import idlever 35 from idlelib import rpc 36 from idlelib import Debugger 37 from idlelib import RemoteDebugger 38 from idlelib import macosxSupport 38 39 39 40 IDENTCHARS = string.ascii_letters + string.digits + "_" 40 LOCALHOST = '127.0.0.1' 41 HOST = '127.0.0.1' # python execution server on localhost loopback 42 PORT = 0 # someday pass in host, port for remote debug capability 41 43 42 44 try: … … 49 51 # temporarily redirect the stream to the shell window to display warnings when 50 52 # checking user's code. 51 global warning_stream 52 warning_stream = sys.__stderr__ 53 try: 54 import warnings 55 except ImportError: 56 pass 57 else: 58 def idle_showwarning(message, category, filename, lineno, 59 file=None, line=None): 53 warning_stream = sys.__stderr__ # None, at least on Windows, if no console. 54 import warnings 55 56 def idle_formatwarning(message, category, filename, lineno, line=None): 57 """Format warnings the IDLE way.""" 58 59 s = "\nWarning (from warnings module):\n" 60 s += ' File \"%s\", line %s\n' % (filename, lineno) 61 if line is None: 62 line = linecache.getline(filename, lineno) 63 line = line.strip() 64 if line: 65 s += " %s\n" % line 66 s += "%s: %s\n" % (category.__name__, message) 67 return s 68 69 def idle_showwarning( 70 message, category, filename, lineno, file=None, line=None): 71 """Show Idle-format warning (after replacing warnings.showwarning). 72 73 The differences are the formatter called, the file=None replacement, 74 which can be None, the capture of the consequence AttributeError, 75 and the output of a hard-coded prompt. 76 """ 77 if file is None: 60 78 file = warning_stream 61 try: 62 file.write(warnings.formatwarning(message, category, filename,\ 63 lineno, file=file, line=line)) 64 except IOError: 65 pass ## file (probably __stderr__) is invalid, warning dropped. 66 warnings.showwarning = idle_showwarning 67 def idle_formatwarning(message, category, filename, lineno, 68 file=None, line=None): 69 """Format warnings the IDLE way""" 70 s = "\nWarning (from warnings module):\n" 71 s += ' File \"%s\", line %s\n' % (filename, lineno) 72 line = linecache.getline(filename, lineno).strip() \ 73 if line is None else line 74 if line: 75 s += " %s\n" % line 76 s += "%s: %s\n>>> " % (category.__name__, message) 77 return s 78 warnings.formatwarning = idle_formatwarning 79 try: 80 file.write(idle_formatwarning( 81 message, category, filename, lineno, line=line)) 82 file.write(">>> ") 83 except (AttributeError, IOError): 84 pass # if file (probably __stderr__) is invalid, skip warning. 85 86 _warnings_showwarning = None 87 88 def capture_warnings(capture): 89 "Replace warning.showwarning with idle_showwarning, or reverse." 90 91 global _warnings_showwarning 92 if capture: 93 if _warnings_showwarning is None: 94 _warnings_showwarning = warnings.showwarning 95 warnings.showwarning = idle_showwarning 96 else: 97 if _warnings_showwarning is not None: 98 warnings.showwarning = _warnings_showwarning 99 _warnings_showwarning = None 100 101 capture_warnings(True) 79 102 80 103 def extended_linecache_checkcache(filename=None, … … 84 107 Rather than repeating the linecache code, patch it to save the 85 108 <pyshell#...> entries, call the original linecache.checkcache() 86 ( which destroysthem), and then restore the saved entries.109 (skipping them), and then restore the saved entries. 87 110 88 111 orig_checkcache is bound at definition time to the original 89 112 method, allowing it to be patched. 90 91 113 """ 92 114 cache = linecache.cache 93 115 save = {} 94 for filename in cache.keys():95 if filename[:1] + filename[-1:] == '<>':96 save[ filename] = cache[filename]97 orig_checkcache( )116 for key in list(cache): 117 if key[:1] + key[-1:] == '<>': 118 save[key] = cache.pop(key) 119 orig_checkcache(filename) 98 120 cache.update(save) 99 121 … … 115 137 'breakpoints.lst') 116 138 # whenever a file is changed, restore breakpoints 117 if self.io.filename: self.restore_file_breaks()118 139 def filename_changed_hook(old_hook=self.io.filename_change_hook, 119 140 self=self): … … 121 142 old_hook() 122 143 self.io.set_filename_change_hook(filename_changed_hook) 123 124 rmenu_specs = [("Set Breakpoint", "<<set-breakpoint-here>>"), 125 ("Clear Breakpoint", "<<clear-breakpoint-here>>")] 144 if self.io.filename: 145 self.restore_file_breaks() 146 147 rmenu_specs = [ 148 ("Cut", "<<cut>>", "rmenu_check_cut"), 149 ("Copy", "<<copy>>", "rmenu_check_copy"), 150 ("Paste", "<<paste>>", "rmenu_check_paste"), 151 ("Set Breakpoint", "<<set-breakpoint-here>>", None), 152 ("Clear Breakpoint", "<<clear-breakpoint-here>>", None) 153 ] 126 154 127 155 def set_breakpoint(self, lineno): … … 208 236 filename = self.io.filename 209 237 try: 210 lines = open(self.breakpointPath,"r").readlines() 238 with open(self.breakpointPath,"r") as old_file: 239 lines = old_file.readlines() 211 240 except IOError: 212 241 lines = [] 213 new_file = open(self.breakpointPath,"w") 214 for line in lines: 215 if not line.startswith(filename + '='): 216 new_file.write(line) 217 self.update_breakpoints() 218 breaks = self.breakpoints 219 if breaks: 220 new_file.write(filename + '=' + str(breaks) + '\n') 221 new_file.close() 242 try: 243 with open(self.breakpointPath,"w") as new_file: 244 for line in lines: 245 if not line.startswith(filename + '='): 246 new_file.write(line) 247 self.update_breakpoints() 248 breaks = self.breakpoints 249 if breaks: 250 new_file.write(filename + '=' + str(breaks) + '\n') 251 except IOError as err: 252 if not getattr(self.root, "breakpoint_error_displayed", False): 253 self.root.breakpoint_error_displayed = True 254 tkMessageBox.showerror(title='IDLE Error', 255 message='Unable to update breakpoint list:\n%s' 256 % str(err), 257 parent=self.text) 222 258 223 259 def restore_file_breaks(self): 224 260 self.text.update() # this enables setting "BREAK" tags to be visible 261 if self.io is None: 262 # can happen if IDLE closes due to the .update() call 263 return 225 264 filename = self.io.filename 226 265 if filename is None: … … 244 283 lines = [] 245 284 for index in range(0, len(ranges), 2): 246 lineno = int(float(ranges[index] ))247 end = int(float(ranges[index+1] ))285 lineno = int(float(ranges[index].string)) 286 end = int(float(ranges[index+1].string)) 248 287 while lineno < end: 249 288 lines.append(lineno) … … 306 345 }) 307 346 347 def removecolors(self): 348 # Don't remove shell color tags before "iomark" 349 for tag in self.tagdefs: 350 self.tag_remove(tag, "iomark", "end") 351 308 352 class ModifiedUndoDelegator(UndoDelegator): 309 353 "Extend base class: forbid insert/delete before the I/O mark" … … 343 387 self.save_warnings_filters = None 344 388 self.restarting = False 345 self.subprocess_arglist = self.build_subprocess_arglist() 346 347 port = 8833 389 self.subprocess_arglist = None 390 self.port = PORT 391 self.original_compiler_flags = self.compile.compiler.flags 392 393 _afterid = None 348 394 rpcclt = None 349 395 rpcpid = None 350 396 351 397 def spawn_subprocess(self): 398 if self.subprocess_arglist is None: 399 self.subprocess_arglist = self.build_subprocess_arglist() 352 400 args = self.subprocess_arglist 353 401 self.rpcpid = os.spawnv(os.P_NOWAIT, sys.executable, args) 354 402 355 403 def build_subprocess_arglist(self): 404 assert (self.port!=0), ( 405 "Socket should have been assigned a port number.") 356 406 w = ['-W' + s for s in sys.warnoptions] 357 407 if 1/2 > 0: # account for new division … … 374 424 375 425 def start_subprocess(self): 376 # spawning first avoids passing a listening socket to the subprocess 377 self.spawn_subprocess() 378 #time.sleep(20) # test to simulate GUI not accepting connection 379 addr = (LOCALHOST, self.port) 380 # Idle starts listening for connection on localhost 426 addr = (HOST, self.port) 427 # GUI makes several attempts to acquire socket, listens for connection 381 428 for i in range(3): 382 429 time.sleep(i) … … 384 431 self.rpcclt = MyRPCClient(addr) 385 432 break 386 except socket.error ,err:433 except socket.error as err: 387 434 pass 388 435 else: 389 436 self.display_port_binding_error() 390 437 return None 438 # if PORT was 0, system will assign an 'ephemeral' port. Find it out: 439 self.port = self.rpcclt.listening_sock.getsockname()[1] 440 # if PORT was not 0, probably working with a remote execution server 441 if PORT != 0: 442 # To allow reconnection within the 2MSL wait (cf. Stevens TCP 443 # V1, 18.6), set SO_REUSEADDR. Note that this can be problematic 444 # on Windows since the implementation allows two active sockets on 445 # the same address! 446 self.rpcclt.listening_sock.setsockopt(socket.SOL_SOCKET, 447 socket.SO_REUSEADDR, 1) 448 self.spawn_subprocess() 449 #time.sleep(20) # test to simulate GUI not accepting connection 391 450 # Accept the connection from the Python execution server 392 451 self.rpcclt.listening_sock.settimeout(10) 393 452 try: 394 453 self.rpcclt.accept() 395 except socket.timeout ,err:454 except socket.timeout as err: 396 455 self.display_no_subprocess_error() 397 456 return None 398 self.rpcclt.register("stdin", self.tkconsole) 457 self.rpcclt.register("console", self.tkconsole) 458 self.rpcclt.register("stdin", self.tkconsole.stdin) 399 459 self.rpcclt.register("stdout", self.tkconsole.stdout) 400 460 self.rpcclt.register("stderr", self.tkconsole.stderr) … … 402 462 self.rpcclt.register("linecache", linecache) 403 463 self.rpcclt.register("interp", self) 404 self.transfer_path( )464 self.transfer_path(with_cwd=True) 405 465 self.poll_subprocess() 406 466 return self.rpcclt 407 467 408 def restart_subprocess(self ):468 def restart_subprocess(self, with_cwd=False): 409 469 if self.restarting: 410 470 return self.rpcclt … … 427 487 try: 428 488 self.rpcclt.accept() 429 except socket.timeout ,err:489 except socket.timeout as err: 430 490 self.display_no_subprocess_error() 431 491 return None 432 self.transfer_path() 492 self.transfer_path(with_cwd=with_cwd) 493 console.stop_readline() 433 494 # annotate restart in shell window and mark it 434 495 console.text.delete("iomark", "end-1c") … … 447 508 # reload remote debugger breakpoints for all PyShellEditWindows 448 509 debug.load_breakpoints() 510 self.compile.compiler.flags = self.original_compiler_flags 449 511 self.restarting = False 450 512 return self.rpcclt … … 457 519 458 520 def kill_subprocess(self): 521 if self._afterid is not None: 522 self.tkconsole.text.after_cancel(self._afterid) 459 523 try: 460 524 self.rpcclt.close() … … 479 543 return 480 544 481 def transfer_path(self): 545 def transfer_path(self, with_cwd=False): 546 if with_cwd: # Issue 13506 547 path = [''] # include Current Working Directory 548 path.extend(sys.path) 549 else: 550 path = sys.path 551 482 552 self.runcommand("""if 1: 483 553 import sys as _sys 484 554 _sys.path = %r 485 555 del _sys 486 \n""" % ( sys.path,))556 \n""" % (path,)) 487 557 488 558 active_seq = None … … 523 593 # Reschedule myself 524 594 if not self.tkconsole.closing: 525 self. tkconsole.text.after(self.tkconsole.pollinterval,526 595 self._afterid = self.tkconsole.text.after( 596 self.tkconsole.pollinterval, self.poll_subprocess) 527 597 528 598 debugger = None … … 540 610 method we allow the subprocess to unblock. After a bit the shell 541 611 requests the subprocess to open the remote stack viewer which returns a 542 static object looking at the last exceptio pn. It is queried through612 static object looking at the last exception. It is queried through 543 613 the RPC mechanism. 544 614 … … 548 618 549 619 def remote_stack_viewer(self): 550 import RemoteObjectBrowser620 from idlelib import RemoteObjectBrowser 551 621 oid = self.rpcclt.remotequeue("exec", "stackviewer", ("flist",), {}) 552 622 if oid is None: … … 554 624 return 555 625 item = RemoteObjectBrowser.StubObjectTreeItem(self.rpcclt, oid) 556 from TreeWidget import ScrolledCanvas, TreeNode626 from idlelib.TreeWidget import ScrolledCanvas, TreeNode 557 627 top = Toplevel(self.tkconsole.root) 558 628 theme = idleConf.GetOption('main','Theme','name') … … 594 664 warnings.filterwarnings(action="error", category=SyntaxWarning) 595 665 if isinstance(source, types.UnicodeType): 596 import IOBinding666 from idlelib import IOBinding 597 667 try: 598 668 source = source.encode(IOBinding.encoding) … … 755 825 tkMessageBox.showerror( 756 826 "Port Binding Error", 757 "IDLE can't bind TCP/IP port 8833, which is necessary to " 758 "communicate with its Python execution server. Either " 759 "no networking is installed on this computer or another " 760 "process (another IDLE?) is using the port. Run IDLE with the -n " 761 "command line switch to start without a subprocess and refer to " 762 "Help/IDLE Help 'Running without a subprocess' for further " 763 "details.", 827 "IDLE can't bind to a TCP/IP port, which is necessary to " 828 "communicate with its Python execution server. This might be " 829 "because no networking is installed on this computer. " 830 "Run IDLE with the -n command line switch to start without a " 831 "subprocess and refer to Help/IDLE Help 'Running without a " 832 "subprocess' for further details.", 764 833 master=self.tkconsole.text) 765 834 … … 782 851 class PyShell(OutputWindow): 783 852 784 shell_title = "Python Shell"853 shell_title = "Python " + python_version() + " Shell" 785 854 786 855 # Override classes … … 799 868 800 869 if macosxSupport.runningAsOSXApp(): 801 del menu_specs[-3]802 870 menu_specs[-2] = ("windows", "_Window") 803 871 804 872 805 873 # New classes 806 from IdleHistory import History874 from idlelib.IdleHistory import History 807 875 808 876 def __init__(self, flist=None): … … 842 910 self.save_stderr = sys.stderr 843 911 self.save_stdin = sys.stdin 844 import IOBinding 845 self.stdout = PseudoFile(self, "stdout", IOBinding.encoding) 846 self.stderr = PseudoFile(self, "stderr", IOBinding.encoding) 847 self.console = PseudoFile(self, "console", IOBinding.encoding) 912 from idlelib import IOBinding 913 self.stdin = PseudoInputFile(self, "stdin", IOBinding.encoding) 914 self.stdout = PseudoOutputFile(self, "stdout", IOBinding.encoding) 915 self.stderr = PseudoOutputFile(self, "stderr", IOBinding.encoding) 916 self.console = PseudoOutputFile(self, "console", IOBinding.encoding) 848 917 if not use_subprocess: 849 918 sys.stdout = self.stdout 850 919 sys.stderr = self.stderr 851 sys.stdin = self 920 sys.stdin = self.stdin 852 921 # 853 922 self.history = self.History(self.text) … … 863 932 endoffile = False 864 933 closing = False 934 _stop_readline_flag = False 865 935 866 936 def set_warning_stream(self, stream): … … 938 1008 if response is False: 939 1009 return "cancel" 940 if self.reading: 941 self.top.quit() 1010 self.stop_readline() 942 1011 self.canceled = True 943 1012 self.closing = True 944 # Wait for poll_subprocess() rescheduling to stop945 self.text.after(2 * self.pollinterval, self.close2)946 947 def close2(self):948 1013 return EditorWindow.close(self) 949 1014 … … 974 1039 'Type "copyright", "credits" or "license()" for more information.' 975 1040 976 firewallmessage = """977 ****************************************************************978 Personal firewall software may warn about the connection IDLE979 makes to its subprocess using this computer's internal loopback980 interface. This connection is not visible on any external981 interface and no data is sent to or received from the Internet.982 ****************************************************************983 """984 985 1041 def begin(self): 986 1042 self.resetoutput() … … 993 1049 else: 994 1050 nosub = "==== No Subprocess ====" 995 self.write("Python %s on %s\n%s\n%s\nIDLE %s %s\n" % 996 (sys.version, sys.platform, self.COPYRIGHT, 997 self.firewallmessage, idlever.IDLE_VERSION, nosub)) 1051 self.write("Python %s on %s\n%s\n%s" % 1052 (sys.version, sys.platform, self.COPYRIGHT, nosub)) 998 1053 self.showprompt() 999 1054 import Tkinter … … 1001 1056 return True 1002 1057 1058 def stop_readline(self): 1059 if not self.reading: # no nested mainloop to exit. 1060 return 1061 self._stop_readline_flag = True 1062 self.top.quit() 1063 1003 1064 def readline(self): 1004 1065 save = self.reading … … 1008 1069 finally: 1009 1070 self.reading = save 1071 if self._stop_readline_flag: 1072 self._stop_readline_flag = False 1073 return "" 1010 1074 line = self.text.get("iomark", "end-1c") 1011 1075 if len(line) == 0: # may be EOF if we quit our mainloop with Ctrl-C 1012 1076 line = "\n" 1013 1077 if isinstance(line, unicode): 1014 import IOBinding1078 from idlelib import IOBinding 1015 1079 try: 1016 1080 line = line.encode(IOBinding.encoding) … … 1190 1254 master=self.text) 1191 1255 return 1192 from StackViewer import StackBrowser1256 from idlelib.StackViewer import StackBrowser 1193 1257 sv = StackBrowser(self.root, self.flist) 1194 1258 … … 1198 1262 1199 1263 def restart_shell(self, event=None): 1200 self.interp.restart_subprocess() 1264 "Callback for Run/Restart Shell Cntl-F6" 1265 self.interp.restart_subprocess(with_cwd=True) 1201 1266 1202 1267 def showprompt(self): … … 1214 1279 source = self.text.get("iomark", "end-1c") 1215 1280 if self.history: 1216 self.history. history_store(source)1281 self.history.store(source) 1217 1282 if self.text.get("end-2c") != "\n": 1218 1283 self.text.insert("end-1c", "\n") … … 1233 1298 raise KeyboardInterrupt 1234 1299 1235 class PseudoFile(object): 1300 def rmenu_check_cut(self): 1301 try: 1302 if self.text.compare('sel.first', '<', 'iomark'): 1303 return 'disabled' 1304 except TclError: # no selection, so the index 'sel.first' doesn't exist 1305 return 'disabled' 1306 return super(PyShell, self).rmenu_check_cut() 1307 1308 def rmenu_check_paste(self): 1309 if self.text.compare('insert', '<', 'iomark'): 1310 return 'disabled' 1311 return super(PyShell, self).rmenu_check_paste() 1312 1313 class PseudoFile(io.TextIOBase): 1236 1314 1237 1315 def __init__(self, shell, tags, encoding=None): … … 1239 1317 self.tags = tags 1240 1318 self.softspace = 0 1241 self.encoding = encoding 1242 1243 def write(self, s): 1244 self.shell.write(s, self.tags) 1245 1246 def writelines(self, l): 1247 map(self.write, l) 1248 1249 def flush(self): 1250 pass 1319 self._encoding = encoding 1320 1321 @property 1322 def encoding(self): 1323 return self._encoding 1324 1325 @property 1326 def name(self): 1327 return '<%s>' % self.tags 1251 1328 1252 1329 def isatty(self): 1253 1330 return True 1331 1332 1333 class PseudoOutputFile(PseudoFile): 1334 1335 def writable(self): 1336 return True 1337 1338 def write(self, s): 1339 if self.closed: 1340 raise ValueError("write to closed file") 1341 if not isinstance(s, (basestring, bytearray)): 1342 raise TypeError('must be string, not ' + type(s).__name__) 1343 return self.shell.write(s, self.tags) 1344 1345 1346 class PseudoInputFile(PseudoFile): 1347 1348 def __init__(self, shell, tags, encoding=None): 1349 PseudoFile.__init__(self, shell, tags, encoding) 1350 self._line_buffer = '' 1351 1352 def readable(self): 1353 return True 1354 1355 def read(self, size=-1): 1356 if self.closed: 1357 raise ValueError("read from closed file") 1358 if size is None: 1359 size = -1 1360 elif not isinstance(size, int): 1361 raise TypeError('must be int, not ' + type(size).__name__) 1362 result = self._line_buffer 1363 self._line_buffer = '' 1364 if size < 0: 1365 while True: 1366 line = self.shell.readline() 1367 if not line: break 1368 result += line 1369 else: 1370 while len(result) < size: 1371 line = self.shell.readline() 1372 if not line: break 1373 result += line 1374 self._line_buffer = result[size:] 1375 result = result[:size] 1376 return result 1377 1378 def readline(self, size=-1): 1379 if self.closed: 1380 raise ValueError("read from closed file") 1381 if size is None: 1382 size = -1 1383 elif not isinstance(size, int): 1384 raise TypeError('must be int, not ' + type(size).__name__) 1385 line = self._line_buffer or self.shell.readline() 1386 if size < 0: 1387 size = len(line) 1388 self._line_buffer = line[size:] 1389 return line[:size] 1390 1391 def close(self): 1392 self.shell.close() 1254 1393 1255 1394 … … 1310 1449 global flist, root, use_subprocess 1311 1450 1451 capture_warnings(True) 1312 1452 use_subprocess = True 1313 1453 enable_shell = False … … 1319 1459 try: 1320 1460 opts, args = getopt.getopt(sys.argv[1:], "c:deihnr:st:") 1321 except getopt.error ,msg:1461 except getopt.error as msg: 1322 1462 sys.stderr.write("Error: %s\n" % str(msg)) 1323 1463 sys.stderr.write(usage_msg) … … 1372 1512 for dir in pathx: 1373 1513 dir = os.path.abspath(dir) 1374 if not dirin sys.path:1514 if dir not in sys.path: 1375 1515 sys.path.insert(0, dir) 1376 1516 else: … … 1382 1522 'editor-on-startup', type='bool') 1383 1523 enable_edit = enable_edit or edit_start 1384 enable_shell = enable_shell or not e dit_start1524 enable_shell = enable_shell or not enable_edit 1385 1525 # start editor and/or shell windows: 1386 1526 root = Tk(className="Idle") … … 1393 1533 if enable_edit: 1394 1534 if not (cmd or script): 1395 for filename in args: 1396 flist.open(filename) 1535 for filename in args[:]: 1536 if flist.open(filename) is None: 1537 # filename is a directory actually, disconsider it 1538 args.remove(filename) 1397 1539 if not args: 1398 1540 flist.new() … … 1430 1572 shell.interp.execfile(script) 1431 1573 1432 root.mainloop() 1574 # Check for problematic OS X Tk versions and print a warning message 1575 # in the IDLE shell window; this is less intrusive than always opening 1576 # a separate window. 1577 tkversionwarning = macosxSupport.tkVersionWarning(root) 1578 if tkversionwarning: 1579 shell.interp.runcommand(''.join(("print('", tkversionwarning, "')"))) 1580 1581 while flist.inversedict: # keep IDLE running while files are open. 1582 root.mainloop() 1433 1583 root.destroy() 1584 capture_warnings(False) 1434 1585 1435 1586 if __name__ == "__main__": 1436 1587 sys.modules['PyShell'] = sys.modules['__main__'] 1437 1588 main() 1589 1590 capture_warnings(False) # Make sure turned off; see issue 18081
Note:
See TracChangeset
for help on using the changeset viewer.