Пример #1
0
    def get_jedi_object(self, func_name, info, use_filename=True):
        """Call a desired function on a Jedi Script and return the result"""
        if not jedi:
            return
        if DEBUG_EDITOR:
            t0 = time.time()
        # override IPython qt_loaders ImportDenier behavior
        metas = sys.meta_path
        for meta in metas:
            if (meta.__class__.__name__ == 'ImportDenier'
                    and hasattr(meta, 'forbid')):
                sys.meta_path.remove(meta)

        if use_filename:
            filename = info['filename']
        else:
            filename = None

        try:
            script = jedi.Script(info['source_code'], info['line_num'],
                                 info['column'], filename)
            func = getattr(script, func_name)
            val = func()
        except Exception as e:
            val = None
            debug_print('Jedi error (%s)' % func_name)
            debug_print(str(e))
            if DEBUG_EDITOR:
                log_last_error(LOG_FILENAME, str(e))
        if DEBUG_EDITOR:
            log_dt(LOG_FILENAME, func_name, t0)
        if not val and filename:
            return self.get_jedi_object(func_name, info, False)
        else:
            return val
Пример #2
0
    def keyReleaseEvent(self, e):
        """Qt override."""
        self.npressed -= 1
        if self.npressed <= 0:
            key = e.key()

            if len(self.keys) == 1 and key == Qt.Key_Tab:
                self.toggle_state()
                return

            if len(self.keys) == 1 and key == Qt.Key_Escape:
                self.set_sequence('')
                self.label_warning.setText(
                    _("Please introduce a different "
                      "shortcut"))

            if len(self.keys) == 1 and key in [Qt.Key_Return, Qt.Key_Enter]:
                self.toggle_state()
                return

            if not self.edit_state:
                self.nonedit_keyrelease(e)
            else:
                debug_print('keys: {}'.format(self.keys))
                if self.keys and key != Qt.Key_Escape:
                    self.validate_sequence()
                self.keys = set()
                self.key_modifiers = set()
                self.key_non_modifiers = list()
                self.key_text = list()
                self.npressed = 0
Пример #3
0
    def get_info(self, info):
        """
        Find the calltip and docs

        Returns a dict like the following:
           {'note': 'Function of numpy.core.numeric...',
            'argspec': "(shape, dtype=None, order='C')'
            'docstring': 'Return an array of given...'
            'name': 'ones',
            'calltip': 'ones(shape, dtype=None, order='C')'}
        """
        call_def = self.get_jedi_object('goto_definitions', info)
        for cd in call_def:
            if cd.doc and not cd.doc.rstrip().endswith(')'):
                call_def = cd
                break
        else:
            call_def = call_def[0]
        name = call_def.name
        if name is None:
            return
        if call_def.module_path:
            mod_name = get_parent_until(call_def.module_path)
        else:
            mod_name = None
        if not mod_name:
            mod_name = call_def.module_name
        if call_def.doc.startswith(name + '('):
            calltip = getsignaturefromtext(call_def.doc, name)
            argspec = calltip[calltip.find('('):]
            docstring = call_def.doc[call_def.doc.find(')') + 3:]
        elif '(' in call_def.doc.splitlines()[0]:
            calltip = call_def.doc.splitlines()[0]
            name = call_def.doc.split('(')[0]
            docstring = call_def.doc[call_def.doc.find(')') + 3:]
            argspec = calltip[calltip.find('('):]
        else:
            calltip = name + '(...)'
            argspec = '()'
            docstring = call_def.doc
        if call_def.type == 'module':
            note = 'Module %s' % mod_name
            argspec = ''
            calltip = name
        elif call_def.type == 'class':
            note = 'Class in %s module' % mod_name
        elif call_def.doc.startswith('%s(self' % name):
            class_name = call_def.full_name.split('.')[-2]
            note = 'Method of %s class in %s module' % (
                class_name.capitalize(), mod_name)
        else:
            note = '%s in %s module' % (call_def.type.capitalize(),
                                        mod_name)
        argspec = argspec.replace(' = ', '=')
        calltip = calltip.replace(' = ', '=')
        debug_print(call_def.name)

        doc_info = dict(name=name, argspec=argspec,
                        note=note, docstring=docstring, calltip=calltip)
        return doc_info
