def get_definition(self, info): """Find a definition location using Rope""" if self.project is None: return filename = info['filename'] source_code = info['source_code'] offset = info['position'] # TODO: test if this is working without any further change in # Python 3 with a user account containing unicode characters try: resource = rope.base.libutils.path_to_resource( self.project, filename) except Exception as _error: if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "path_to_resource: %r" % filename) resource = None try: if DEBUG_EDITOR: t0 = time.time() resource, lineno = rope.contrib.codeassist.get_definition_location( self.project, source_code, offset, resource, maxfixes=3) if DEBUG_EDITOR: log_dt(LOG_FILENAME, "get_definition_location", t0) if resource is not None: filename = resource.real_path if filename and lineno: return filename, lineno except Exception as _error: #analysis:ignore if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "get_definition_location")
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 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
def run(self): """Start notification thread""" while True: if self.notify_socket is None: continue output = None try: try: cdict = read_packet(self.notify_socket) except: # This except statement is intended to handle a struct.error # (but when writing 'except struct.error', it doesn't work) # Note: struct.error is raised when the communication has # been interrupted and the received data is not a string # of length 8 as required by struct.unpack (see read_packet) break if cdict is None: # Another notification thread has just terminated and # then wrote 'None' in the notification socket # (see the 'finally' statement below) continue if not isinstance(cdict, dict): raise TypeError("Invalid data type: %r" % cdict) command = cdict['command'] data = cdict.get('data') if command == 'pdb_step': fname, lineno = data self.sig_pdb.emit(fname, lineno) self.refresh_namespace_browser.emit() elif command == 'refresh': self.refresh_namespace_browser.emit() elif command == 'remote_view': self.sig_process_remote_view.emit(data) elif command == 'open_file': fname, lineno = data self.open_file.emit(fname, lineno) else: raise RuntimeError('Unsupported command: %r' % command) if DEBUG_INTROSPECTION: logging.debug("received command: %r" % command) except: log_last_error(LOG_FILENAME, "notification thread") finally: try: write_packet(self.notify_socket, output) except: # The only reason why it should fail is that TRex is # closing while this thread is still alive break
def get_completions(self, info): """Get a list of (completion, type) tuples using Rope""" if self.project is None: return [] filename = info['filename'] source_code = info['source_code'] offset = info['position'] # Prevent Rope from returning import completions because # it can't handle them. Only Jedi can do it! lines = sourcecode.split_source(source_code[:offset]) last_line = lines[-1].lstrip() if (last_line.startswith('import ') or last_line.startswith('from ')) \ and not ';' in last_line: return [] # TODO: test if this is working without any further change in # Python 3 with a user account containing unicode characters try: resource = rope.base.libutils.path_to_resource( self.project, filename) except Exception as _error: if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "path_to_resource: %r" % filename) resource = None try: if DEBUG_EDITOR: t0 = time.time() proposals = rope.contrib.codeassist.code_assist(self.project, source_code, offset, resource, maxfixes=3) proposals = rope.contrib.codeassist.sorted_proposals(proposals) if DEBUG_EDITOR: log_dt(LOG_FILENAME, "code_assist/sorted_proposals", t0) return [(proposal.name, proposal.type) for proposal in proposals] except Exception as _error: #analysis:ignore if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "get_completion_list") return []
def create_rope_project(self, root_path): """Create a Rope project on a desired path""" # TODO: test if this is working without any further change in # Python 3 with a user account containing unicode characters try: import rope.base.project self.project = rope.base.project.Project(root_path, **ROPE_PREFS) except ImportError: print >> STDERR, 'project error' self.project = None if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "create_rope_project: %r" % root_path) except TypeError: self.project = None if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "create_rope_project: %r" % root_path) self.validate()
def get_definition_info(defn): """Extract definition information from the Jedi definition object""" try: module_path = defn.module_path name = defn.name if hasattr(defn, 'line_nr'): line_nr = defn.line_nr else: line_nr = defn.line description = defn.description in_builtin = defn.in_builtin_module() except Exception as e: if DEBUG_EDITOR: log_last_error(LOG_FILENAME, 'Get Defintion: %s' % e) return None pattern = 'class\s+{0}|def\s+{0}|self.{0}\s*=|{0}\s*='.format(name) if not re.match(pattern, description): goto_next = True else: goto_next = False return dict(module_path=module_path, line_nr=line_nr, description=description, name=name, in_builtin=in_builtin, goto_next=goto_next)
def get_info(self, info): """Get a formatted calltip and docstring from Rope""" if self.project is None: return filename = info['filename'] source_code = info['source_code'] offset = info['position'] # TODO: test if this is working without any further change in # Python 3 with a user account containing unicode characters try: resource = rope.base.libutils.path_to_resource( self.project, filename) except Exception as _error: if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "path_to_resource: %r" % filename) resource = None try: if DEBUG_EDITOR: t0 = time.time() cts = rope.contrib.codeassist.get_calltip(self.project, source_code, offset, resource, ignore_unknown=False, remove_self=True, maxfixes=3) if DEBUG_EDITOR: log_dt(LOG_FILENAME, "get_calltip", t0) if cts is not None: while '..' in cts: cts = cts.replace('..', '.') if '(.)' in cts: cts = cts.replace('(.)', '(...)') try: doc_text = rope.contrib.codeassist.get_doc(self.project, source_code, offset, resource, maxfixes=3) if DEBUG_EDITOR: log_dt(LOG_FILENAME, "get_doc", t0) except Exception as _error: doc_text = '' if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "get_doc") return self.handle_info(cts, doc_text, source_code, offset) except Exception as _error: #analysis:ignore if DEBUG_EDITOR: log_last_error(LOG_FILENAME, "get_calltip_text")
def run(self): while True: output = pickle.dumps(None, PICKLE_HIGHEST_PROTOCOL) glbs = self.mglobals() try: if DEBUG_MONITOR: logging.debug("****** Introspection request /Begin ******") command = PACKET_NOT_RECEIVED try: timeout = self.timeout if self.auto_refresh else None command = read_packet(self.i_request, timeout=timeout) if command is None: continue timed_out = False except socket.timeout: timed_out = True except struct.error: # This should mean that TRex GUI has crashed if DEBUG_MONITOR: logging.debug("struct.error -> quitting monitor") break if timed_out: if DEBUG_MONITOR: logging.debug( "connection timed out -> updating remote view") self.update_remote_view() if DEBUG_MONITOR: logging.debug( "****** Introspection request /End ******") continue if DEBUG_MONITOR: logging.debug("command: %r" % command) lcls = self.mlocals() result = eval(command, glbs, lcls) if DEBUG_MONITOR: logging.debug(" result: %r" % result) if self.pdb_obj is None: lcls["_"] = result # old com implementation: (see solution (1) in Issue 434) output = pickle.dumps(result, PICKLE_HIGHEST_PROTOCOL) # # new com implementation: (see solution (2) in Issue 434) # output = pickle.dumps((command, result), # PICKLE_HIGHEST_PROTOCOL) except SystemExit: break except: if DEBUG_MONITOR: logging.debug("error!") log_last_error(LOG_FILENAME, command) finally: try: if DEBUG_MONITOR: logging.debug("updating remote view") if self.refresh_after_eval: self.update_remote_view() self.refresh_after_eval = False if DEBUG_MONITOR: logging.debug("sending result") logging.debug( "****** Introspection request /End ******") if command is not PACKET_NOT_RECEIVED: if write_packet is None: # This may happen during interpreter shutdown break else: write_packet(self.i_request, output, already_pickled=True) except AttributeError as error: if "'NoneType' object has no attribute" in str(error): # This may happen during interpreter shutdown break else: raise except TypeError as error: if "'NoneType' object is not subscriptable" in str(error): # This may happen during interpreter shutdown break else: raise self.i_request.close() self.n_request.close()