def do_validate(self):
        if rpdb2.is_valid_pwd(self.get_password()):
            return True

        baddpwd = _("The password should begin with a letter and continue "
                    "with any combination of digits, letters or underscores "
                    "(\'_\'). Only English characters are accepted for letters.")
        PyStudioUtils.error_dialog(self, baddpwd)
        return False
    def RunDebuggee(self):
        """Run rpdb2args"""
        flag, localpythonpath = ToolConfig.GetPythonExecutablePath("PyDbg")
        # TODO: convert errors to error codes and translate to meaningful
        #       messages on main thread.
        if not flag:
            # No configured Python
            return [(u"No Python", localpythonpath, u"NA"),]

        # No rpdb2 found in plugin
        if not pkg_resources.resource_exists("rpdb2", "rpdb2.py"):
            return ["No rpdb2 found"]

        rpdb2_script = pkg_resources.resource_filename("rpdb2", "rpdb2.py")

        if wx.Platform == "__WXMSW__":        
            self.rpdb2args += ["--pwd=%s" % RpdbDebugger.password]
        else:
            rpdb2_pw = GetPwdFile(RpdbDebugger.password)
            self.rpdb2args += ["--rid=%s" % rpdb2_pw]
        
        childPath, parentPath = PyStudioUtils.get_packageroot(self.filename)

        # Start rpdb2
        cmdargs = ""
        debuggee = childPath
        if self.debuggerargs:
            cmdargs = self.debuggerargs.split(" ")
            for i, cmd in enumerate(cmdargs):
                if cmd == "%SCRIPT%":
                    cmdargs[i] = debuggee
                elif cmd == "%MODULE%":
                    debuggee = PyStudioUtils.get_modulepath(childPath)
                    cmdargs[i] = debuggee

            cmdargs = self.rpdb2args + cmdargs
        else:
            cmdargs = self.rpdb2args + [debuggee,]
        allargs = cmdargs
        if self.programargs:
            allargs = allargs + self.programargs.split(" ")
        rpdb2_cmd = [localpythonpath, "-u", rpdb2_script] + allargs
        text = ""
        if self.pythonpath:
            text += "Using PYTHONPATH + %s\n" % u", ".join(self.pythonpath)
        text += "Rpdb2 command line: %s" % " ".join(rpdb2_cmd)
        text += "\nDirectory Variables file: %s\n\n" % self.dirvarfile
        self.debuggeewindow.SetText(_(text))
        self.debuggeewindow.calldebugger = self.RunDebugger
        RpdbDebugger().do_abort()
        RpdbDebugger().debuggerattachedtext = self.debuggerattachedtext
        RpdbDebugger().debuggerdetachedtext = self.debuggerdetachedtext
        RpdbDebugger().remoteprocess = False
        self.processcreator = AsyncProcessCreator(self.debuggeewindow, self.UpdateOutput, "PyDbg", parentPath, rpdb2_cmd, self.pythonpath)
        self.processcreator.start()
        util.Log("[PyDbg][info] Rpdb2 command running")
    def do_validate(self):
        if rpdb2.is_valid_pwd(self.get_password()):
            return True

        baddpwd = _(
            "The password should begin with a letter and continue "
            "with any combination of digits, letters or underscores "
            "(\'_\'). Only English characters are accepted for letters.")
        PyStudioUtils.error_dialog(self, baddpwd)
        return False
示例#4
0
    def OnCheckComplete(self, data):
        """Callback for when compile check"""
        if len(data) != 2:
            util.Log("[PyTools][err] OnCheckComplete Invalid Data %s" %
                     repr(data))
            return

        path = data[0]
        err = data[1]
        if err:
            line = -1

            # Python 3 outputs correct exception to stderr
            pat = re.compile('File "(.+)", line ([0-9]+)')
            matches = pat.findall(err)
            if len(matches) and len(matches[0]) == 2:
                match = matches[0]
                if match[1].isdigit():
                    line = int(matches[0][1])

            # Python 2 py_compile outputs a tuple of args
            if line < 0:
                pat = re.compile("\('.*', ([0-9]+),")
                matchs = pat.findall(err)
                if len(matchs) and matchs[0].isdigit():
                    line = max(0, int(matchs[0]) - 1)

            if line >= 0:
                mw = wx.GetApp().GetActiveWindow()
                buff = PyStudioUtils.GetEditorForFile(mw, path)
                if buff:
                    self._errdata[path] = (line, err)
                    buff.AddMarker(ed_marker.ErrorMarker(), line)
                    buff.GotoLine(line)
 def fillexpressiontype(self, res, idx):
     if not res:
         return
     value, w, error = res
     if error:
         value = error
     self.SetStringItem(idx, ExpressionsList.COL_TYPE, PyStudioUtils.get_unicodevalue(value))        
 def fillexpressionvalue(self, res, idx):
     if not res:
         return
     value, w, error = res
     if error:
         value = error
     self.SetStringItem(idx, ExpressionsList.COL_VALUE, PyStudioUtils.get_unicodevalue(value))        
     self.SetColumnWidth(ExpressionsList.COL_VALUE, wx.LIST_AUTOSIZE)
示例#7
0
 def SetStepMarker(self, fileName, lineNo):
     self.editor = PyStudioUtils.GetEditorOrOpenFile(self.mainwindow, fileName)
     if not self.editor:
         util.Log("[PyStudio][err] Unable to get editor for file: %s" % fileName)
         return
     self.editorlineno = lineNo - 1
     self.editor.GotoLine(self.editorlineno)
     self.editor.ShowStepMarker(self.editorlineno, show=True)
 def fillexpressiontype(self, res, idx):
     if not res:
         return
     value, w, error = res
     if error:
         value = error
     self.SetStringItem(idx, ExpressionsList.COL_TYPE,
                        PyStudioUtils.get_unicodevalue(value))
示例#9
0
 def OnFileLoad(self, msg):
     """Load File message"""
     editor = PyStudioUtils.GetEditorForFile(self._mw, msg.GetData())
     if ToolConfig.GetConfigValue(ToolConfig.TLC_LINT_AUTORUN):
         wx.CallAfter(self._onfileaccess, editor)
         self.UpdateForEditor(editor, True)
     else:
         self.UpdateForEditor(editor)
    def DoItemActivated(self, item):
        """Override to handle item activation
        @param item: TreeItem

        """
        path = self.GetPyData(item)
        if path and os.path.exists(path):
            if not os.path.isdir(path):
                PyStudioUtils.GetEditorOrOpenFile(self.Parent.MainWindow, path)
 def fillexpressionvalue(self, res, idx):
     if not res:
         return
     value, w, error = res
     if error:
         value = error
     self.SetStringItem(idx, ExpressionsList.COL_VALUE,
                        PyStudioUtils.get_unicodevalue(value))
     self.SetColumnWidth(ExpressionsList.COL_VALUE, wx.LIST_AUTOSIZE)
    def expand_item(self, item, variables, froot=False, fskip_expansion_check=False):
        if not self.ItemHasChildren(item):
            return

        if not froot and not fskip_expansion_check and self.IsExpanded(item):
            return

        if self.get_numberofchildren(item) > 0:
            return

        (expr, is_valid) = self.GetPyData(item)

        variables_with_expr = []
        for expression in variables:
            if hasattr(expression, "get") and expression.get("expr", None) == expr:
                variables_with_expr.append(expression)
        if variables_with_expr == []:
            return

        first_variable_with_expr = variables_with_expr[0]
        if first_variable_with_expr is None:
            return

        if "error" in first_variable_with_expr:
            return

        if first_variable_with_expr["n_subnodes"] == 0:
            self.SetItemHasChildren(item, False)
            return

        #
        # Create a list of the subitems.
        # The list is indexed by name or directory key.
        # In case of a list, no sorting is needed.
        #
        for subnode in first_variable_with_expr["subnodes"]:
            _name = unicode(subnode["name"])
            if not re.match(self.FilterExpr, _name):
                continue
            _type = unicode(subnode["type"])
            _value = PyStudioUtils.get_unicodevalue(subnode["repr"])

            child = self.AppendItem(item, _name)
            self.SetItemText(child, u' ' + _value, VariablesList.COL_VALUE)
            self.SetItemText(child, u' ' + _type, VariablesList.COL_TYPE)
            self.SetItemPyData(child, (subnode["expr"], subnode["fvalid"]))
            self.SetItemHasChildren(child, (subnode["n_subnodes"] > 0))
            # Add some bitmaps depending on the object type
            if subnode["type"] in ('type', 'module'):
                self.SetItemImage(child, self._imgmap[VariablesList.IMG_CLASS])
            elif subnode["type"] in ('function', 'builtin_function_or_method',
                                     'instancemethod'):
                self.SetItemImage(child, self._imgmap[VariablesList.IMG_FUNCT])
            else:
                self.SetItemImage(child, self._imgmap[VariablesList.IMG_VAR])

        self.Expand(item)
示例#13
0
    def _oncodeexecuted(self, res):
        """Expression execution callback"""
        if not res:
            return
        if len(res) == 2:
            warning, error = res
        else:
            error = res
            warning = None

        PyStudioUtils.error_dialog(self, error)
        if warning and not warning in self.ignoredwarnings:
            dlg = wx.MessageDialog(self,
                                   _("Would you like to ignore this warning for the rest of this session?\n\n%s") % warning,\
                                   _("Ignore Warning"),
                                   wx.YES_NO|wx.YES_DEFAULT|wx.ICON_WARNING)
            if dlg.ShowModal() == wx.ID_YES:
                self.ignoredwarnings[warning] = True
            dlg.Destroy()
    def _oncodeexecuted(self, res):
        """Expression execution callback"""
        if not res:
            return
        if len(res) == 2:
            warning, error = res
        else:
            error = res
            warning = None

        PyStudioUtils.error_dialog(self, error)
        if warning and not warning in self.ignoredwarnings:
            dlg = wx.MessageDialog(self,
                                   _("Would you like to ignore this warning for the rest of this session?\n\n%s") % warning,\
                                   _("Ignore Warning"),
                                   wx.YES_NO|wx.YES_DEFAULT|wx.ICON_WARNING)
            if dlg.ShowModal() == wx.ID_YES:
                self.ignoredwarnings[warning] = True
            dlg.Destroy()
    def _onitemactivatedcallback(self, res):
        if not res:
            return

        if len(res) == 2:
            warning, error = res
        else:
            error = res

        PyStudioUtils.error_dialog(self, error)

        if not warning in self.ignoredwarnings:
            dlg = wx.MessageDialog(self,
                                   _("%s\n\nClick 'Cancel' to ignore this warning in this session.") % warning,\
                                   _("Warning"),
                                   wx.OK|wx.CANCEL|wx.YES_DEFAULT|wx.ICON_WARNING)
            res = dlg.ShowModal()
            dlg.Destroy()

            if res == wx.ID_CANCEL:
                self.ignoredwarnings[warning] = True
    def _onitemactivatedcallback(self, res):
        if not res:
            return

        if len(res) == 2:
            warning, error = res
        else:
            error = res

        PyStudioUtils.error_dialog(self, error)

        if not warning in self.ignoredwarnings:
            dlg = wx.MessageDialog(self,
                                   _("%s\n\nClick 'Cancel' to ignore this warning in this session.") % warning,\
                                   _("Warning"),
                                   wx.OK|wx.CANCEL|wx.YES_DEFAULT|wx.ICON_WARNING)
            res = dlg.ShowModal()
            dlg.Destroy()

            if res == wx.ID_CANCEL:
                self.ignoredwarnings[warning] = True
    def LoadData(self, data, fname=None):
        """Load data into the cache and display it in the list
        @param fname: filename
        @param data: Lint data [(errorType, errorText, errorLine),]

        """
        if fname is None:
            if not self.editor:
                return  # TODO: Log
            fname = self.editor.GetFileName()
        else:
            self.editor = PyStudioUtils.GetEditorOrOpenFile(self._mw, fname)
        CheckResultsList._cache[fname] = LintData(data)
        self._PopulateRows(CheckResultsList._cache[fname])