Пример #4
0
 def get_completions(self, info):
     """Return a list of (completion, type) tuples"""
     completions = self.get_jedi_object('completions', info)
     if DEBUG_EDITOR:
         log_last_error(LOG_FILENAME, str("comp: " + str(completions)[:100]))
     completions = [(c.name, c.type) for c in completions]
     debug_print(str(completions)[:100])
     return completions
Пример #5
0
 def _send(self, obj):
     """Send an object to the server.
     """
     try:
         self.socket.send_pyobj(obj, zmq.NOBLOCK)
     except Exception as e:
         debug_print(e)
         self.is_initialized = False
         self._on_finished()
Пример #6
0
 def handle_response(self, response):
     name = self.ids.get(response['request_id'], None)
     if not name:
         return
     if response.get('error', None):
         debug_print('Response error:', response['error'])
         return
     if name == self.desired[0] or not self.waiting:
         if response.get('result', None):
             self._finalize(response)
     else:
         self.pending = response
Пример #7
0
    def run(self):
        """Handle the connection with the server.
        """
        # Set up the zmq port.
        self.socket = self.context.socket(zmq.PAIR)
        self.port = self.socket.bind_to_random_port('tcp://*')

        # Set up the process.
        self.process = QProcess(self)
        if self.cwd:
            self.process.setWorkingDirectory(self.cwd)
        p_args = ['-u', self.target, str(self.port)]
        if self.extra_args is not None:
            p_args += self.extra_args

        # Set up environment variables.
        processEnvironment = QProcessEnvironment()
        env = self.process.systemEnvironment()
        if (self.env and 'PYTHONPATH' not in self.env) or self.env is None:
            python_path = osp.dirname(get_module_path('trex'))
            # Add the libs to the python path.
            for lib in self.libs:
                try:
                    path = osp.dirname(imp.find_module(lib)[1])
                    python_path = osp.pathsep.join([python_path, path])
                except ImportError:
                    pass
            if self.extra_path:
                try:
                    python_path = osp.pathsep.join([python_path] +
                                                   self.extra_path)
                except Exception as e:
                    debug_print("Error when adding extra_path to plugin env")
                    debug_print(e)
            env.append("PYTHONPATH=%s" % python_path)
        if self.env:
            env.update(self.env)
        for envItem in env:
            envName, separator, envValue = envItem.partition('=')
            processEnvironment.insert(envName, envValue)
        self.process.setProcessEnvironment(processEnvironment)

        # Start the process and wait for started.
        self.process.start(self.executable, p_args)
        self.process.finished.connect(self._on_finished)
        running = self.process.waitForStarted()
        if not running:
            raise IOError('Could not start %s' % self)

        # Set up the socket notifer.
        fid = self.socket.getsockopt(zmq.FD)
        self.notifier = QSocketNotifier(fid, QSocketNotifier.Read, self)
        self.notifier.activated.connect(self._on_msg_received)
Пример #8
0
 def _finalize(self, response):
     self.waiting = False
     self.pending = None
     if self.info:
         delta = time.time() - self._start_time
         debug_print('%s request from %s finished: "%s" in %.1f sec'
             % (self.info.name, response['name'],
                str(response['result'])[:100], delta))
         response['info'] = self.info
         self.introspection_complete.emit(response)
         self.info = None
     if self.pending_request:
         info = self.pending_request
         self.pending_request = None
         self.send_request(info)
