diff --git a/Components.py b/Components.py index 72f16f96..343c60da 100644 --- a/Components.py +++ b/Components.py @@ -48,8 +48,7 @@ import ZipManager -from ReloadModule import recompile -from Utilities import GetActiveWindow, path_to_module, printOnStatusBar +from Utilities import GetActiveWindow, path_to_module, install_and_import, printOnStatusBar from NetManager import Net from SimpleFrameEditor import FrameEditor from which import which @@ -188,9 +187,9 @@ def __init__(self, *argv, **kwargs): """ # local copy self._canvas = kwargs['canvas'] if 'id' in kwargs else None - self._x = kwargs['x'] if 'x' in kwargs else None - self._y = kwargs['y'] if 'y' in kwargs else None - self._label = kwargs['label'] if 'label' in kwargs else None + self._x = kwargs.get('x',None) + self._y = kwargs.get('y',None) + self._label = kwargs.get('label',None) if 'id' in kwargs: self._iid = kwargs['id'] @@ -209,12 +208,11 @@ def __init__(self, *argv, **kwargs): #self._iid = kwargs['id'] if 'id' in kwargs else self._canvas.diagram.GetiPortCount() #self._oid = kwargs['id'] if 'id' in kwargs else self._canvas.diagram.GetoPortCount() - self._inputs = kwargs['inputs'] if 'inputs' in kwargs else 1 - self._outputs = kwargs['outputs'] if 'outputs' in kwargs else 1 + self._inputs = kwargs.get('inputs',1) + self._outputs = kwargs.get('outputs',1) self._python_file = kwargs['python_file'] - self._model_file = kwargs['model_file'] if 'model_file' in kwargs else '' - - self._specific_behavior = kwargs['specific_behavior'] if 'specific_behavior' in kwargs else '' + self._model_file = kwargs.get('model_file','') + self._specific_behavior = kwargs.get('specific_behavior','') def Create(self): """ Create component from attributes diff --git a/Container.py b/Container.py index 4d4a3b7e..a78780f2 100644 --- a/Container.py +++ b/Container.py @@ -363,12 +363,14 @@ def makeDEVSInstance(diagram = None): 4. we make the connection """ + #import ReloadModule #ReloadModule.recompile("DomainInterface.DomainBehavior") #ReloadModule.recompile("DomainInterface.DomainStructure") #ReloadModule.recompile("DomainInterface.MasterModel") + #import DomainInterface.MasterModel ### PyPDEVS work with this -# diagram.setDEVSModel(DomainInterface.MasterModel.Master()) + #diagram.setDEVSModel(DomainInterface.MasterModel.Master()) ### TODO to be tested with PyPDEVS !!! # if isinstance(diagram.parent, ShapeCanvas): @@ -904,7 +906,7 @@ def DeleteShape(self, shape): coupled_devs = self.getDEVSModel() devs = shape.getDEVSModel() if coupled_devs and devs in coupled_devs.getComponentSet(): - coupled_devs.delTocomponentSet([devs]) + coupled_devs.delToComponentSet([devs]) try: ### delete shape @@ -3869,7 +3871,7 @@ def __init__(self, label = 'ContainerBlock', nb_inputs = 1, nb_outputs = 1): Block.__init__(self, label, nb_inputs, nb_outputs) Diagram.__init__(self) #Structurable.__init__(self) - self.fill = Container.FILL + self.fill = ContainerBlock.FILL ### def __setstate__(self, state): diff --git a/Domain/Collector/To_Disk.py b/Domain/Collector/To_Disk.py index b29c87d5..3f3aa1a6 100644 --- a/Domain/Collector/To_Disk.py +++ b/Domain/Collector/To_Disk.py @@ -18,6 +18,19 @@ from decimal import * import os +def append_new_line(file_name, text_to_append): + """Append given text as a new line at the end of file""" + # Open the file in append & read mode ('a+') + with open(file_name, "a+") as file_object: + # Move read cursor to the start of file. + file_object.seek(0) + # If file is not empty then append '\n' + data = file_object.read(100) + if len(data) > 0: + file_object.write("\n") + # Append text at the end of file + file_object.write(text_to_append) + # ================================================================ # class To_Disk(QuickScope): """ Atomic Model writing on the disk. @@ -40,7 +53,7 @@ def __init__(self, fileName = os.path.join(os.getcwd(),"result%d"%random.randint self.comma = comma self.ext = ext self.col = col - + #decimal precision getcontext().prec = 6 @@ -114,9 +127,11 @@ def extTransition(self, *args): else: v = val + if t != self.last_time_value[fn]: - with open(fn, 'a') as f: - f.write("%s%s%s\n"%(self.last_time_value[fn],self.comma,self.buffer[fn])) + append_new_line(fn,"%s%s%s"%(self.last_time_value[fn],self.comma,self.buffer[fn])) + #with open(fn, 'a') as f: + # f.write("%s%s%s\n"%(self.last_time_value[fn],self.comma,self.buffer[fn])) self.last_time_value[fn] = t self.buffer[fn] = v @@ -146,7 +161,9 @@ def finish(self, msg): for np in range(n): fn = "%s%d%s"%(self.fileName, np, self.ext) if (fn in self.last_time_value) and (fn in self.buffer): - with open(fn, 'a') as f: - f.write("%s%s%s\n"%(self.last_time_value[fn],self.comma,self.buffer[fn])) + append_new_line(fn,"%s%s%s"%(self.last_time_value[fn],self.comma,self.buffer[fn])) +# with open(fn, 'a') as f: +# f.write("%s%s%s\n"%(self.last_time_value[fn],self.comma,self.buffer[fn])) + ### def __str__(self):return "To_Disk" diff --git a/DomainInterface/DomainStructure.py b/DomainInterface/DomainStructure.py index 492d584c..a7a44420 100644 --- a/DomainInterface/DomainStructure.py +++ b/DomainInterface/DomainStructure.py @@ -89,7 +89,7 @@ def addToComponentSet(self,V:list)->None: elif hasattr(self, 'component_set'): self.component_set.extend(V) - def delToCompnentsSet(self,V:list)->None: + def delToComponentSet(self,V:list)->None: """ del values in the components set attribute """ if hasattr(self, 'componentSet'): diff --git a/Editor.py b/Editor.py index 77b859d4..069cd6c8 100644 --- a/Editor.py +++ b/Editor.py @@ -983,7 +983,11 @@ def DoSaveFile(self, code): zf.Update(replace_files=[fic_filename]) ### Clean up the temporary file yourself - os.remove(fic_filename) + try: + os.remove(fic_filename) + except Exception as info: + sys.exc_info() + sys.stderr.write(_('File has not been deleted: %s'%info)) ### reload module only if zipped python file is not plugins ### update only for python file of model which have path like .../name.amd(.cmd)/name.ext @@ -2055,6 +2059,7 @@ def UpdateModule(self): module_name = path_to_module(self.cb.python_path) info = ReloadModule.recompile(module_name) + cp = self.nb.GetCurrentPage() cp.error_flag = isinstance(info, Exception) or isinstance(info, str) diff --git a/LibraryTree.py b/LibraryTree.py index 532aa20a..389fc8c9 100644 --- a/LibraryTree.py +++ b/LibraryTree.py @@ -450,7 +450,6 @@ def GetPYFileList(dName, ext=".py"): else: sys.stderr.write(_("%s not imported: Class is not DomainBehavior\n"%(s))) - ### If cls is tuple, there is an error but we load the model to correct it. ### If its not DEVS model, the Dnd don't allows the instantiation and when the error is corrected, it don't appear before a update. else: @@ -1139,7 +1138,7 @@ def OnItemDocumentation(self, evt): doc = inspect.getdoc(module) ### Add maccabe complexity measure - doc += "".join([_("\n\n MacCabe Complexity: %d")%elf.MetricDico[item]['mcc']]) + doc += "".join([_("\n\n MacCabe Complexity: %d")%self.MetricDico[item]['mcc']]) if doc: dlg = wx.lib.dialogs.ScrolledMessageDialog(self, doc, _("%s Documentation")%name, style=wx.OK|wx.ICON_EXCLAMATION|wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER) diff --git a/Mixins/Savable.py b/Mixins/Savable.py index 656e9f7f..d4af398c 100644 --- a/Mixins/Savable.py +++ b/Mixins/Savable.py @@ -179,8 +179,8 @@ def Save(self, obj_dumped, fileName = None): protocol = 0) except Exception as info: - - sys.stderr.write(_("Problem saving (during the dump): %s -- %s\n")%(str(fileName),info)) + tb = traceback.format_exc() + sys.stderr.write(_("Problem saving (during the dump): %s -- %s\n")%(str(fileName),str(tb))) return False else: @@ -214,8 +214,10 @@ def Save(self, obj_dumped, fileName = None): mainW.tree.SortChildren(mainW.tree.root) except Exception as info: - NotificationMessage(_('Error'), _("Problem saving (during the zip handling): %s -- %s\n")%(str(fileName),info), parent=self, timeout=5) - sys.stderr.write(_("Problem saving (during the zip handling): %s -- %s\n")%(str(fileName),info)) + tb = traceback.format_exc() + NotificationMessage(_('Error'), _("Problem saving (during the zip handling): %s -- %s\n")%(str(fileName),info), parent=getTopLevelWindow(), timeout=5) + sys.stderr.write(_("Problem saving (during the zip handling): %s -- %s\n")%(str(fileName),str(tb))) + return False else: @@ -232,10 +234,12 @@ def Load(self, obj_loaded, fileName = None): data_file = 'DEVSimPyModel.dat' path = zf.extract(data_file, gettempdir()) except KeyError as info: - sys.stderr.write(_("ERROR: Did not %s find in zip file %s --\n%s \n")%(data_file, str(fileName), info)) + tb = traceback.format_exc() + sys.stderr.write(_("ERROR: Did not %s find in zip file %s --\n%s \n")%(data_file, str(fileName), str(tb))) return info except Exception as info: - sys.stderr.write(_("Problem extracting: %s -- %s \n")%(str(fileName),info)) + tb = traceback.format_exc() + sys.stderr.write(_("Problem extracting: %s -- %s \n")%(str(fileName),str(tb))) return info finally: zf.close() @@ -252,7 +256,8 @@ def Load(self, obj_loaded, fileName = None): L = pickle.load(f) f.close() except Exception as info: - sys.stderr.write(_("Problem loading: %s -- %s \n")%(str(fileName), info)) + tb = traceback.format_exc() + sys.stderr.write(_("Problem loading: %s -- %s \n")%(str(fileName), str(tb))) return info ### Check comparison between serialized attribut (L) and normal attribut (dump_attributes) @@ -301,7 +306,8 @@ def Load(self, obj_loaded, fileName = None): except IndexError as info: - sys.stderr.write(_("Problem loading (old model): %s -- %s \n")%(str(fileName), info)) + tb = traceback.format_exc() + sys.stderr.write(_("Problem loading (old model): %s -- %s \n")%(str(fileName), str(tb))) return info @@ -332,7 +338,8 @@ def LoadPlugins(self, obj, fileName): try: module = importer.load_module('plugins') except ImportError as info: - sys.stdout.write("%s\n"%info) + tb = traceback.format_exc() + sys.stdout.write("%s\n"%str(tb)) return info for m in [e for e in [module.__dict__.get(a) for a in dir(module)] if not inspect.ismodule(e) and inspect.getmodule(e) is module]: @@ -349,7 +356,8 @@ def LoadPlugins(self, obj, fileName): pass except Exception as info: - sys.stdout.write(_('plugins %s not loaded : %s\n'%(name,info))) + tb = traceback.format_exc() + sys.stdout.write(_('plugins %s not loaded : %s\n'%(name,str(tb)))) return info ### restor method which was assigned to None before being pickled @@ -382,7 +390,8 @@ def Save(self, obj_dumped, fileName = None): protocol = 0) except Exception as info: - sys.stderr.write(_("\nProblem saving: %s -- %s\n")%(str(fileName),info)) + tb = traceback.format_exc() + sys.stderr.write(_("\nProblem saving: %s -- %s\n")%(str(fileName),str(tb))) return False else: return True @@ -400,7 +409,6 @@ def Load(self, obj_loaded, fileName = None): except Exception as info: exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] - sys.stderr.write(_("Problem opening: %s -- description: %s / type: %s / name: %s / line: %s\n")%(str(fileName), info, exc_type, fname, exc_tb.tb_lineno)) return info @@ -409,7 +417,8 @@ def Load(self, obj_loaded, fileName = None): try: dsp = pickle.load(f) except Exception as info: - sys.stderr.write(_("Problem loading: %s -- %s\n")%(str(fileName), info)) + tb = traceback.format_exc() + sys.stderr.write(_("Problem loading: %s -- %s\n")%(str(fileName), str(tb))) return info finally: f.close() @@ -450,7 +459,8 @@ def Save(self, obj_dumped, fileName = None): with open(fileName, 'w') as yf: ruamel.yaml.dump(PickledCollection(obj_dumped), stream=yf, default_flow_style=False) except Exception as info: - sys.stderr.write(_("\nProblem saving: %s -- %s\n")%(str(fileName),info)) + tb = traceback.format_exc() + sys.stderr.write(_("\nProblem saving: %s -- %s\n")%(str(fileName),str(tb))) return False else: return True @@ -469,7 +479,6 @@ def Load(self, obj_loaded, fileName = None): except Exception as info: exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] - sys.stderr.write(_("Problem opening: %s -- description: %s / type: %s / name: %s / line: %s\n")%(str(fileName), info, exc_type, fname, exc_tb.tb_lineno)) sys.stderr.write(traceback.format_exc()) return info @@ -519,17 +528,11 @@ def Save(self, obj_dumped, fileName = None): diagram = obj_dumped D = diagram.__class__.makeDEVSGraph(diagram, {}) - - if isinstance(diagram, Components.GenericComponent): - label = diagram.label - else: - label = os.path.splitext(os.path.basename(fileName))[0] - + label = diagram.label if isinstance(diagram, Components.GenericComponent) else os.path.splitext(os.path.basename(fileName))[0] makeDEVSXML(label, D, fileName) return True - ###----------------------------------------------------------- class Savable(object): """ Savable class that allows methods to save and load diagram into file. diff --git a/PropertiesGridCtrl.py b/PropertiesGridCtrl.py index cf0a790f..d4f95671 100644 --- a/PropertiesGridCtrl.py +++ b/PropertiesGridCtrl.py @@ -742,7 +742,7 @@ def OnMouseMotion(evt): ### display the data path on tooltip if self.GetCellValue(row, 1).endswith(('csv','dat','txt')): if col == 1: - hinttext = self.parent.model.args['fileName'] + hinttext = self.parent.model.args.get('fileName',None) or self.parent.model.args.get('filename',None) or self.parent.model.args.get('FileName',None) elif hinttext is None: hinttext = '' diff --git a/ReloadModule.py b/ReloadModule.py index fae985fe..58f66828 100644 --- a/ReloadModule.py +++ b/ReloadModule.py @@ -69,9 +69,10 @@ def recompile(modulename): except Exception as info: sys.stdout.write(_('Error trying to reload dependencies in recompile module: %s\n')%info) finally: - return importlib.reload(sys.modules[modulename]) + ### failed when modifycations are done in py file + #return importlib.reload(sys.modules[modulename]) - #return importlib.reload(tmp) + return importlib.reload(tmp) def recompile2(modulename): """ recompile module from modulename diff --git a/ZipManager.py b/ZipManager.py index ac5a7882..c034c732 100644 --- a/ZipManager.py +++ b/ZipManager.py @@ -45,7 +45,7 @@ def getPythonModelFileName(fn:str)->str: #global Cmtp - assert(zipfile.is_zipfile(fn)) + #assert(zipfile.is_zipfile(fn)) zf = zipfile.ZipFile(fn,'r') @@ -89,15 +89,6 @@ def __init__(self, fn:str, files:[str]=[]): ### local copy self.fn = fn - ### get module name - try: - self.module_name = getPythonModelFileName(fn) - except Exception as info: - sys.stderr.write(_("Error in ZipManager class for GetModule: no python file in the archive\n")) - - ### - self.fullname = "".join([os.path.basename(os.path.dirname(self.fn)), self.module_name.split('.py')[0]]) - if files != []: self.Create(files) @@ -310,8 +301,9 @@ def GetModule(self, rcp: bool=False)->types.ModuleType: #if rcp: recompile(module_name) PluginManager.trigger_event("IMPORT_STRATEGIES", fn=self.fn) - - return self.ImportModule() if self.fullname not in sys.modules else sys.modules[self.fullname] + fullname = "".join([os.path.basename(os.path.dirname(self.fn)), getPythonModelFileName(self.fn).split('.py')[0]]) + + return self.ImportModule() if fullname not in sys.modules else sys.modules[fullname] def ImportModule(self)->types.ModuleType: """ Import module from zip file corresponding to the amd or cmd model. @@ -323,9 +315,10 @@ def ImportModule(self)->types.ModuleType: sys.path.append(p) importer = zipimport.zipimporter(self.fn) + module_name = getPythonModelFileName(self.fn) - try: - module = importer.load_module(self.module_name.split('.py')[0]) + try: + module = importer.load_module(module_name.split('.py')[0]) ### package is needed by the self.module_name (dependency) except ModuleNotFoundError as info: @@ -333,11 +326,11 @@ def ImportModule(self)->types.ModuleType: package = sys.exc_info()[1].name import wx - dial = wx.MessageDialog(None, _('%s package is needed by %s.\nDo you want to install it?')%(package,self.module_name), _('Required package'), wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION) + dial = wx.MessageDialog(None, _('%s package is needed by %s.\nDo you want to install it?')%(package,module_name), _('Required package'), wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION) if dial.ShowModal() == wx.ID_YES: ### try to install if install_and_import(package): - module = importer.load_module(self.module_name.split('.py')[0]) + module = importer.load_module(module_name.split('.py')[0]) else: module = None else: @@ -346,12 +339,13 @@ def ImportModule(self)->types.ModuleType: dial.Destroy() finally: if module: - module.__name__ = path_to_module(self.module_name) + module.__name__ = path_to_module(module_name) ### allows to import with a reference from the parent directory (like parentName.model). ### Now import of .amd or .cmd module is composed by DomainModel (no point!). - ### Example : import CollectorMessageCollector - sys.modules[self.fullname] = module + ### Example : import CollectorMessageCollector + fullname = "".join([os.path.basename(os.path.dirname(self.fn)), getPythonModelFileName(self.fn).split('.py')[0]]) + sys.modules[fullname] = module return module else: @@ -366,7 +360,8 @@ def ReImport(self): # try: ### reload submodule from module dependencies! - module = sys.modules[self.fullname] + fullname = "".join([os.path.basename(os.path.dirname(self.fn)), getPythonModelFileName(self.fn).split('.py')[0]]) + module = sys.modules[fullname] domain_name = os.path.basename(os.path.dirname(self.fn)) for name in dir(module): if type(getattr(module, name)) == types.ModuleType: