Ignore:
Timestamp:
Mar 19, 2014, 11:31:01 PM (11 years ago)
Author:
dmik
Message:

python: Merge vendor 2.7.6 to trunk.

Location:
python/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • python/trunk

  • python/trunk/Lib/idlelib/PyShell.py

    r2 r391  
    1212import traceback
    1313import types
    14 import macosxSupport
     14import io
    1515
    1616import linecache
    1717from code import InteractiveInterpreter
     18from platform import python_version
    1819
    1920try:
     
    2526import tkMessageBox
    2627
    27 from EditorWindow import EditorWindow, fixwordbreaks
    28 from FileList import FileList
    29 from ColorDelegator import ColorDelegator
    30 from UndoDelegator import UndoDelegator
    31 from OutputWindow import OutputWindow
    32 from configHandler import idleConf
    33 import idlever
    34 
    35 import rpc
    36 import Debugger
    37 import RemoteDebugger
     28from idlelib.EditorWindow import EditorWindow, fixwordbreaks
     29from idlelib.FileList import FileList
     30from idlelib.ColorDelegator import ColorDelegator
     31from idlelib.UndoDelegator import UndoDelegator
     32from idlelib.OutputWindow import OutputWindow
     33from idlelib.configHandler import idleConf
     34from idlelib import idlever
     35from idlelib import rpc
     36from idlelib import Debugger
     37from idlelib import RemoteDebugger
     38from idlelib import macosxSupport
    3839
    3940IDENTCHARS = string.ascii_letters + string.digits + "_"
    40 LOCALHOST = '127.0.0.1'
     41HOST = '127.0.0.1' # python execution server on localhost loopback
     42PORT = 0  # someday pass in host, port for remote debug capability
    4143
    4244try:
     
    4951# temporarily redirect the stream to the shell window to display warnings when
    5052# 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):
     53warning_stream = sys.__stderr__  # None, at least on Windows, if no console.
     54import warnings
     55
     56def 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
     69def 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:
    6078        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
     88def 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
     101capture_warnings(True)
    79102
    80103def extended_linecache_checkcache(filename=None,
     
    84107    Rather than repeating the linecache code, patch it to save the
    85108    <pyshell#...> entries, call the original linecache.checkcache()
    86     (which destroys them), and then restore the saved entries.
     109    (skipping them), and then restore the saved entries.
    87110
    88111    orig_checkcache is bound at definition time to the original
    89112    method, allowing it to be patched.
    90 
    91113    """
    92114    cache = linecache.cache
    93115    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)
    98120    cache.update(save)
    99121
     
    115137                                           'breakpoints.lst')
    116138        # whenever a file is changed, restore breakpoints
    117         if self.io.filename: self.restore_file_breaks()
    118139        def filename_changed_hook(old_hook=self.io.filename_change_hook,
    119140                                  self=self):
     
    121142            old_hook()
    122143        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    ]
    126154
    127155    def set_breakpoint(self, lineno):
     
    208236        filename = self.io.filename
    209237        try:
    210             lines = open(self.breakpointPath,"r").readlines()
     238            with open(self.breakpointPath,"r") as old_file:
     239                lines = old_file.readlines()
    211240        except IOError:
    212241            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)
    222258
    223259    def restore_file_breaks(self):
    224260        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
    225264        filename = self.io.filename
    226265        if filename is None:
     
    244283        lines = []
    245284        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))
    248287            while lineno < end:
    249288                lines.append(lineno)
     
    306345        })
    307346
     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
    308352class ModifiedUndoDelegator(UndoDelegator):
    309353    "Extend base class: forbid insert/delete before the I/O mark"
     
    343387        self.save_warnings_filters = None
    344388        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
    348394    rpcclt = None
    349395    rpcpid = None
    350396
    351397    def spawn_subprocess(self):
     398        if self.subprocess_arglist is None:
     399            self.subprocess_arglist = self.build_subprocess_arglist()
    352400        args = self.subprocess_arglist
    353401        self.rpcpid = os.spawnv(os.P_NOWAIT, sys.executable, args)
    354402
    355403    def build_subprocess_arglist(self):
     404        assert (self.port!=0), (
     405            "Socket should have been assigned a port number.")
    356406        w = ['-W' + s for s in sys.warnoptions]
    357407        if 1/2 > 0: # account for new division
     
    374424
    375425    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
    381428        for i in range(3):
    382429            time.sleep(i)
     
    384431                self.rpcclt = MyRPCClient(addr)
    385432                break
    386             except socket.error, err:
     433            except socket.error as err:
    387434                pass
    388435        else:
    389436            self.display_port_binding_error()
    390437            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
    391450        # Accept the connection from the Python execution server
    392451        self.rpcclt.listening_sock.settimeout(10)
    393452        try:
    394453            self.rpcclt.accept()
    395         except socket.timeout, err:
     454        except socket.timeout as err:
    396455            self.display_no_subprocess_error()
    397456            return None
    398         self.rpcclt.register("stdin", self.tkconsole)
     457        self.rpcclt.register("console", self.tkconsole)
     458        self.rpcclt.register("stdin", self.tkconsole.stdin)
    399459        self.rpcclt.register("stdout", self.tkconsole.stdout)
    400460        self.rpcclt.register("stderr", self.tkconsole.stderr)
     
    402462        self.rpcclt.register("linecache", linecache)
    403463        self.rpcclt.register("interp", self)
    404         self.transfer_path()
     464        self.transfer_path(with_cwd=True)
    405465        self.poll_subprocess()
    406466        return self.rpcclt
    407467
    408     def restart_subprocess(self):
     468    def restart_subprocess(self, with_cwd=False):
    409469        if self.restarting:
    410470            return self.rpcclt
     
    427487        try:
    428488            self.rpcclt.accept()
    429         except socket.timeout, err:
     489        except socket.timeout as err:
    430490            self.display_no_subprocess_error()
    431491            return None
    432         self.transfer_path()
     492        self.transfer_path(with_cwd=with_cwd)
     493        console.stop_readline()
    433494        # annotate restart in shell window and mark it
    434495        console.text.delete("iomark", "end-1c")
     
    447508            # reload remote debugger breakpoints for all PyShellEditWindows
    448509            debug.load_breakpoints()
     510        self.compile.compiler.flags = self.original_compiler_flags
    449511        self.restarting = False
    450512        return self.rpcclt
     
    457519
    458520    def kill_subprocess(self):
     521        if self._afterid is not None:
     522            self.tkconsole.text.after_cancel(self._afterid)
    459523        try:
    460524            self.rpcclt.close()
     
    479543                    return
    480544
    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
    482552        self.runcommand("""if 1:
    483553        import sys as _sys
    484554        _sys.path = %r
    485555        del _sys
    486         \n""" % (sys.path,))
     556        \n""" % (path,))
    487557
    488558    active_seq = None
     
    523593        # Reschedule myself
    524594        if not self.tkconsole.closing:
    525             self.tkconsole.text.after(self.tkconsole.pollinterval,
    526                                       self.poll_subprocess)
     595            self._afterid = self.tkconsole.text.after(
     596                self.tkconsole.pollinterval, self.poll_subprocess)
    527597
    528598    debugger = None
     
    540610        method we allow the subprocess to unblock.  After a bit the shell
    541611        requests the subprocess to open the remote stack viewer which returns a
    542         static object looking at the last exceptiopn.  It is queried through
     612        static object looking at the last exception.  It is queried through
    543613        the RPC mechanism.
    544614
     
    548618
    549619    def remote_stack_viewer(self):
    550         import RemoteObjectBrowser
     620        from idlelib import RemoteObjectBrowser
    551621        oid = self.rpcclt.remotequeue("exec", "stackviewer", ("flist",), {})
    552622        if oid is None:
     
    554624            return
    555625        item = RemoteObjectBrowser.StubObjectTreeItem(self.rpcclt, oid)
    556         from TreeWidget import ScrolledCanvas, TreeNode
     626        from idlelib.TreeWidget import ScrolledCanvas, TreeNode
    557627        top = Toplevel(self.tkconsole.root)
    558628        theme = idleConf.GetOption('main','Theme','name')
     
    594664        warnings.filterwarnings(action="error", category=SyntaxWarning)
    595665        if isinstance(source, types.UnicodeType):
    596             import IOBinding
     666            from idlelib import IOBinding
    597667            try:
    598668                source = source.encode(IOBinding.encoding)
     
    755825        tkMessageBox.showerror(
    756826            "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.",
    764833            master=self.tkconsole.text)
    765834
     
    782851class PyShell(OutputWindow):
    783852
    784     shell_title = "Python Shell"
     853    shell_title = "Python " + python_version() + " Shell"
    785854
    786855    # Override classes
     
    799868
    800869    if macosxSupport.runningAsOSXApp():
    801         del menu_specs[-3]
    802870        menu_specs[-2] = ("windows", "_Window")
    803871
    804872
    805873    # New classes
    806     from IdleHistory import History
     874    from idlelib.IdleHistory import History
    807875
    808876    def __init__(self, flist=None):
     
    842910        self.save_stderr = sys.stderr
    843911        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)
    848917        if not use_subprocess:
    849918            sys.stdout = self.stdout
    850919            sys.stderr = self.stderr
    851             sys.stdin = self
     920            sys.stdin = self.stdin
    852921        #
    853922        self.history = self.History(self.text)
     
    863932    endoffile = False
    864933    closing = False
     934    _stop_readline_flag = False
    865935
    866936    def set_warning_stream(self, stream):
     
    9381008            if response is False:
    9391009                return "cancel"
    940         if self.reading:
    941             self.top.quit()
     1010        self.stop_readline()
    9421011        self.canceled = True
    9431012        self.closing = True
    944         # Wait for poll_subprocess() rescheduling to stop
    945         self.text.after(2 * self.pollinterval, self.close2)
    946 
    947     def close2(self):
    9481013        return EditorWindow.close(self)
    9491014
     
    9741039          'Type "copyright", "credits" or "license()" for more information.'
    9751040
    976     firewallmessage = """
    977     ****************************************************************
    978     Personal firewall software may warn about the connection IDLE
    979     makes to its subprocess using this computer's internal loopback
    980     interface.  This connection is not visible on any external
    981     interface and no data is sent to or received from the Internet.
    982     ****************************************************************
    983     """
    984 
    9851041    def begin(self):
    9861042        self.resetoutput()
     
    9931049        else:
    9941050            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))
    9981053        self.showprompt()
    9991054        import Tkinter
     
    10011056        return True
    10021057
     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
    10031064    def readline(self):
    10041065        save = self.reading
     
    10081069        finally:
    10091070            self.reading = save
     1071        if self._stop_readline_flag:
     1072            self._stop_readline_flag = False
     1073            return ""
    10101074        line = self.text.get("iomark", "end-1c")
    10111075        if len(line) == 0:  # may be EOF if we quit our mainloop with Ctrl-C
    10121076            line = "\n"
    10131077        if isinstance(line, unicode):
    1014             import IOBinding
     1078            from idlelib import IOBinding
    10151079            try:
    10161080                line = line.encode(IOBinding.encoding)
     
    11901254                master=self.text)
    11911255            return
    1192         from StackViewer import StackBrowser
     1256        from idlelib.StackViewer import StackBrowser
    11931257        sv = StackBrowser(self.root, self.flist)
    11941258
     
    11981262
    11991263    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)
    12011266
    12021267    def showprompt(self):
     
    12141279        source = self.text.get("iomark", "end-1c")
    12151280        if self.history:
    1216             self.history.history_store(source)
     1281            self.history.store(source)
    12171282        if self.text.get("end-2c") != "\n":
    12181283            self.text.insert("end-1c", "\n")
     
    12331298                raise KeyboardInterrupt
    12341299
    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
     1313class PseudoFile(io.TextIOBase):
    12361314
    12371315    def __init__(self, shell, tags, encoding=None):
     
    12391317        self.tags = tags
    12401318        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
    12511328
    12521329    def isatty(self):
    12531330        return True
     1331
     1332
     1333class 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
     1346class 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()
    12541393
    12551394
     
    13101449    global flist, root, use_subprocess
    13111450
     1451    capture_warnings(True)
    13121452    use_subprocess = True
    13131453    enable_shell = False
     
    13191459    try:
    13201460        opts, args = getopt.getopt(sys.argv[1:], "c:deihnr:st:")
    1321     except getopt.error, msg:
     1461    except getopt.error as msg:
    13221462        sys.stderr.write("Error: %s\n" % str(msg))
    13231463        sys.stderr.write(usage_msg)
     
    13721512        for dir in pathx:
    13731513            dir = os.path.abspath(dir)
    1374             if not dir in sys.path:
     1514            if dir not in sys.path:
    13751515                sys.path.insert(0, dir)
    13761516    else:
     
    13821522                                    'editor-on-startup', type='bool')
    13831523    enable_edit = enable_edit or edit_start
    1384     enable_shell = enable_shell or not edit_start
     1524    enable_shell = enable_shell or not enable_edit
    13851525    # start editor and/or shell windows:
    13861526    root = Tk(className="Idle")
     
    13931533    if enable_edit:
    13941534        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)
    13971539            if not args:
    13981540                flist.new()
     
    14301572            shell.interp.execfile(script)
    14311573
    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()
    14331583    root.destroy()
     1584    capture_warnings(False)
    14341585
    14351586if __name__ == "__main__":
    14361587    sys.modules['PyShell'] = sys.modules['__main__']
    14371588    main()
     1589
     1590capture_warnings(False)  # Make sure turned off; see issue 18081
Note: See TracChangeset for help on using the changeset viewer.