Пример #9
0
    def __init__(self, parent=None, namespace=None, commands=[], message=None,
                 exitfunc=None, profile=False, multithreaded=False):
        if PYQT5:
            TRexPluginWidget.__init__(self, parent, main = parent)
        else:
            TRexPluginWidget.__init__(self, parent)
        
        debug_print("    ..internal console: initializing")
        self.dialog_manager = DialogManager()

        # Shell
        light_background = self.get_option('light_background')
        self.shell = InternalShell(parent, namespace, commands, message,
                                   self.get_option('max_line_count'),
                                   self.get_plugin_font(), exitfunc, profile,
                                   multithreaded,
                                   light_background=light_background)
        self.shell.status.connect(lambda msg: self.show_message.emit(msg, 0))
        self.shell.go_to_error.connect(self.go_to_error)
        self.shell.focus_changed.connect(lambda: self.focus_changed.emit())

        # Redirecting some signals:
        self.shell.redirect_stdio.connect(lambda state:
                                          self.redirect_stdio.emit(state))
        
        # Initialize plugin
        self.initialize_plugin()

        # Find/replace widget
        self.find_widget = FindReplace(self)
        self.find_widget.set_editor(self.shell)
        self.find_widget.hide()
        self.register_widget_shortcuts(self.find_widget)

        # Main layout
        layout = QVBoxLayout()
        layout.addWidget(self.shell)
        layout.addWidget(self.find_widget)
        self.setLayout(layout)
        
        # Parameters
        self.shell.toggle_wrap_mode(self.get_option('wrap'))
            
        # Accepting drops
        self.setAcceptDrops(True)
Пример #10
0
    def _introspection_complete(self, response):
        """
        Handle an introspection response completion.

        Route the response to the correct handler.
        """
        result = response.get('result', None)
        if result is None:
            return
        info = response['info']
        current = self._get_code_info(response['info']['name'])

        if result and current.filename == info.filename:
            func = getattr(self, '_handle_%s_result' % info.name)
            try:
                func(result, current, info)
            except Exception as e:
                debug_print(e)
Пример #11
0
 def _on_msg_received(self):
     """Handle a message trigger from the socket.
     """
     self.notifier.setEnabled(False)
     while 1:
         try:
             resp = self.socket.recv_pyobj(flags=zmq.NOBLOCK)
         except zmq.ZMQError:
             self.notifier.setEnabled(True)
             return
         if not self.is_initialized:
             self.is_initialized = True
             debug_print('Initialized %s' % self.name)
             self.initialized.emit()
             self.timer.start(HEARTBEAT)
             continue
         resp['name'] = self.name
         self.received.emit(resp)
Пример #12
0
    def send_request(self, info):
        """Handle an incoming request from the user."""
        if self.waiting:
            if info.serialize() != self.info.serialize():
                self.pending_request = info
            else:
                debug_print('skipping duplicate request')
            return
        debug_print('%s request' % info.name)
        desired = None
        self.info = info
        editor = info.editor
        if (info.name == 'completion' and 'jedi' not in self.plugins and
                info.line.lstrip().startswith(('import ', 'from '))):
            desired = 'fallback'

        if ((not editor.is_python_like()) or
                sourcecode.is_keyword(info.obj) or
                (editor.in_comment_or_string() and info.name != 'info')):
            desired = 'fallback'

        plugins = self.plugins.values()
        if desired:
            plugins = [self.plugins[desired]]
            self.desired = [desired]
        elif (info.name == 'definition' and not info.editor.is_python() or
              info.name == 'info'):
            self.desired = list(self.plugins.keys())
        else:
            # Use all but the fallback
            plugins = list(self.plugins.values())[:-1]
            self.desired = list(self.plugins.keys())[:-1]

        self._start_time = time.time()
        self.waiting = True
        method = 'get_%s' % info.name
        value = info.serialize()
        self.ids = dict()
        for plugin in plugins:
            request_id = plugin.request(method, value)
            self.ids[request_id] = plugin.name
        self.timer.stop()
        self.timer.singleShot(LEAD_TIME_SEC * 1000, self._handle_timeout)
