예제 #1
0
    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")
예제 #2
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
예제 #3
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
예제 #4
0
 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
예제 #5
0
    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 []
예제 #6
0
    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()
예제 #7
0
 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)
예제 #8
0
    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")
예제 #9
0
    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()