~ubuntu-branches/ubuntu/trusty/spyder/trusty-proposed

« back to all changes in this revision

Viewing changes to spyderlib/widgets/externalshell/pythonshell.py

  • Committer: Package Import Robot
  • Author(s): Picca Frédéric-Emmanuel
  • Date: 2013-05-08 21:12:32 UTC
  • mfrom: (1.2.1) (18.1.5 experimental)
  • Revision ID: package-import@ubuntu.com-20130508211232-r867h9xoenknvuxf
Tags: 2.2.0+dfsg-1
* Imported Upstream version 2.2.0+dfsg
* Depends on ipython-qtconsole (< 1.0)
* Removed the obsolte DM-Upload-Allowed

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
from spyderlib.qt.compat import getexistingdirectory
18
18
 
19
19
# Local imports
20
 
from spyderlib.utils.qthelpers import (create_toolbutton, create_action,
21
 
                                       get_std_icon, DialogManager,
22
 
                                       add_actions)
 
20
from spyderlib.utils.qthelpers import (get_icon, get_std_icon, add_actions,
 
21
                                       create_toolbutton, create_action,
 
22
                                       DialogManager)
23
23
from spyderlib.utils.environ import RemoteEnvDialog
24
24
from spyderlib.utils.programs import get_python_args
25
25
from spyderlib.utils.misc import get_python_executable
26
 
from spyderlib.baseconfig import _, get_module_source_path
27
 
from spyderlib.config import get_icon
 
26
from spyderlib.baseconfig import _, get_module_source_path, DEBUG
28
27
from spyderlib.widgets.shell import PythonShellWidget
29
28
from spyderlib.widgets.externalshell.namespacebrowser import NamespaceBrowser
30
29
from spyderlib.widgets.externalshell.monitor import communicate, write_packet
34
33
 
35
34
 
36
35
class ExtPythonShellWidget(PythonShellWidget):
37
 
    def __init__(self, parent, history_filename, debug=False, profile=False):
38
 
        PythonShellWidget.__init__(self, parent, history_filename,
39
 
                                   debug, profile)
 
36
    def __init__(self, parent, history_filename, profile=False):
 
37
        PythonShellWidget.__init__(self, parent, history_filename, profile)
 
38
        self.path = []
40
39
    
41
40
    def set_externalshell(self, externalshell):
42
41
        # ExternalShellBase instance:
119
118
        """Return True if object is defined"""
120
119
        return self.ask_monitor("isdefined('%s', force_import=%s)"
121
120
                                % (objtxt, force_import))
122
 
 
123
 
    def get_completion(self, objtxt):
124
 
        """Return completion list associated to object name"""
125
 
        return self.ask_monitor("getcomplist('%s')" % objtxt)
126
121
        
127
122
    def get_module_completion(self, objtxt):
128
123
        """Return module completion list associated to object name"""
129
 
        return self.ask_monitor("getmodcomplist('%s')" % objtxt)
 
124
        return self.ask_monitor("getmodcomplist('%s', %s)" % \
 
125
                                                           (objtxt, self.path))
130
126
    
131
127
    def get_cwd(self):
132
128
        """Return shell current working directory"""
148
144
        """Return sys.path[:]"""
149
145
        return self.ask_monitor("getsyspath()")
150
146
 
 
147
    def set_spyder_breakpoints(self):
 
148
        """Set Spyder breakpoints into debugging session"""
 
149
        return self.ask_monitor("set_spyder_breakpoints()")
 
150
        
151
151
 
152
152
class ExternalPythonShell(ExternalShellBase):
153
153
    """External Shell widget: execute Python script in a separate process"""
154
154
    SHELL_CLASS = ExtPythonShellWidget
