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
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)
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
def _introspection_complete(self): """ Handle an introspection response from the thread. Route the response to the correct handler, and then handle any pending requests. """ self.busy = False result = self.request.result info = self.request.info current = self._get_code_info("current") if result and current.filename == info.filename: func = getattr(self, "_handle_%s_response" % info.name) try: func(result, current, info) except Exception as e: debug_print(e) elif current.filename == info.filename and info.name == "definition": result = self.plugins["fallback"].get_definition(info) if info == self.pending: self.pending = None self._handle_pending()
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
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
def _finalize(self, name, result): self.result = result self.waiting = False self.pending = None delta = time.time() - self._start_time debug_print('%s request from %s finished: "%s" in %.1f sec' % (self.info.name, name, str(result)[:100], delta)) self.introspection_complete.emit()
def _introspection_complete(self): """ Handle an introspection response from the thread. Route the response to the correct handler, and then handle any pending requests. """ self.busy = False result = self.request.result info = self.request.info current = self._get_code_info('current') if result and current.filename == info.filename: func = getattr(self, '_handle_%s_response' % info.name) try: func(result, current, info) except Exception as e: debug_print(e) elif current.filename == info.filename and info.name == 'definition': result = self.plugins['fallback'].get_definition(info) if info == self.pending: self.pending = None self._handle_pending()
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 = self.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
def _handle_timeout(self): debug_print('got timeout: %s' % self.plugins) if self.pending: for plugin in self.plugins: if plugin.name in self.pending: self._finalize(plugin.name, self.pending[plugin.name]) return self.waiting = False
def _handle_timeout(self): debug_print("got timeout: %s" % self.plugins) if self.pending: for plugin in self.plugins: if plugin.name in self.pending: self._finalize(plugin.name, self.pending[plugin.name]) return self.waiting = False
def run(self): func = getattr(self.plugin, "get_%s" % self.info.name) self.plugin.busy = True try: self.result = func(self.info) except Exception as e: debug_print(e) self.plugin.busy = False self.request_handled.emit(self.plugin.name)
def run(self): func = getattr(self.plugin, 'get_%s' % self.info.name) self.plugin.busy = True try: self.result = func(self.info) except Exception as e: debug_print(e) self.plugin.busy = False self.request_handled.emit(self.plugin.name)
def _send(self, obj): """Send an object to the server. """ try: self.socket.send_pyobj(obj) except Exception as e: debug_print(e) self.is_initialized = False self._on_finished()
def __init__(self, parent=None, namespace=None, commands=[], message=None, exitfunc=None, profile=False, multithreaded=False): if PYQT5: SpyderPluginWidget.__init__(self, parent, main=parent) else: SpyderPluginWidget.__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("Editor", 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)
def _handle_request(self, info, desired=None): """Handle an incoming request from the user.""" debug_print('%s request' % info.name) editor = info.editor if ((not editor.is_python_like()) or sourcecode.is_keyword(info.obj) or (editor.in_comment_or_string() and info.name != 'info')): desired = 'fallback' self.pending = (info, desired) if not self.busy: self._handle_pending()
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
def __init__( self, parent=None, namespace=None, commands=[], message=None, exitfunc=None, profile=False, multithreaded=False ): if PYQT5: SpyderPluginWidget.__init__(self, parent, main=parent) else: SpyderPluginWidget.__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("Editor", 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)
def _finalize(self, response): self.waiting = False self.pending = None delta = time.time() - self._start_time debug_print(str(response.keys())) debug_print('%s request from %s finished: "%s" in %.1f sec' % (self.info.name, response['plugin_name'], str(response['result'])[:100], delta)) self.introspection_complete.emit(response) self.info = None if self.pending_request: info = self.pending_request self.pending_request = None self.send_request(info)
def _handle_incoming(self, name): # coerce to a str in case it is a QString name = str(name) self._threads[name].wait() if self.result: return result = self._threads[name].result if name == self.plugins[0].name or not self.waiting: if result: self._finalize(name, result) else: debug_print("No valid responses acquired") self.introspection_complete.emit() else: self.pending[name] = result
def _handle_incoming(self, name): # coerce to a str in case it is a QString name = str(name) self._threads[name].wait() if self.result: return result = self._threads[name].result if name == self.plugins[0].name or not self.waiting: if result: self._finalize(name, result) else: debug_print('No valid responses acquired') self.introspection_complete.emit() else: self.pending[name] = result
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)
def handle_response(self, response): if (self.request is None): return if (response.get('request_id', None) != id(self.info)): return name = response['plugin_name'] response['info'] = self.info 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
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() continue resp['name'] = self.name self.received.emit(resp)
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)
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)
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)
def _on_finished(self): debug_print('finished %s %s' % (self.plugin_name, self._initialized)) if self._initialized: self.start() else: self._initialized = False debug_print(self.process.readAllStandardOutput()) debug_print(self.process.readAllStandardError()) self.errored.emit()
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)
def load_plugins(self): """Get and load a plugin, checking in order of PLUGINS""" plugins = OrderedDict() for plugin_name in PLUGINS: mod_name = plugin_name + "_plugin" try: mod = __import__("spyderlib.utils.introspection." + mod_name, fromlist=[mod_name]) cls = getattr(mod, "%sPlugin" % plugin_name.capitalize()) plugin = cls() plugin.load_plugin() except Exception as e: debug_print(e) if DEBUG_EDITOR: log_last_error(LOG_FILENAME) else: plugins[plugin_name] = plugin debug_print("Instropection Plugin Loaded: %s" % plugin.name) self.plugins = plugins debug_print("Plugins loaded: %s" % self.plugins.keys()) return plugins
def __init__(self, executable): super(PluginManager, self).__init__() plugins = OrderedDict() for name in PLUGINS: try: plugin = PluginClient(name, executable) 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.request_handled.connect(self.handle_response) self.plugins = plugins self.timer = QTimer() self.desired = [] self.info = None self.request = None self.pending = None self.pending_request = None self.waiting = False
def load_plugins(self): """Get and load a plugin, checking in order of PLUGINS""" plugins = OrderedDict() for plugin_name in PLUGINS: mod_name = plugin_name + '_plugin' try: mod = __import__('spyderlib.utils.introspection.' + mod_name, fromlist=[mod_name]) cls = getattr(mod, '%sPlugin' % plugin_name.capitalize()) plugin = cls() plugin.load_plugin() except Exception as e: debug_print(e) if DEBUG_EDITOR: log_last_error(LOG_FILENAME) else: plugins[plugin_name] = plugin debug_print('Instropection Plugin Loaded: %s' % plugin.name) self.plugins = plugins debug_print('Plugins loaded: %s' % self.plugins.keys()) return plugins
def __init__(self, executable): super(PluginManager, self).__init__() plugins = OrderedDict() for name in PLUGINS: try: plugin = PluginClient(name, executable) 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
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()
def _on_initialized(self, port): debug_print('Initialized %s' % self.plugin_name) self._initialized = True self.client_port = port self.initialized.emit()
def get_completions(self, info): """Return a list of (completion, type) tuples""" completions = self.get_jedi_object('completions', info) completions = [(c.name, c.type) for c in completions] debug_print(str(completions)[:100]) return completions
def _handle_timeout(self): self.waiting = False if self.pending: self._finalize(self.pending) else: debug_print('No valid responses acquired')