示例#18
0
 def OnItemActivated(self, evt):
     """Go to the file"""
     idx = evt.GetIndex()
     fileName = self.GetItem(idx, BreakPointsList.COL_FILE).GetText()
     if not fileName:
         return
     editor = PyStudioUtils.GetEditorOrOpenFile(self._mainw, fileName)
     if editor:
         try:
             lineno = int(
                 self.GetItem(idx, BreakPointsList.COL_LINE).GetText())
             editor.GotoLine(lineno - 1)
         except ValueError:
             pass
def GetPythonExecutablePath(info):
    # Figure out what Python to use
    # 1) First check configuration
    # 2) Second check for it on the path
    localpythonpath = GetConfigValue(TLC_PYTHON_PATH)
    if not localpythonpath:
        localpythonpath = PyStudioUtils.GetDefaultPython()

    if localpythonpath:
        util.Log("[%s][info] Using Python: %s" % (info, localpythonpath))
        return (True, localpythonpath)
    else:
        # No configured Python
        util.Log("[%s][info] %s" % (info, NOPYTHONERROR))
        return (False, NOPYTHONERROR)
    def OnContextMenu(self, evt):
        """Handle context menu events"""
        e_id = evt.Id
        path = self._menu.GetUserData('path')
        dname = path
        if not os.path.isdir(path):
            dname = os.path.dirname(path)

        if e_id == ProjectTree.ID_EDIT_FILE:
            PyStudioUtils.GetEditorOrOpenFile(self.Parent.MainWindow, path)
        elif e_id in (ProjectTree.ID_OPEN_FILE, ProjectTree.ID_REVEL_FILE):
            self.OpenPathWithFM(path,
                                revel=(e_id == ProjectTree.ID_REVEL_FILE))
        elif e_id == ProjectTree.ID_NEW_FILE:
            self.CreateNewFile(dname)
        elif e_id in (ProjectTree.ID_NEW_FOLDER, ProjectTree.ID_NEW_PACKAGE):
            self.CreateNewFolder(dname, e_id == ProjectTree.ID_NEW_PACKAGE)
        elif e_id == ed_glob.ID_DELETE:
            # TODO need error handling?
            if dname == path:
                cmsg = _(
                    "Are you sure you want to delete '%s' and all of its contents?"
                )
            else:
                cmsg = _("Are you sure you want to delete '%s'?")
            name = os.path.basename(path)
            result = wx.MessageBox(cmsg % name,
                                   _("Delete?"),
                                   style=wx.YES_NO | wx.CENTER
                                   | wx.ICON_QUESTION)
            if result == wx.YES:
                self.FileController.MoveToTrash(path)
        elif e_id == ProjectTree.ID_RENAME_FILE:
            item = self._menu.GetUserData('itemId')
            if item:
                self.EditLabel(item)
        elif e_id == ProjectTree.ID_PROPERTIES:
            pass  # TODO: project properties dialog
        else:
            # Handle Custom Menu options
            handler = self._menu.GetHandler(e_id)
            if handler:
                handler(path)
    def __DoLayout(self):
        sizer = wx.BoxSizer(wx.VERTICAL)

        # Python executable configuration
        config = Profile_Get(PYTOOL_CONFIG, default=dict())
        pythonpath = config.get(TLC_PYTHON_PATH, None)
        if not pythonpath:
            pythonpath = PyStudioUtils.GetDefaultPython()
        all_pythons = config.get(TLC_ALL_PYTHON_PATHS, [])
        if pythonpath:
            pythonpath = os.path.normcase(
                pythonpath
            )  #TODO: this will likely cause problems on non Windows
            config[TLC_PYTHON_PATH] = pythonpath
            if not pythonpath in all_pythons:
                all_pythons.append(pythonpath)
        config[TLC_ALL_PYTHON_PATHS] = all_pythons
        ## Layout Python path selections
        hsizer = wx.BoxSizer(wx.HORIZONTAL)
        self._python_path_combo.Items = all_pythons
        self._python_path_combo.StringSelection = pythonpath
        self._python_path_combo.ToolTip = wx.ToolTip(
            _("Currently active Python"))
        hsizer.Add(wx.StaticText(self, label=_("Python Path:")), 0, wx.ALL, 5)
        hsizer.Add(self._python_path_combo, 1,
                   wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
        hsizer.Add(self._add_path, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5)
        hsizer.Add(self._rm_path, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5)
        sizer.Add(hsizer, 0, wx.EXPAND | wx.ALL, 8)
        # Syntax check
        self._check_on_save_cb.ToolTip = wx.ToolTip(
            _("Mark syntax errors in buffer after save"))
        self._check_on_save_cb.SetValue(
            GetConfigValue(TLC_COMPILE_ON_SAVE, True))
        sizer.Add(self._check_on_save_cb, 0, wx.ALL, 5)
        # Project
        self._load_proj_cb.ToolTip = wx.ToolTip(
            _("Automatically reload last project at startup."))
        self._load_proj_cb.SetValue(GetConfigValue(TLC_LOAD_LAST_PROJECT,
                                                   True))
        sizer.Add(self._load_proj_cb, 0, wx.ALL, 5)

        self.SetSizer(sizer)
    def OnFrameSelected(self, evt):
        index = evt.GetIndex()
        if self.previndex == index:
            return
        filename = self.GetItem(index, StackFrameList.COL_FILE).GetText()
        if index > self.GetItemCount() - 4:
            if filename and os.path.basename(filename) == "rpdb2.py":
                return
        self.previndex = index
        RpdbDebugger().set_frameindex(index)

        if not filename:
            return
        editor = PyStudioUtils.GetEditorOrOpenFile(self._mainw, filename)
        if editor:
            try:
                lineno = int(
                    self.GetItem(index, StackFrameList.COL_LINE).GetText())
                editor.GotoLine(lineno - 1)
            except ValueError:
                util.Log("[PyStudio][err] StackFrame: failed to jump to file")
示例#23
0
    def _issysexit(self, variables):
        if not variables:
            wx.CallAfter(self._unhandledexception)
            return
        variables_with_expr = []
        for expression in variables:
            if hasattr(expression, "get"):
                variables_with_expr.append(expression)
        if variables_with_expr == []:
            wx.CallAfter(self._unhandledexception)
            return

        first_variable_with_expr = variables_with_expr[0]
        if first_variable_with_expr is None:
            wx.CallAfter(self._unhandledexception)
            return

        if "error" in first_variable_with_expr:
            wx.CallAfter(self._unhandledexception)
            return

        if first_variable_with_expr["n_subnodes"] == 0:
            wx.CallAfter(self._unhandledexception)
            return

        #
        # Create a list of the subitems.
        # The list is indexed by name or directory key.
        # In case of a list, no sorting is needed.
        #
        for subnode in first_variable_with_expr["subnodes"]:
            _name = unicode(subnode["name"])
            _type = unicode(subnode["type"])
            _value = PyStudioUtils.get_unicodevalue(subnode["repr"])
            if _name == u"type" and _value.find(u"SystemExit") != -1:
                RpdbDebugger().unhandledexception = False
                RpdbDebugger().do_go()
                return

        wx.CallAfter(self._unhandledexception)
示例#24
0
    def OnFileSaved(self, msg):
        """Performs file saved checks"""
        data = msg.GetData()
        if not data[0] or data[1] != synglob.ID_LANG_PYTHON:
            return

        buff = None
        for mw in wx.GetApp().GetMainWindows():
            if mw.Id == msg.Context:
                buff = PyStudioUtils.GetEditorForFile(mw, data[0])
                break

        if not buff:
            return

        buff.RemoveAllMarkers(ed_marker.ErrorMarker())
        if data[0] in self._errdata:
            del self._errdata[data[0]]

        if ToolConfig.GetConfigValue(ToolConfig.TLC_COMPILE_ON_SAVE, True):
            # Run the compilation check
            RunAsyncTask("CompileCheck", self.OnCheckComplete,
                         self.DoCompileCheck, data[0])
示例#25
0
 def OnCopyModulePath(self, editor, evt):
     path = os.path.normcase(editor.GetFileName())
     if path is not None:
         childPath, foo = PyStudioUtils.get_packageroot(path)
         modulepath = PyStudioUtils.get_modulepath(childPath)
         util.SetClipboardText(modulepath)
示例#26
0
    def printerror(self, processcreator, err):
        processcreator.AddText(_("\n%s\n" % err))
    
    def attached_callsessionmanagerfn(self, fn, *args, **kwargs):
        if not self.attached:
            return None
        ex = None
        try:
            return fn(*args, **kwargs)
        except rpdb2.NotAttached, ex:
            self.attached = False
        except Exception, ex:
            util.Log("[PyDbg][err] %s" % traceback.format_exc())
        if self.mainwindow:
            err = rpdb2.g_error_mapping.get(type(ex), repr(ex))
            PyStudioUtils.error_dialog(self.mainwindow, err)
        return None
    
    def callsessionmanagerfn(self, fn, *args, **kwargs):
        ex = None
        try:
            return fn(*args, **kwargs)
        except Exception, ex:
            util.Log("[PyDbg][err] %s" % traceback.format_exc())
        if self.mainwindow:
            err = rpdb2.g_error_mapping.get(type(ex), repr(ex))
            PyStudioUtils.error_dialog(self.mainwindow, err)
        return None

    def do_abort(self):
        self.do_detach()
    def RunSyntaxCheck(self):
        """Run pep8
        @return: tuple([list_of_rows,], string)

        """

        flag, localpythonpath = ToolConfig.GetPythonExecutablePath("Pep8")

        if not flag:
            # No configured Python
            return ([(u"No Python", localpythonpath, u"NA")], u"None")

        childPath, parentPath = PyStudioUtils.get_packageroot(self.filename)

        # Start pep8 check
        pythoncode = "import sys,pep8;sys.argv=[u'pep8', %s];pep8._main()" % repr(
            childPath)
        pep8_cmd = [localpythonpath, "-c", pythoncode]
        processcreator = ProcessCreator("Pep8", parentPath, pep8_cmd,
                                        self.pythonpath)
        process = processcreator.createprocess()
        stdoutdata, stderrdata = process.communicate()
        processcreator.restorepath()

        util.Log("[Pep8][info] stdout %s" % stdoutdata)
        util.Log("[Pep8][info] stderr %s" % stderrdata)
        stderrlower = stderrdata.lower()
        ind = stderrlower.find("importerror")
        if ind != -1:
            if stderrlower.find("pep8", ind) != -1:
                return ([(u"No Pep8", self.nopep8error, u"NA")], u"None")

        # The parseable line format is:
        #       '%(path)s:%(line)s: [%(sigle)s%(obj)s] %(msg)s'
        regex = re.compile(r"(.*):(.*):(.*): ([A-Z])[0-9]* (.*)%s" %
                           os.linesep)
        rows = []
        # TODO: returned messages need to be translatable
        if self.pythonpath:
            rows.append((u"***", u"Using PYTHONPATH + %s"\
                          % u", ".join(self.pythonpath), u"NA"))
        rows.append(
            (u"***", u"Pep8 command line: %s" % " ".join(pep8_cmd), u"NA"))
        rowsdict = {}
        for matcher in regex.finditer(stdoutdata):
            if matcher is None:
                continue
            mtypeabr = matcher.group(4)
            linenostr = matcher.group(2)
            colnostr = matcher.group(3)
            mtext = matcher.group(5)
            if mtypeabr in (u"E", u"F"):
                mtype = u"Error"
            else:  #TODO: add more specific filtering? / do translations on display
                mtype = u"Warning"

            outtext = "%s: %s" % (colnostr, mtext)
            try:
                lineno = int(linenostr)
                mtyperows = rowsdict.get(mtype)
                if not mtyperows:
                    mtyperows = {}
                    rowsdict[mtype] = mtyperows
                linenorows = mtyperows.get(lineno)
                if not linenorows:
                    linenorows = set()
                    mtyperows[lineno] = linenorows
                linenorows.add(outtext)
            except:
                rows.append((mtype, outtext, linenostr))

        for mtype in sorted(rowsdict):
            mtyperows = rowsdict[mtype]
            for lineno in sorted(mtyperows):
                linenorows = mtyperows[lineno]
                for outtext in sorted(linenorows):
                    rows.append((mtype, outtext, lineno))

        util.Log("[Pep8][info] Pep8 command finished running")
        return (rows, stdoutdata)
示例#28
0
    def RunSyntaxCheck(self):
        """Run pylint"""

        flag, localpythonpath = ToolConfig.GetPythonExecutablePath("PyLint")

        if not flag:
            # No configured Python
            return ([(u"No Python", localpythonpath, u"NA")], u"None")

        childPath, parentPath = PyStudioUtils.get_packageroot(self.filename)

        # Start pylint
        modpath = PyStudioUtils.get_modulepath(childPath)
        allargs = self.pylintargs + [
            modpath,
        ]
        pythoncode = "from pylint import lint;lint.Run(%s)" % repr(allargs)
        plint_cmd = [localpythonpath, "-c", pythoncode]
        processcreator = ProcessCreator("Pylint", parentPath, plint_cmd,
                                        self.pythonpath)
        process = processcreator.createprocess()
        stdoutdata, stderrdata = process.communicate()
        processcreator.restorepath()

        util.Log("[Pylint][info] stdout %s" % stdoutdata)
        util.Log("[Pylint][info] stderr %s" % stderrdata)
        stderrlower = stderrdata.lower()
        ind = stderrlower.find("importerror")
        if ind != -1:
            if stderrlower.find("pylint", ind) != -1:
                return ([(u"No Pylint", self.nopylinterror, u"NA")], u"None")

        # The parseable line format is:
        #       '%(path)s:%(line)s: [%(sigle)s%(obj)s] %(msg)s'
        regex = re.compile(r"(.*):(.*): \[([A-Z])[, ]*(.*)\] (.*)%s" %
                           os.linesep)
        rows = []
        # TODO: returned messages need to be translatable
        if self.pythonpath:
            rows.append((u"***", u"Using PYTHONPATH + %s"\
                          % u", ".join(self.pythonpath), u"NA"))
        rows.append(
            (u"***", u"Pylint command line: %s" % " ".join(plint_cmd), u"NA"))
        rows.append(
            (u"***", u"Directory Variables file: %s" % self.dirvarfile, u"NA"))
        rowsdict = {}
        lastmatchindex = 0
        for matcher in regex.finditer(stdoutdata):
            if matcher is None:
                continue
            mtypeabr = matcher.group(3)
            linenostr = matcher.group(2)
            classmeth = matcher.group(4)
            mtext = matcher.group(5)
            lastmatchindex = matcher.end(5)
            if mtypeabr in (u"E", u"F"):
                mtype = u"Error"
            elif mtypeabr == u"C":
                mtype = u"Convention"
            elif mtypeabr == u"R":
                mtype = u"Refactor"
            else:  # TODO: add more specific filtering? / do translations on display
                mtype = u"Warning"

            outtext = mtext
            if classmeth:
                outtext = u"[%s] %s" % (classmeth, outtext)

            try:
                lineno = int(linenostr)
                mtyperows = rowsdict.get(mtype)
                if not mtyperows:
                    mtyperows = {}
                    rowsdict[mtype] = mtyperows
                linenorows = mtyperows.get(lineno)
                if not linenorows:
                    linenorows = set()
                    mtyperows[lineno] = linenorows
                linenorows.add(outtext)
            except:
                rows.append((mtype, outtext, linenostr))

        for mtype in sorted(rowsdict):
            mtyperows = rowsdict[mtype]
            for lineno in sorted(mtyperows):
                linenorows = mtyperows[lineno]
                for outtext in sorted(linenorows):
                    rows.append((mtype, outtext, lineno))

        index = stdoutdata.find("Report", lastmatchindex)
        util.Log("[PyLint][info] Pylint command finished running")
        if index == -1:
            return (rows, "")
        return (rows, stdoutdata[index:].replace("\r", ""))
示例#29
0
    def RunDebuggee(self):
        """Run rpdb2args"""
        flag, localpythonpath = ToolConfig.GetPythonExecutablePath("PyDbg")
        # TODO: convert errors to error codes and translate to meaningful
        #       messages on main thread.
        if not flag:
            # No configured Python
            return [
                (u"No Python", localpythonpath, u"NA"),
            ]

        # No rpdb2 found in plugin
        if not pkg_resources.resource_exists("rpdb2", "rpdb2.py"):
            return ["No rpdb2 found"]

        rpdb2_script = pkg_resources.resource_filename("rpdb2", "rpdb2.py")

        if wx.Platform == "__WXMSW__":
            self.rpdb2args += ["--pwd=%s" % RpdbDebugger.password]
        else:
            rpdb2_pw = GetPwdFile(RpdbDebugger.password)
            self.rpdb2args += ["--rid=%s" % rpdb2_pw]

        childPath, parentPath = PyStudioUtils.get_packageroot(self.filename)

        # Start rpdb2
        cmdargs = ""
        debuggee = childPath
        if self.debuggerargs:
            cmdargs = self.debuggerargs.split(" ")
            for i, cmd in enumerate(cmdargs):
                if cmd == "%SCRIPT%":
                    cmdargs[i] = debuggee
                elif cmd == "%MODULE%":
                    debuggee = PyStudioUtils.get_modulepath(childPath)
                    cmdargs[i] = debuggee

            cmdargs = self.rpdb2args + cmdargs
        else:
            cmdargs = self.rpdb2args + [
                debuggee,
            ]
        allargs = cmdargs
        if self.programargs:
            allargs = allargs + self.programargs.split(" ")
        rpdb2_cmd = [localpythonpath, "-u", rpdb2_script] + allargs
        text = ""
        if self.pythonpath:
            text += "Using PYTHONPATH + %s\n" % u", ".join(self.pythonpath)
        text += "Rpdb2 command line: %s" % " ".join(rpdb2_cmd)
        text += "\nDirectory Variables file: %s\n\n" % self.dirvarfile
        self.debuggeewindow.SetText(_(text))
        self.debuggeewindow.calldebugger = self.RunDebugger
        RpdbDebugger().do_abort()
        RpdbDebugger().debuggerattachedtext = self.debuggerattachedtext
        RpdbDebugger().debuggerdetachedtext = self.debuggerdetachedtext
        RpdbDebugger().remoteprocess = False
        self.processcreator = AsyncProcessCreator(self.debuggeewindow,
                                                  self.UpdateOutput, "PyDbg",
                                                  parentPath, rpdb2_cmd,
                                                  self.pythonpath)
        self.processcreator.start()
        util.Log("[PyDbg][info] Rpdb2 command running")
class RpdbDebugger(object):
    __metaclass__ = ebmlib.Singleton

    fAllowUnencrypted = True
    fRemote = False
    host = "localhost"
    fAttach = True
    fchdir = False
    password = "******"

    def __init__(self):
        super(RpdbDebugger, self).__init__()

        # Setup
        self.sessionmanager = rpdb2.CSessionManager(RpdbDebugger.password, \
            RpdbDebugger.fAllowUnencrypted, RpdbDebugger.fRemote, RpdbDebugger.host)
        self.breakpointmanager = RpdbBreakpointsManager(self)
        self.statemanager = RpdbStateManager(self)
        self.stackframemanager = RpdbStackFrameManager(self)
        self.threadmanager = RpdbThreadsManager(self)
        self.variablesmanager = RpdbVariablesManager(self)

        # attributes that will be set later
        self.attached = False
        self.analyzing = False
        self.broken = False
        self.mainwindow = None
        self.processcreator = None
        self.breakpoints = {}
        self.breakpoints_installed = False
        self.curstack = {}
        self.unhandledexception = False
        self.debuggerattachedtext = None
        self.debuggerdetachedtext = None
        self.remoteprocess = False
        self.abortattach = False

        # functions that will be set later

        # message handler
        self.conflictingmodules = lambda x: None
        self.setstepmarker = lambda x, y: None
        self.clearstepmarker = lambda: None
        self.setstepmarker = lambda x, y: None
        self.restorestepmarker = lambda x: None
        # debuggee shelf
        self.debugbuttonsupdate = lambda: None
        self.disabledebugbuttons = lambda: None
        # breakpoints shelf
        self.saveandrestorebreakpoints = lambda: None
        # stackframe shelf
        self.clearframe = lambda: None
        self.selectframe = lambda x: None
        self.updatestacklist = lambda x: None
        # thread shelf
        self.clearthread = lambda: None
        self.updatethread = lambda x, y, z: None
        self.updatethreadlist = lambda x, y: None
        # variables shelf
        self.clearlocalvariables = lambda: None
        self.clearglobalvariables = lambda: None
        self.clearexceptions = lambda: None
        self.updatelocalvariables = lambda x, y: (None, None)
        self.updateglobalvariables = lambda x, y: (None, None)
        self.updateexceptions = lambda x, y: (None, None)
        self.catchunhandledexception = lambda: None
        self.updateanalyze = lambda: None
        # expressions shelf
        self.setexpression = lambda x, y: None
        self.restoreexpressions = lambda: None
        self.saveandrestoreexpressions = lambda: None
        self.clearexpressionvalues = lambda: None

    def clear_all(self):
        self.breakpoints_installed = False
        self.curstack = {}
        self.unhandledexception = False
        self.abortattach = False
        self.attached = False
        self.analyzing = False
        self.broken = False
        self.processcreator = None
        self.debuggerattachedtext = None
        self.debuggerdetachedtext = None
        self.clearstepmarker()
        self.clearframe()
        self.clearthread()
        self.clearlocalvariables()
        self.clearglobalvariables()
        self.clearexceptions()
        self.clearexpressionvalues()
        self.saveandrestoreexpressions()
        self.saveandrestorebreakpoints()
        self.updateanalyze()

    def isrpdbbreakpoint(self, filepath, lineno):
        if filepath.find("rpdb2.py") == -1:
            return False
        bpinfile = self.breakpoints.get(filepath)
        if not bpinfile:
            return True
        if not bpinfile.get(lineno):
            return True
        return False

    def attach(self, processcreator):
        if not processcreator:
            return
        self.processcreator = processcreator
        pid = str(processcreator.GetPID())
        tries = 0
        ex = None

        while tries != 5:
            sleep(1)
            util.Log("[PyDbg][info] Trying to Attach")
            ex = None
            try:
                if self.abortattach:
                    self.do_abort()
                    break
                self.sessionmanager.attach(pid, encoding=rpdb2.detect_locale())
                self.attached = True
                break
            except Exception, ex:
                tries = tries + 1
        ed_msg.PostMessage(ed_msg.EDMSG_PROGRESS_SHOW,
                           (self.mainwindow.GetId(), False))
        if ex:
            self.do_abort()
            err = rpdb2.g_error_mapping.get(type(ex), repr(ex))
            err = "Failed to attach. Error: %s" % err
            util.Log("[PyDbg][err] %s" % err)
            wx.CallAfter(self.printerror, processcreator, err)
            PyStudioUtils.error_dialog(self.mainwindow, err)
            return
        util.Log("[PyDbg][info] Running")
        processcreator.AddText(self.debuggerattachedtext)
    def printerror(self, processcreator, err):
        processcreator.AddText(_("\n%s\n" % err))

    def attached_callsessionmanagerfn(self, fn, *args, **kwargs):
        if not self.attached:
            return None
        ex = None
        try:
            return fn(*args, **kwargs)
        except rpdb2.NotAttached, ex:
            self.attached = False
        except Exception, ex:
            util.Log("[PyDbg][err] %s" % traceback.format_exc())
        if self.mainwindow:
            err = rpdb2.g_error_mapping.get(type(ex), repr(ex))
            PyStudioUtils.error_dialog(self.mainwindow, err)
        return None

    def callsessionmanagerfn(self, fn, *args, **kwargs):
        ex = None
        try:
            return fn(*args, **kwargs)
        except Exception, ex:
            util.Log("[PyDbg][err] %s" % traceback.format_exc())
        if self.mainwindow:
            err = rpdb2.g_error_mapping.get(type(ex), repr(ex))
            PyStudioUtils.error_dialog(self.mainwindow, err)
        return None

    def do_abort(self):
        self.do_detach()
示例#32
0
 def OnCopyModulePath(self, editor, evt):
     path = os.path.normcase(editor.GetFileName())
     if path is not None:
         childPath, foo = PyStudioUtils.get_packageroot(path)
         modulepath = PyStudioUtils.get_modulepath(childPath)
         util.SetClipboardText(modulepath)
示例#33
0
 def OnFileSave(self, msg):
     """Load File message"""
     filename, tmp = msg.GetData()
     editor = PyStudioUtils.GetEditorForFile(self.mainwindow, filename)
     self._starttimer(editor)
示例#34
0
 def OnFileLoad(self, msg):
     """Load File message"""
     editor = PyStudioUtils.GetEditorForFile(self.mainwindow, msg.GetData())
     self._starttimer(editor)
    def RunSyntaxCheck(self):
        """Run pep8
        @return: tuple([list_of_rows,], string)

        """

        flag, localpythonpath = ToolConfig.GetPythonExecutablePath("Pep8")

        if not flag:
            # No configured Python
            return ([(u"No Python", localpythonpath, u"NA")], u"None")

        childPath, parentPath = PyStudioUtils.get_packageroot(self.filename)

        # Start pep8 check
        pythoncode = "import sys,pep8;sys.argv=[u'pep8', %s];pep8._main()" % repr(childPath)
        pep8_cmd = [localpythonpath, "-c", pythoncode]
        processcreator = ProcessCreator("Pep8", parentPath, pep8_cmd, self.pythonpath)
        process = processcreator.createprocess()
        stdoutdata, stderrdata = process.communicate()
        processcreator.restorepath()

        util.Log("[Pep8][info] stdout %s" % stdoutdata)
        util.Log("[Pep8][info] stderr %s" % stderrdata)
        stderrlower = stderrdata.lower()
        ind = stderrlower.find("importerror")
        if ind != -1:
            if stderrlower.find("pep8", ind) != -1:
                return ([(u"No Pep8", self.nopep8error, u"NA")], u"None")

        # The parseable line format is:
        #       '%(path)s:%(line)s: [%(sigle)s%(obj)s] %(msg)s'
        regex = re.compile(r"(.*):(.*):(.*): ([A-Z])[0-9]* (.*)%s" % os.linesep)
        rows = []
        # TODO: returned messages need to be translatable
        if self.pythonpath:
            rows.append((u"***", u"Using PYTHONPATH + %s"\
                          % u", ".join(self.pythonpath), u"NA"))
        rows.append((u"***", u"Pep8 command line: %s" % " ".join(pep8_cmd), u"NA"))
        rowsdict = {}
        for matcher in regex.finditer(stdoutdata):
            if matcher is None:
                continue
            mtypeabr = matcher.group(4)
            linenostr = matcher.group(2)
            colnostr = matcher.group(3)
            mtext = matcher.group(5)
            if mtypeabr in (u"E", u"F"):
                mtype = u"Error"
            else: #TODO: add more specific filtering? / do translations on display
                mtype = u"Warning"

            outtext = "%s: %s" % (colnostr, mtext)
            try:
                lineno = int(linenostr)
                mtyperows = rowsdict.get(mtype)
                if not mtyperows:
                    mtyperows = {}
                    rowsdict[mtype] = mtyperows
                linenorows = mtyperows.get(lineno)
                if not linenorows:
                    linenorows = set()
                    mtyperows[lineno] = linenorows
                linenorows.add(outtext)
            except:
                rows.append((mtype, outtext, linenostr))

        for mtype in sorted(rowsdict):
            mtyperows = rowsdict[mtype]
            for lineno in sorted(mtyperows):
                linenorows = mtyperows[lineno]
                for outtext in sorted(linenorows):
                    rows.append((mtype, outtext, lineno))
        
        util.Log("[Pep8][info] Pep8 command finished running")
        return (rows, stdoutdata)
    def expand_item(self,
                    item,
                    variables,
                    froot=False,
                    fskip_expansion_check=False):
        if not self.ItemHasChildren(item):
            return

        if not froot and not fskip_expansion_check and self.IsExpanded(item):
            return

        if self.get_numberofchildren(item) > 0:
            return

        (expr, is_valid) = self.GetPyData(item)

        variables_with_expr = []
        for expression in variables:
            if hasattr(expression, "get") and expression.get("expr",
                                                             None) == expr:
                variables_with_expr.append(expression)
        if variables_with_expr == []:
            return

        first_variable_with_expr = variables_with_expr[0]
        if first_variable_with_expr is None:
            return

        if "error" in first_variable_with_expr:
            return

        if first_variable_with_expr["n_subnodes"] == 0:
            self.SetItemHasChildren(item, False)
            return

        #
        # Create a list of the subitems.
        # The list is indexed by name or directory key.
        # In case of a list, no sorting is needed.
        #
        for subnode in first_variable_with_expr["subnodes"]:
            _name = unicode(subnode["name"])
            if not re.match(self.FilterExpr, _name):
                continue
            _type = unicode(subnode["type"])
            _value = PyStudioUtils.get_unicodevalue(subnode["repr"])

            child = self.AppendItem(item, _name)
            self.SetItemText(child, u' ' + _value, VariablesList.COL_VALUE)
            self.SetItemText(child, u' ' + _type, VariablesList.COL_TYPE)
            self.SetItemPyData(child, (subnode["expr"], subnode["fvalid"]))
            self.SetItemHasChildren(child, (subnode["n_subnodes"] > 0))
            # Add some bitmaps depending on the object type
            if subnode["type"] in ('type', 'module'):
                self.SetItemImage(child, self._imgmap[VariablesList.IMG_CLASS])
            elif subnode["type"] in ('function', 'builtin_function_or_method',
                                     'instancemethod'):
                self.SetItemImage(child, self._imgmap[VariablesList.IMG_FUNCT])
            else:
                self.SetItemImage(child, self._imgmap[VariablesList.IMG_VAR])

        self.Expand(item)
    def RunSyntaxCheck(self):
        """Run pylint"""

        flag, localpythonpath = ToolConfig.GetPythonExecutablePath("PyLint")

        if not flag:
            # No configured Python
            return ([(u"No Python", localpythonpath, u"NA")], u"None")

        childPath, parentPath = PyStudioUtils.get_packageroot(self.filename)

        # Start pylint
        modpath = PyStudioUtils.get_modulepath(childPath)
        allargs = self.pylintargs + [modpath,]
        pythoncode = "from pylint import lint;lint.Run(%s)" % repr(allargs)
        plint_cmd = [localpythonpath, "-c", pythoncode]
        processcreator = ProcessCreator("Pylint", parentPath, plint_cmd, self.pythonpath)
        process = processcreator.createprocess()
        stdoutdata, stderrdata = process.communicate()
        processcreator.restorepath()

        util.Log("[Pylint][info] stdout %s" % stdoutdata)
        util.Log("[Pylint][info] stderr %s" % stderrdata)
        stderrlower = stderrdata.lower()
        ind = stderrlower.find("importerror")
        if ind != -1:
            if stderrlower.find("pylint", ind) != -1:
                return ([(u"No Pylint", self.nopylinterror, u"NA")], u"None")

        # The parseable line format is:
        #       '%(path)s:%(line)s: [%(sigle)s%(obj)s] %(msg)s'
        regex = re.compile(r"(.*):(.*): \[([A-Z])[, ]*(.*)\] (.*)%s" % os.linesep)
        rows = []
        # TODO: returned messages need to be translatable
        if self.pythonpath:
            rows.append((u"***", u"Using PYTHONPATH + %s"\
                          % u", ".join(self.pythonpath), u"NA"))
        rows.append((u"***", u"Pylint command line: %s" % " ".join(plint_cmd), u"NA"))
        rows.append((u"***", u"Directory Variables file: %s" % self.dirvarfile, u"NA"))
        rowsdict = {}
        lastmatchindex = 0
        for matcher in regex.finditer(stdoutdata):
            if matcher is None:
                continue
            mtypeabr = matcher.group(3)
            linenostr = matcher.group(2)
            classmeth = matcher.group(4)
            mtext = matcher.group(5)
            lastmatchindex = matcher.end(5)
            if mtypeabr in (u"E", u"F"):
                mtype = u"Error"
            elif mtypeabr == u"C":
                mtype = u"Convention"
            elif mtypeabr == u"R":
                mtype = u"Refactor"
            else: # TODO: add more specific filtering? / do translations on display
                mtype = u"Warning"

            outtext = mtext
            if classmeth:
                outtext = u"[%s] %s" % (classmeth, outtext)

            try:
                lineno = int(linenostr)
                mtyperows = rowsdict.get(mtype)
                if not mtyperows:
                    mtyperows = {}
                    rowsdict[mtype] = mtyperows
                linenorows = mtyperows.get(lineno)
                if not linenorows:
                    linenorows = set()
                    mtyperows[lineno] = linenorows
                linenorows.add(outtext)
            except:
                rows.append((mtype, outtext, linenostr))

        for mtype in sorted(rowsdict):
            mtyperows = rowsdict[mtype]
            for lineno in sorted(mtyperows):
                linenorows = mtyperows[lineno]
                for outtext in sorted(linenorows):
                    rows.append((mtype, outtext, lineno))

        index = stdoutdata.find("Report", lastmatchindex)
        util.Log("[PyLint][info] Pylint command finished running")
        if index == -1:
            return (rows, "")
        return (rows, stdoutdata[index:].replace("\r", ""))
示例#38
0
 def OnItemActivate(self, evt):
     """Go to the file"""
     idx = evt.GetIndex()
     fname = self.GetItem(idx, 0).GetText()
     if os.path.exists(fname):
         PyStudioUtils.GetEditorOrOpenFile(self._mainw, fname)