155
155
    def __init__(self, parent=None, fname=None, wdir=None,
156
156
                 interact=False, debug=False, path=[], python_args='',
157
 
                 ipython_shell=False, ipython_kernel=False,
158
 
                 arguments='', stand_alone=None,
 
157
                 ipykernel=False, arguments='', stand_alone=None,
159
158
                 umd_enabled=True, umd_namelist=[], umd_verbose=True,
160
159
                 pythonstartup=None, pythonexecutable=None,
161
160
                 monitor_enabled=True, mpl_patch_enabled=True,
214
213
        assert isinstance(arguments, basestring)
215
214
        self.arguments = arguments
216
215
        
217
 
        self.is_ipython_shell = ipython_shell
218
 
        self.is_ipython_kernel = ipython_kernel
219
 
        if self.is_ipython_shell or self.is_ipython_kernel:
 
216
        self.connection_file = None
 
217
        self.is_ipykernel = ipykernel
 
218
        if self.is_ipykernel:
220
219
            interact = False
221
 
            # Running our custom startup script for IPython sessions:
222
 
            # (see spyderlib/widgets/externalshell/startup.py)
 
220
            # Running our custom startup script for IPython kernels:
 
221
            # (see spyderlib/widgets/externalshell/start_ipython_kernel.py)
223
222
            self.fname = get_module_source_path(
224
 
                            'spyderlib.widgets.externalshell', 'startup.py')
 
223
                'spyderlib.widgets.externalshell', 'start_ipython_kernel.py')
225
224
        
226
225
        self.shell.set_externalshell(self)
227
226
 
237
236
        
238
237
        # Additional python path list
239
238
        self.path = path
 
239
        self.shell.path = path
240
240
        
241
241
    def set_introspection_socket(self, introspection_socket):
242
242
        self.introspection_socket = introspection_socket
307
307
        return actions
308
308
 
309
309
    def is_interpreter(self):
310
 
        """Return True if shellwidget is a Python/IPython interpreter"""
 
310
        """Return True if shellwidget is a Python interpreter"""
311
311
        return self.is_interpreter
312
312
        
313
313
    def get_shell_widget(self):
340
340
        ExternalShellBase.set_buttons_runnning_state(self, state)
341
341
        self.interact_action.setEnabled(not state and not self.is_interpreter)
342
342
        self.debug_action.setEnabled(not state and not self.is_interpreter)
343
 
        self.args_action.setEnabled(not state and
344
 
                                    (not self.is_interpreter or\
345
 
                                     self.is_ipython_shell))
 
343
        self.args_action.setEnabled(not state and not self.is_interpreter)
346
344
        if state:
347
345
            if self.arguments:
348
346
                argstr = _("Arguments: %s") % self.arguments
380
378
        self.shell.clear()
381
379
            
382
380
        self.process = QProcess(self)
383
 
        if self.merge_output_channels or self.is_ipython_shell:
 
381
        if self.merge_output_channels:
384
382
            self.process.setProcessChannelMode(QProcess.MergedChannels)
385
383
        else:
386
384
            self.process.setProcessChannelMode(QProcess.SeparateChannels)
393
391
 
394
392
        #-------------------------Python specific-------------------------------
395
393
        # Python arguments
396
 
        p_args = ['-u'] + get_python_args(self.fname, self.python_args,
397
 
                                          self.interact_action.isChecked(),
398
 
                                          self.debug_action.isChecked(),
399
 
                                          self.arguments)
 
394
        p_args = ['-u']
 
395
        if DEBUG:
 
396
            p_args += ['-v']
 
397
        p_args += get_python_args(self.fname, self.python_args,
 
398
                                  self.interact_action.isChecked(),
 
399
                                  self.debug_action.isChecked(),
 
400
                                  self.arguments)
400
401
        
401
402
        env = [unicode(_path) for _path in self.process.systemEnvironment()]
 
403
 
402
404
        if self.pythonstartup:
403
405
            env.append('PYTHONSTARTUP=%s' % self.pythonstartup)
404
406
        
