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
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)
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 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 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 _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 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])
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")
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)
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])
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)
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)
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", ""))
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 OnFileSave(self, msg): """Load File message""" filename, tmp = msg.GetData() editor = PyStudioUtils.GetEditorForFile(self.mainwindow, filename) self._starttimer(editor)
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 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", ""))
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)