Пример #13
0
    def keyPressEvent(self, e):
        """Qt override."""
        key = e.key()
        # Check if valid keys
        if key not in VALID_KEYS:
            self.invalid_key_flag = True
            return

        self.npressed += 1
        self.key_non_modifiers.append(key)
        self.key_modifiers.add(key)
        self.key_text.append(e.text())
        self.invalid_key_flag = False

        debug_print('key {0}, npressed: {1}'.format(key, self.npressed))

        if key == Qt.Key_unknown:
            return

        # The user clicked just and only the special keys
        # Ctrl, Shift, Alt, Meta.
        if (key == Qt.Key_Control or key == Qt.Key_Shift or key == Qt.Key_Alt
                or key == Qt.Key_Meta):
            return

        modifiers = e.modifiers()
        if modifiers & Qt.ShiftModifier:
            key += Qt.SHIFT
        if modifiers & Qt.ControlModifier:
            key += Qt.CTRL
            if sys.platform == 'darwin':
                self.npressed -= 1
            debug_print('decrementing')
        if modifiers & Qt.AltModifier:
            key += Qt.ALT
        if modifiers & Qt.MetaModifier:
            key += Qt.META

        self.keys.add(key)
Пример #14
0
 def run_script(self, filename=None, silent=False, set_focus=False,
                args=None):
     """Run a Python script"""
     if filename is None:
         self.shell.interpreter.restore_stds()
         filename, _selfilter = getopenfilename(self, _("Run Python script"),
                getcwd(), _("Python scripts")+" (*.py ; *.pyw ; *.ipy)")
         self.shell.interpreter.redirect_stds()
         if filename:
             os.chdir( osp.dirname(filename) )
             filename = osp.basename(filename)
         else:
             return
     debug_print(args)
     filename = osp.abspath(filename)
     rbs = remove_backslashes
     command = "runfile('%s', args='%s')" % (rbs(filename), rbs(args))
     if set_focus:
         self.shell.setFocus()
     if self.dockwidget and not self.ismaximized:
         self.dockwidget.setVisible(True)
         self.dockwidget.raise_()
     self.shell.write(command+'\n')
     self.shell.run_command(command)
Пример #15
0
    def __init__(self, executable, extra_path=None):

        super(PluginManager, self).__init__()
        plugins = OrderedDict()
        for name in PLUGINS:
            try:
                plugin = PluginClient(name, executable, extra_path=extra_path)
                plugin.run()
            except Exception as e:
                debug_print('Introspection Plugin Failed: %s' % name)
                debug_print(str(e))
                continue
            debug_print('Introspection Plugin Loaded: %s' % name)
            plugins[name] = plugin
            plugin.received.connect(self.handle_response)
        self.plugins = plugins
        self.timer = QTimer()
        self.desired = []
        self.ids = dict()
        self.info = None
        self.request = None
        self.pending = None
        self.pending_request = None
        self.waiting = False
Пример #16
0
 def _handle_timeout(self):
     self.waiting = False
     if self.pending:
         self._finalize(self.pending)
     else:
         debug_print('No valid responses acquired')
Пример #17
0
 def _on_finished(self):
     """Handle a finished signal from the process.
     """
     if self.closing:
         return
     if self.is_initialized:
         debug_print('Restarting %s' % self.name)
         debug_print(self.process.readAllStandardOutput())
         debug_print(self.process.readAllStandardError())
         self.is_initialized = False
         self.notifier.setEnabled(False)
         self.run()
     else:
         debug_print('Errored %s' % self.name)
         debug_print(self.process.readAllStandardOutput())
         debug_print(self.process.readAllStandardError())
         self.errored.emit()
Пример #18
0
 def close(self):
     for name, plugin in self.plugins.items():
         plugin.close()
         debug_print("Introspection Plugin Closed: {}".format(name))