def GetMacCabeMetric(path): """ """ complexity = 0.0 try: p = os.path.dirname(path) if p not in sys.path: sys.path.append(p) import maccabe as codepaths except ImportError as info: msg = 'ERROR: maccabe module not imported: %s\n' % info sys.stderr.write(msg) return complexity else: cls = Components.GetClass(path) if inspect.isclass(cls): args = Components.GetArgs(cls) devs = getInstance(cls, args) ### Get class of model if not path.endswith('.pyc'): ### mcCabe complexity ### beware to use tab for devs code of models L = [ getattr(cls, fct) for fct in ('extTransition', 'intTransition', 'outputFnc') if hasattr(cls, fct) ] source_list = list(map(inspect.getsource, L)) L_args = [] for text in source_list: ### textwrap for deleting the indentation ast = codepaths.ast.parse(textwrap.dedent(text).strip()) visitor = codepaths.PathGraphingAstVisitor() visitor.preorder(ast, visitor) for graph in visitor.graphs.values(): complexity += graph.complexity() return complexity ### for .pyc file else: return 0.0 else: return 0.0
def OnItemDeselected(self, event): """ Item has been deselected """ line_number = self.getColumnText(self.currentItem, 2) python_path = self.getColumnText(self.currentItem, 4) if line_number != "": ### DEVS model retrieve devs = getInstance(Components.GetClass(python_path)) ### check error and change image if not isinstance(devs, tuple): self.SetItemImage(self.currentItem, self.idx2)
def __init__(self, parent, id, model=None): wx.Choicebook.__init__(self, parent, id) self.parent = parent cls = Components.GetClass(model.python_path) if inspect.isclass(cls): pageTexts = { _('Doc'): inspect.getdoc(cls), _('Class'): inspect.getsource(cls), _('Constructor'): inspect.getsource(cls.__init__), _('Internal Transition'): inspect.getsource(cls.intTransition), _('External Transition'): inspect.getsource(cls.extTransition), _('Output Function'): inspect.getsource(cls.outputFnc), _('Time Advance Function'): inspect.getsource(cls.timeAdvance), _('Finish Function'): inspect.getsource(cls.finish) if hasattr(cls, 'finish') else "\tpass" } else: pageTexts = { _("Importing Error"): _("Error trying to import the module: %s.\nChange the python path by clicking in the above 'python_path' cell.\n %s" % (model.python_path, str(cls))) } # Now make a bunch of panels for the choice book for nameFunc in pageTexts: win = wx.Panel(self) box = wx.BoxSizer(wx.HORIZONTAL) st = wx.TextCtrl(win, wx.NewId(), '', style=wx.TE_MULTILINE) try: txt = unicode(pageTexts[nameFunc], errors='replace').encode('utf-8') except TypeError: txt = pageTexts[nameFunc] st.AppendText(txt) st.ShowPosition(wx.TOP) st.SetEditable(False) box.Add(st, 1, wx.EXPAND) win.SetSizer(box) self.AddPage(win, nameFunc)
def getPythonModelFileName(fn): """ Get filename of zipped python file """ #global Cmtp assert (zipfile.is_zipfile(fn)) zf = zipfile.ZipFile(fn, 'r') ### TODO: finally impose : py_file_list = filter(lambda f: f.endswith('.py')) ### find if python file has same name of model file py_file_list = filter( lambda f: f.endswith('.py') and os.path.dirname(f) == '' and f not in ('plugins.py', 'steps.py', 'environment.py', 'strategies.py'), zf.namelist()) zf.close() #Cmtp+=1 #print Cmtp, fn ### if there is more than one python file in the zip file ### we find the correct behavioral file if len(py_file_list) > 1: model_name = os.path.splitext(os.path.basename(fn))[0] for python_file in py_file_list: ### if the name of python fiel in zip and the name of the model are similar. if os.path.splitext(python_file)[0] == model_name: return python_file ### esle test if the python file containing the class inherit of the DomainBehavior or DomainStructure else: import Components cls = Components.GetClass(os.path.join(fn, python_file)) from DomainInterface.DomainBehavior import DomainBehavior from DomainInterface.DomainStructure import DomainStructure if inspect.isclass(cls): if issubclass(cls, DomainBehavior) or issubclass( cls, DomainStructure): return python_file sys.stdout.write(_('Behavioral python file not found in %s file' % fn)) raise Exception else: ### zip file must contain python file return py_file_list[0]
def OnUpdate(self, evt): """ Update list has been invocked """ ### deep copy of data list D = copy.deepcopy(self.list.itemDataMap) ### update in error line self.list.itemDataMap for k, v in D.items(): line_number = v[2] if line_number != "": python_path = v[-1] devs = getInstance(Components.GetClass(python_path)) ### check error and change image if not isinstance(devs, tuple): self.list.itemDataMap[k] = (v[0], "", "", v[3], v[4]) ### refresh items self.list.RefreshItems(-1, -1)
def python_path_call_back(evt): fn = evt.GetEventObject().GetValue() cls = Components.GetClass(fn) if inspect.isclass(cls): ### import are here because the simulator (PyDEVS or PyPDEVS) require it from DomainInterface.DomainBehavior import DomainBehavior from DomainInterface.DomainStructure import DomainStructure if not (issubclass(cls, DomainBehavior) or issubclass(cls, DomainStructure)): dlg = wx.MessageDialog( parent, _('The python file must contain a class that inherit of DomainBehavior or DomainStructure master class.\n Please choose a correct python file.' ), _('Wizard Manager'), wx.ID_OK | wx.ICON_ERROR) dlg.ShowModal() else: dlg = wx.MessageDialog( parent, _('The python file not includes a class definition.\n Please choose a correct python file.' ), _('Wizard Manager'), wx.ID_OK | wx.ICON_ERROR) dlg.ShowModal()
def Save(self, obj_dumped, fileName=None): """ Function that save the codeblock on the disk. """ assert (fileName.endswith(tuple(DumpZipFile.ext))) ### local copy of paths python_path = obj_dumped.python_path image_path = obj_dumped.image_path ### Now, file paths are in the compressed file if os.path.isabs(python_path): obj_dumped.python_path = os.path.join( fileName, os.path.basename(obj_dumped.python_path)) if os.path.isabs(image_path): obj_dumped.image_path = os.path.join( fileName, os.path.basename(obj_dumped.image_path)) obj_dumped.model_path = fileName ### args is constructor args and we save these and not the current value if hasattr(obj_dumped, 'args'): obj_dumped.args = Components.GetArgs( Components.GetClass(obj_dumped.python_path)) try: fn = 'DEVSimPyModel.dat' ### dump attributes in fn file cPickle.dump(obj=PickledCollection(obj_dumped), file=open(fn, "wb"), protocol=0) except Exception, info: sys.stderr.write( _("Problem saving (during the dump): %s -- %s\n") % (str(fileName), info)) return False
def Populate(self, model): """ Populate the data and dataTypes lists """ self.model = model self.data = [] self.dataTypes = [] self.nb_behavior_var = 0 self.nb_graphic_var = 0 n = len(model.GetAttributes()) ### graphical attributes number m = len( self.infoBlockLabelList) ### docstring graphical attributes number ### if user define new graphical attributes we add their description in infoBlockLabelList if m != n: self.infoBlockLabelList.extend(model.GetAttributes()[m:]) ### default behavioral attributes dictionary if model.args: infoBlockBehavioralDict = dict( map(lambda attr: (attr, _('Unknown information')), model.args.keys())) else: infoBlockBehavioralDict = {} ### if user code the information of behavioral attribute in docstring of class with @ or - symbol, we update the infoBlockBehavioralDict if hasattr(model, 'python_path') and infoBlockBehavioralDict != {}: ### cls object from python file cls = Components.GetClass(model.python_path) ### Behavioral sorted values fields args_in_constructor = Components.GetArgs(cls) ### if cls is class if inspect.isclass(cls): regex = re.compile( '[@|-][param]*[\s]*([a-zA-Z0-9-_\s]*)[=|:]([a-zA-Z0-9-_\s]+)' ) doc = cls.__init__.__doc__ or "" for attr, val in regex.findall(doc): ### attr could be in model.args if string.strip(attr) in model.args: infoBlockBehavioralDict.update( {string.strip(attr): string.strip(val)}) else: args_in_constructor = None ### Port class has specific attribute if isinstance(model, Container.Port): self.infoBlockLabelList.insert(4, _('Id number')) ### Graphical values fields for i in xrange(n): attr = str(model.GetAttributes()[i]) val = getattr(model, attr) if attr == "image_path": val = os.path.basename(val) self.data.append([attr, val, self.infoBlockLabelList[i]]) self.dataTypes.append(self.GetTypeList(val)) for attr_name, info in sorted(infoBlockBehavioralDict.items()): val = model.args[attr_name] ### if the type of value has changed for an instance (edition of the code block), we reinitilize the value if args_in_constructor and attr_name in args_in_constructor.keys(): val_in_constructor = args_in_constructor[attr_name] t1 = type(val) t2 = type(val_in_constructor) if t1 != t2 and (t1 not in (str, unicode) and t2 not in (str, unicode)): val = val_in_constructor ### if val is tab and the len has been changed ### when dict, the value on PropertiesGridCtrl is tuple like ('key', 'value') elif isinstance(val, ( tuple, dict, )) and len(val_in_constructor) != 0: if len(val_in_constructor) != len(val): val = val_in_constructor else: pass else: pass self.data.append([attr_name, val, info]) self.dataTypes.append(self.GetTypeList(val)) self.nb_behavior_var += 1 if args_in_constructor: for attr_name, val in args_in_constructor.items(): if attr_name not in infoBlockBehavioralDict.keys(): model.args[attr_name] = val self.data.append( [attr_name, val, _('Unknown information')]) self.dataTypes.append(self.GetTypeList(val)) self.nb_behavior_var += 1 else: sys.stdout.write(_("Args in constructor is none\n")) ### Python File Path if hasattr(model, 'python_path'): val = os.path.basename(self.model.python_path) self.data.append(['python_path', val, _("Python file path")]) self.dataTypes.append(self.GetTypeList(val)) self.nb_behavior_var += 1
def __init__(self, parent, id, model=None): wx.Choicebook.__init__(self, parent, id) self.parent = parent cls = Components.GetClass(model.python_path) if inspect.isclass(cls): info = _("Unable to load sources") try: a = inspect.getdoc(cls) except: a = info try: b = inspect.getsource(cls) except: b = info try: c = inspect.getsource(cls.__init__) except: c = info try: d = inspect.getsource(cls.intTransition) except: d = info try: e = inspect.getsource(cls.extTransition) except: e = info try: f = inspect.getsource(cls.outputFnc) except: f = info try: g = inspect.getsource(cls.timeAdvance) except: g = info try: h = inspect.getsource(cls.finish) if hasattr( cls, 'finish') else "\tpass" except: h = info pageTexts = { _('Doc'): a, _('Class'): b, _('Constructor'): c, _('Internal Transition'): d, _('External Transition'): e, _('Output Function'): f, _('Time Advance Function'): g, _('Finish Function'): h } else: pageTexts = { _("Importing Error"): _("Error trying to import the module: %s.\nChange the python path by clicking in the above 'python_path' cell.\n %s" % (model.python_path, str(cls))) } # Now make a bunch of panels for the choice book for nameFunc in pageTexts: win = wx.Panel(self) box = wx.BoxSizer(wx.HORIZONTAL) st = wx.TextCtrl(win, wx.NewId(), '', style=wx.TE_MULTILINE) try: txt = unicode(pageTexts[nameFunc], errors='replace').encode('utf-8') except TypeError: txt = pageTexts[nameFunc] finally: if txt: st.AppendText(txt) st.ShowPosition(wx.TOP) st.SetEditable(False) box.Add(st, 1, wx.EXPAND) win.SetSizer(box) else: sys.stdout.write( _("Method %s of class %s unknown!\n" % (nameFunc, cls.__name__))) self.AddPage(win, nameFunc)
def SelectProp(self, evt): """ """ row, col = evt.GetRow(), evt.GetCol() table = self.GetTable() typ = table.dataTypes[row][1] prop = self.GetCellValue(row, 0) if prop == 'fill' or re.findall( "[.]*color[.]*", prop, flags=re.IGNORECASE): val = self.GetCellValue(row, 1) dlg = wx.ColourDialog(self.parent) dlg.GetColourData().SetChooseFull(True) if dlg.ShowModal() == wx.ID_OK: data = dlg.GetColourData() val = str([RGBToHEX(data.GetColour().Get())]) self.SetCellValue(row, 1, val) else: dlg.Destroy() return False dlg.Destroy() self.AcceptProp(row, col) elif prop == 'font': val = eval(self.GetCellValue(row, 1)) default_font = wx.Font(val[0], val[1], val[2], val[3], False, val[4]) data = wx.FontData() if sys.platform == 'win32': data.EnableEffects(True) data.SetAllowSymbols(False) data.SetInitialFont(default_font) data.SetRange(10, 30) dlg = wx.FontDialog(self.parent, data) if dlg.ShowModal() == wx.ID_OK: data = dlg.GetFontData() font = data.GetChosenFont() color = data.GetColour() val = [ font.GetPointSize(), font.GetFamily(), font.GetStyle(), font.GetWeight(), font.GetFaceName() ] self.SetCellValue(row, 1, str(val)) else: dlg.Destroy() return False dlg.Destroy() self.AcceptProp(row, col) elif prop == 'label': d = LabelGUI.LabelDialog(self.parent, self.parent.model) d.ShowModal() self.SetCellValue(row, 1, str(self.parent.model.label)) self.AcceptProp(row, col) elif prop == 'image_path': dlg = ib.ImageDialog(self, os.path.join(HOME_PATH)) dlg.Centre() if dlg.ShowModal() == wx.ID_OK: val = os.path.normpath(dlg.GetFile()) if val != self.GetCellValue(row, 1): self.SetCellValue(row, 1, val) self.canvas.UpdateShapes([self.parent.model]) else: dlg.Destroy() return False dlg.Destroy() self.AcceptProp(row, col) elif 'filename' in str(prop).lower(): wcd = _('Data files All files (*)|*') val = self.GetCellValue(row, 1) default_dir = os.path.dirname(val) if os.path.exists( os.path.dirname(val)) else HOME_PATH dlg = wx.FileDialog(self, message=_("Select file ..."), defaultDir=default_dir, defaultFile="", wildcard=wcd, style=wx.OPEN | wx.CHANGE_DIR) if dlg.ShowModal() == wx.ID_OK: val = os.path.normpath(dlg.GetPath()) if val != self.GetCellValue(row, 1): self.SetCellValue(row, 1, val) self.canvas.UpdateShapes([self.parent.model]) else: dlg.Destroy() return False dlg.Destroy() self.AcceptProp(row, col) elif prop == 'python_path': model = self.parent.model ### for .amd or .cmd if model.model_path != '': wcd = _( 'Atomic DEVSimPy model (*.amd)|*.amd|Coupled DEVSimPy model (*.cmd)|*.cmd|All files (*)|*' ) else: wcd = _('Python files (*.py)|*.py|All files (*)|*') default_dir = os.path.dirname(model.python_path) if os.path.exists( os.path.dirname(model.python_path)) else DOMAIN_PATH dlg = wx.FileDialog(self, message=_("Select file ..."), defaultDir=default_dir, defaultFile="", wildcard=wcd, style=wx.OPEN | wx.CHANGE_DIR) if dlg.ShowModal() == wx.ID_OK: new_python_path = os.path.normpath(dlg.GetPath()) ### if the user would like to load a compressed python file, he just give the name of compressed file that contain the python file if zipfile.is_zipfile(new_python_path): zf = zipfile.ZipFile(new_python_path, 'r') new_python_path = os.path.join( new_python_path, filter( lambda f: f.endswith('.py') and f != 'plugins.py', zf.namelist())[0]) ### update model path model.model_path = os.path.dirname(new_python_path) self.SetCellValue(row, 1, new_python_path) # behavioral args update (because depends of the new class coming from new python file) new_cls = Components.GetClass(new_python_path) if inspect.isclass(new_cls): ### update attributes (behavioral ang graphic) model.args = Components.GetArgs(new_cls) model.SetAttributes(Attributable.GRAPHICAL_ATTR) ### TODO: when ScopeGUI and DiskGUI will be amd models, delete this line) ### delete xlabel and ylabel attributes if exist model.RemoveAttribute('xlabel') model.RemoveAttribute('ylabel') ### Update of DEVSimPy model from new python behavioral file (ContainerBlock is not considered because he did not behavioral) if new_cls.__name__ in ('To_Disk', 'MessagesCollector'): model.__class__ = Container.DiskGUI elif new_cls.__name__ == 'QuickScope': model.__class__ = Container.ScopeGUI model.AddAttribute("xlabel") model.AddAttribute("ylabel") elif True in map(lambda a: 'DomainStructure' in str(a), new_cls.__bases__): model.__class__ = Container.ContainerBlock else: model.__class__ = Container.CodeBlock ### if we change the python file from zipfile we compresse the new python file and we update the python_path value if zipfile.is_zipfile(model.model_path): zf = ZipManager.Zip(model.model_path) zf.Update([new_python_path]) #model.model_path = ### update flag and color if bad filename if model.bad_filename_path_flag: model.bad_filename_path_flag = False else: Container.MsgBoxError(evt, self, new_cls) dlg.Destroy() return False else: dlg.Destroy() return False dlg.Destroy() self.AcceptProp(row, col) elif typ == "list": frame = ListEditor(self, wx.ID_ANY, _('List editor'), values=self.GetCellValue(row, 1)) if frame.ShowModal() == wx.ID_CANCEL: self.SetCellValue(row, 1, frame.GetValueAsString()) else: frame.Destroy() self.AcceptProp(row, col) elif typ == 'dict': frame = DictionaryEditor(self, wx.ID_ANY, _('List editor'), values=self.GetCellValue(row, 1)) if frame.ShowModal() == wx.ID_CANCEL: self.SetCellValue(row, 1, frame.GetValueAsString()) else: frame.Destroy() self.AcceptProp(row, col) elif 'choice' in typ: self.AcceptProp(row, col) else: pass ### all properties grid update (because the python classe has been changed) ### here, because OnAcceptProp should be executed before if prop == 'python_path': ### Update table from new model table.UpdateRowBehavioralData(model) self.SetTable(table, False) self.ForceRefresh() self.AutoSizeColumns() # code updating if isinstance(model, Achievable): new_code = CodeCB(self.parent, wx.ID_ANY, model) #self.parent.boxH.Remove(0) if hasattr(self.parent, '_boxH'): # DeleteWindows work better in vista if wx.VERSION_STRING < '4.0': self.parent._boxH.DeleteWindows() self.parent._boxH.AddWindow(new_code, 1, wx.EXPAND, userData='code') else: self.parent._boxH.Clear() self.parent._boxH.Add(new_code, 1, wx.EXPAND, userData='code') self.parent._boxH.Layout() else: sys.stdout.write("_boxH is unknown!")
def Save(self, obj_dumped, fileName = None): """ Function that save the codeblock on the disk. """ assert(fileName.endswith(tuple(DumpZipFile.ext))) ### local copy of paths python_path = obj_dumped.python_path image_path = obj_dumped.image_path ### Now, file paths are in the compressed file if os.path.isabs(python_path): path = os.path.join(fileName, os.path.basename(obj_dumped.python_path)) if os.path.exists(path): obj_dumped.python_path = path if os.path.isabs(image_path): obj_dumped.image_path = os.path.join(fileName, os.path.basename(obj_dumped.image_path)) obj_dumped.model_path = fileName ### args is constructor args and we save these and not the current value if hasattr(obj_dumped, 'args'): obj_dumped.args = Components.GetArgs(Components.GetClass(obj_dumped.python_path)) try: fn = 'DEVSimPyModel.dat' ### dump attributes in fn file pickle.dump( obj = PickledCollection(obj_dumped), file = open(fn, "wb"), protocol = 0) except Exception as info: sys.stderr.write(_("Problem saving (during the dump): %s -- %s\n")%(str(fileName),info)) return False else: try: zf = ZipManager.Zip(fileName) ### create or update fileName if os.path.exists(fileName): zf.Update(replace_files = [fn, python_path, image_path]) else: zf.Create(add_files = [fn, python_path, image_path]) os.remove(fn) ## abs path of the directory that contains the file to export (str() to avoid unicode) newExportPath = str(os.path.dirname(fileName)) mainW = getTopLevelWindow() ### if export on local directory, we insert the path in the config file if not os.path.basename(DOMAIN_PATH) in newExportPath.split(os.sep): ### update of .devsimpy config file mainW.exportPathsList = eval(mainW.cfg.Read("exportPathsList")) if newExportPath not in mainW.exportPathsList: mainW.exportPathsList.append(str(newExportPath)) mainW.cfg.Write("exportPathsList", str(eval("mainW.exportPathsList"))) ### if lib is already in the lib tree, we update the tree mainW.tree.UpdateDomain(newExportPath) ### to sort lib tree mainW.tree.SortChildren(mainW.tree.root) except Exception as info: sys.stderr.write(_("Problem saving (during the zip handling): %s -- %s\n")%(str(fileName),info)) return False else: return True
def Populate(self, model): """ Populate the data and dataTypes lists """ self.model = model self.data = [] self.dataTypes = [] self.nb_behavior_var = 0 self.nb_graphic_var = 0 n = len(model.GetAttributes()) ### graphical attributes number m = len( self.infoBlockLabelList) ### docstring graphical attributes number ### if user define new graphical attributes we add their description in infoBlockLabelList if m != n: self.infoBlockLabelList.extend(model.GetAttributes()[m:]) ### default behavioral attributes dictionary infoBlockBehavioralDict = dict( map(lambda attr: (attr, _('Unknown information')), model.args.keys())) ### if user code the information of behavioral attribute in docstring of class with @ or - symbol, we update the infoBlockBehavioralDict if hasattr(model, 'python_path') and infoBlockBehavioralDict != {}: ### cls object from python file cls = Components.GetClass(model.python_path) ### if cls is class if inspect.isclass(cls): regex = re.compile( '[@|-][param]*[\s]*([a-zA-Z0-9-_\s]*)[=|:]([a-zA-Z0-9-_\s]+)' ) doc = cls.__init__.__doc__ or "" for attr, val in regex.findall(doc): ### attr could be in model.args if string.strip(attr) in model.args: infoBlockBehavioralDict.update( {string.strip(attr): string.strip(val)}) ### Port class has specific attribute if isinstance(model, Container.Port): self.infoBlockLabelList.insert(4, _('Id number')) ### Graphical values fields for i in xrange(n): attr = str(model.GetAttributes()[i]) val = getattr(model, attr) if attr == "image_path": val = os.path.basename(val) self.data.append([attr, val, self.infoBlockLabelList[i]]) self.dataTypes.append(self.GetTypeList(val)) ### Behavioral sorted values fields for attr_name, info in sorted(infoBlockBehavioralDict.items()): val = model.args[attr_name] #print model.args #print val, self.GetTypeList(val) self.data.append([attr_name, val, info]) self.dataTypes.append(self.GetTypeList(val)) self.nb_behavior_var += 1 ### Python File Path if hasattr(model, 'python_path'): val = os.path.basename(self.model.python_path) self.data.append(['python_path', val, _("Python file path")]) self.dataTypes.append(self.GetTypeList(val)) self.nb_behavior_var += 1