418
420
            self.connect(self.notification_thread,
419
421
                         SIGNAL('new_ipython_kernel(QString)'),
420
422
                         lambda args:
421
 
                         self.emit(SIGNAL('create_ipython_frontend(QString)'),
 
423
                         self.emit(SIGNAL('create_ipython_client(QString)'),
422
424
                         args))
423
425
            self.connect(self.notification_thread,
424
426
                         SIGNAL('open_file(QString,int)'),
454
456
            env.append('UMD_ENABLED=%r' % self.umd_enabled)
455
457
            env.append('UMD_NAMELIST=%s' % ','.join(self.umd_namelist))
456
458
            env.append('UMD_VERBOSE=%r' % self.umd_verbose)
457
 
        
458
 
        # IPython related configuration
459
 
        if self.is_ipython_shell:
460
 
            env.append('IPYTHON=True')
461
 
            # Do not call msvcrt.getch in IPython.genutils.page_more:
462
 
            env.append('TERM=emacs')
463
 
        elif self.is_ipython_kernel:
464
 
            env.append('IPYTHON_KERNEL=True')
 
459
 
 
460
        # IPython kernel
 
461
        env.append('IPYTHON_KERNEL=%r' % self.is_ipykernel)
465
462
            
466
463
        pathlist = []
467
464
 
474
471
        
475
472
        # Adding path list to PYTHONPATH environment variable
476
473
        add_pathlist_to_PYTHONPATH(env, pathlist)
477
 
        
478
 
        self.process.setEnvironment(env)
 
474
 
479
475
        #-------------------------Python specific-------------------------------
480
476
                        
481
477
        self.connect(self.process, SIGNAL("readyReadStandardOutput()"),
496
492
        executable = self.pythonexecutable
497
493
        if executable is None:
498
494
            executable = get_python_executable()
 
495
        
 
496
        # Fixes for our Mac app:
 
497
        # 1. PYTHONPATH and PYTHONHOME are set while bootstrapping the app,
 
498
        #    but their values are messing sys.path for external interpreters
 
499
        #    (e.g. EPD) so we need to remove them from the environment.
 
500
        # 2. Add this file's dir to PYTHONPATH. This will make every external
 
501
        #    interpreter to use our sitecustomize script.
 
502
        # 3. Remove PYTHONOPTIMIZE from env so that we can have assert
 
503
        #    statements working with our interpreters (See Issue 1281)
 
504
        if sys.platform == 'darwin' and 'Spyder.app' in __file__:
 
505
            env.append('SPYDER_INTERPRETER=%s' % executable)
 
506
            if 'Spyder.app' not in executable:
 
507
                env = [p for p in env if not (p.startswith('PYTHONPATH') or \
 
508
                                              p.startswith('PYTHONHOME'))] # 1.
 
509
 
 
510
                env.append('PYTHONPATH=%s' % osp.dirname(__file__))        # 2.
 
511
 
 
512
            env = [p for p in env if not p.startswith('PYTHONOPTIMIZE')]   # 3.
 
513
 
 
514
        self.process.setEnvironment(env)
499
515
        self.process.start(executable, p_args)
500
516
        #-------------------------Python specific-------------------------------
501
517
            
509
525
            self.emit(SIGNAL('started()'))
510
526
            
511
527
        return self.process
 
528
 
 
529
    def finished(self, exit_code, exit_status):
 
530
        """Reimplement ExternalShellBase method"""
 
531
        ExternalShellBase.finished(self, exit_code, exit_status)
 
532
        self.introspection_socket = None
 
533
 
512
534
    
513
535
#===============================================================================
514
536
#    Input/Output
524
546
        QApplication.processEvents()
525
547
        
526
548
    def send_to_process(self, text):
 
549
        if not self.is_running():
 
550
            return
 
551
            
527
552
        if not isinstance(text, basestring):
528
553
            text = unicode(text)
529
 
        if self.install_qt_inputhook and not self.is_ipython_shell:
530
 
            # For now, the Spyder's input hook does not work with IPython:
531
 
            # with IPython v0.10 or non-Windows platforms, this is not a
532
 
            # problem. However, with IPython v0.11 on Windows, this will be
533
 
            # fixed by patching IPython to force it to use our inputhook.
534
 
            if self.introspection_socket is not None:
535
 
                communicate(self.introspection_socket,
536
 
                            "toggle_inputhook_flag(True)")
 
554
        if self.install_qt_inputhook and self.introspection_socket is not None:
 
555
            communicate(self.introspection_socket,
 
556
                        "toggle_inputhook_flag(True)")
537
557
#            # Socket-based alternative (see input hook in sitecustomize.py):
538
558
#            while self.local_server.hasPendingConnections():
539
559
#                self.local_server.nextPendingConnection().write('go!')
540
 
        if not self.is_ipython_shell and text.startswith(('%', '!')):
 
560
        if text.startswith(('%', '!')):
541
561
            text = 'evalsc(r"%s")\n' % text
542
562
        if not text.endswith('\n'):
543
563
            text += '\n'