Ignore:
Timestamp:
May 20, 2016 8:37:21 PM (9 years ago)
Author:
Paul Kienzle <pkienzle@…>
Branches:
master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, release_4.0.1, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
5dfbb24
Parents:
cd54205
Message:

make sure compiler/test errors on custom models are reported to the user

Location:
src/sas/sasgui/perspectives/calculator
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/sas/sasgui/perspectives/calculator/model_editor.py

    rcb4ef58 r26d6e045  
    3030from wx.py.editwindow import EditWindow 
    3131from sas.sasgui.guiframe.documentation_window import DocumentationWindow 
     32from .pyconsole import show_model_output, check_model 
    3233 
    3334 
     
    4546PANEL_WIDTH = 500 
    4647_BOX_WIDTH = 55 
    47  
    48  
    49 def _compile_file(path): 
    50     """ 
    51     Compile the file in the path 
    52     """ 
    53     try: 
    54         import py_compile 
    55         py_compile.compile(file=path, doraise=True) 
    56         return '' 
    57     except: 
    58         _, value, _ = sys.exc_info() 
    59         return value 
    6048 
    6149def _delete_file(path): 
     
    384372            name2 = label[1] 
    385373            self.write_string(fname, name1, name2) 
    386             self.compile_file(fname) 
    387             self.parent.update_custom_combo() 
     374            success = show_model_output(self, fname) 
     375            if success: 
     376                self.parent.update_custom_combo() 
    388377            msg = self._notes 
    389378            info = 'Info' 
     
    618607        """ 
    619608        path = self.fname 
    620         _compile_file(path) 
     609        show_model_output(self, path) 
    621610 
    622611    def delete_file(self, path): 
     
    954943        info = 'Info' 
    955944        msg = '' 
     945        result, check_err = '', '' 
    956946        # Sort out the errors if occur 
    957947        # First check for valid python name then if the name already exists 
     
    969959                    self.write_file(self.fname, name, description, param_str, 
    970960                                    pd_param_str, func_str) 
     961                    try: 
     962                        result, msg = check_model(self.fname), None 
     963                    except Exception: 
     964                        import traceback 
     965                        result, msg = None, "error building model" 
     966                        check_err = "\n"+traceback.format_exc(limit=2) 
     967 
    971968                    # Modified compiling test, as it will fail for sasmodels.sasview_model class 
    972969                    # Should add a test to check that the class is correctly built  
     
    10311028            color = 'red' 
    10321029        else: 
    1033             msg = "Successful! " 
     1030            self._notes = result 
     1031            msg = "Successful! Please look for %s in Customized Models."%name 
    10341032            msg += "  " + self._notes 
    1035             msg += " Please look for it in the Customized Models." 
    10361033            info = 'Info' 
    10371034            color = 'blue' 
     
    10411038        if self.base != None: 
    10421039            from sas.sasgui.guiframe.events import StatusEvent 
    1043             wx.PostEvent(self.base.parent, StatusEvent(status=msg, info=info)) 
     1040            wx.PostEvent(self.base.parent, 
     1041                         StatusEvent(status=msg+check_err, info=info)) 
    10441042        self.warning = msg 
    10451043 
  • src/sas/sasgui/perspectives/calculator/pyconsole.py

    rd85c194 r26d6e045  
    44import sys 
    55import os 
     6 
     7import numpy as np 
     8 
    69import wx 
    7 import wx.lib.dialogs 
     10from wx.lib.dialogs import ScrolledMessageDialog 
    811import wx.py.editor as editor 
    9 import wx.py.frame as frame 
    10 import py_compile 
    1112 
    1213if sys.platform.count("win32") > 0: 
     
    1819    PANEL_HEIGHT = 730 
    1920    FONT_VARIANT = 1 
    20 ID_COMPILE = wx.NewId() 
     21ID_CHECK_MODEL = wx.NewId() 
    2122ID_RUN = wx.NewId() 
    2223 
    23 def compile_file(path): 
     24def check_model(path): 
    2425    """ 
    25     Compile a python file 
     26    Check that the model on the path can run. 
    2627    """ 
     28    # try running the model 
     29    from sasmodels.core import load_model, call_kernel 
     30    model = load_model(path) 
     31 
     32    q =  np.array([0.01, 0.1]) 
     33    kernel = model.make_kernel([q]) 
     34    Iq = call_kernel(kernel, {}) 
     35 
     36    qx, qy =  np.array([0.01, 0.01]), np.array([0.1, 0.1]) 
     37    kernel = model.make_kernel([qx, qy]) 
     38    Iqxy = call_kernel(kernel, {}) 
     39 
     40    result = """ 
     41    Iq(%s) = %s 
     42    Iqxy(%s, %s) = %s 
     43    """%(q, Iq, qx, qy, Iqxy) 
     44 
     45    return result 
     46 
     47def show_model_output(parent, fname): 
     48    # Make sure we have a python file; not sure why we care though... 
     49    if not (fname and os.path.exists(fname) and fname.endswith('.py')): 
     50        mssg = "\n This is not a python file." 
     51        wx.MessageBox(str(mssg), 'Error', style=wx.ICON_ERROR) 
     52        return False 
     53 
    2754    try: 
    28         import py_compile 
    29         py_compile.compile(file=path, doraise=True) 
    30     except: 
    31         type, value, traceback = sys.exc_info() 
    32         return value 
    33     return None 
     55        result, errmsg = check_model(fname), None 
     56    except Exception: 
     57        import traceback 
     58        result, errmsg = None, traceback.format_exc(limit=2) 
     59 
     60    parts = ["Running model '%s'..." % os.path.basename(fname)] 
     61    if errmsg is not None: 
     62        parts.extend(["", "Error occurred:", errmsg, ""]) 
     63        title, icon = "Error", wx.ICON_ERROR 
     64    else: 
     65        parts.extend(["", "Success:", result, ""]) 
     66        title, icon = "Info", wx.ICON_INFORMATION 
     67    text = "\n".join(parts) 
     68    dlg = ScrolledMessageDialog(parent, text, title, size=((550, 250))) 
     69    fnt = wx.Font(10, wx.TELETYPE, wx.NORMAL, wx.NORMAL) 
     70    dlg.GetChildren()[0].SetFont(fnt) 
     71    dlg.GetChildren()[0].SetInsertionPoint(0) 
     72    dlg.ShowModal() 
     73    dlg.Destroy() 
     74    return errmsg is None 
    3475 
    3576class PyConsole(editor.EditorNotebookFrame): 
     
    65106        self.Bind(wx.EVT_MENU, self.OnSaveFile, id=wx.ID_SAVE) 
    66107        self.Bind(wx.EVT_MENU, self.OnSaveAsFile, id=wx.ID_SAVEAS) 
    67         self.Bind(wx.EVT_MENU, self.OnCompile, id=ID_COMPILE) 
     108        self.Bind(wx.EVT_MENU, self.OnCheckModel, id=ID_CHECK_MODEL) 
    68109        self.Bind(wx.EVT_MENU, self.OnRun, id=ID_RUN) 
    69         self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateCompileMenu, id=ID_COMPILE) 
     110        self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateCompileMenu, id=ID_CHECK_MODEL) 
    70111        self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateCompileMenu, id=ID_RUN) 
    71112        self.Bind(wx.EVT_CLOSE, self.on_close) 
     
    81122        """ 
    82123        self.compileMenu = wx.Menu() 
    83         self.compileMenu.Append(ID_COMPILE, 'Compile', 
    84                  'Compile the file') 
     124        self.compileMenu.Append(ID_CHECK_MODEL, 'Check model', 
     125                 'Loading and run the model') 
    85126        self.compileMenu.AppendSeparator() 
    86127        self.compileMenu.Append(ID_RUN, 'Run in Shell', 
     
    192233        Run 
    193234        """ 
    194         if self._check_changed(): 
     235        if not self._check_saved(): 
    195236            return True 
    196237        if self.buffer and self.buffer.doc.filepath: 
     
    207248            icon = wx.ICON_ERROR 
    208249            wx.MessageBox(str(mssg), title, style=icon) 
    209             return 0 
    210  
    211     def OnCompile(self, event): 
     250            return False 
     251 
     252    def OnCheckModel(self, event): 
    212253        """ 
    213254        Compile 
    214255        """ 
    215         if self._check_changed(): 
     256        if not self._check_saved(): 
    216257            return True 
    217         run_out = self.OnRun(None) 
    218         if self._get_err_msg(run_out): 
    219             if self._manager != None and self.panel != None: 
    220                 self._manager.set_edit_menu_helper(self.parent) 
    221                 # Update custom model list in fitpage combobox 
    222                 wx.CallAfter(self._manager.update_custom_combo) 
    223  
    224     def _check_changed(self): 
     258        fname = self.editor.getStatus()[0] 
     259        success = show_model_output(self, fname) 
     260 
     261        # Update custom model list in fitpage combobox 
     262        if success and self._manager != None and self.panel != None: 
     263            self._manager.set_edit_menu_helper(self.parent) 
     264            wx.CallAfter(self._manager.update_custom_combo) 
     265 
     266    def _check_saved(self): 
    225267        """ 
    226268        If content was changed, suggest to save it first 
     
    228270        if self.bufferHasChanged() and self.buffer.doc.filepath: 
    229271            cancel = self.bufferSuggestSave() 
    230             if cancel: 
    231                 return cancel 
    232  
    233     def _get_err_msg(self, text=''): 
    234         """ 
    235         Get err_msg 
    236         """ 
    237         name = None 
    238         mssg = "\n This is not a python file." 
    239         title = 'Error' 
    240         icon = wx.ICON_ERROR 
    241         try: 
    242             fname = self.editor.getStatus()[0] 
    243             name = os.path.basename(fname) 
    244             if name.split('.')[-1] != 'py': 
    245                 wx.MessageBox(str(mssg), title, style=icon) 
    246                 return False 
    247             msg = compile_file(fname) 
    248         except: 
    249             msg = None 
    250         if name == None: 
    251             wx.MessageBox(str(mssg), title, style=icon) 
    252             return False 
    253         mssg = "Compiling '%s'...\n" % name 
    254         if msg != None: 
    255             mssg += "Error occurred:\n" 
    256             mssg += str(msg) + "\n\n" 
    257             if text: 
    258                 mssg += "Run-Test results:\n" 
    259                 mssg += str(text) 
    260                 title = 'Warning' 
    261                 icon = wx.ICON_WARNING 
    262         else: 
    263             mssg += "Successful.\n\n" 
    264             if text: 
    265                 if text.count('Failed') or text.count('Error:') > 0: 
    266                     mssg += "But Simple Test FAILED: Please check your code.\n" 
    267                 mssg += "Run-Test results:\n" 
    268                 mssg += str(text) 
    269             title = 'Info' 
    270             icon = wx.ICON_INFORMATION 
    271         dlg = wx.lib.dialogs.ScrolledMessageDialog(self, mssg, title, 
    272                                                    size=((550, 250))) 
    273         fnt = wx.Font(10, wx.TELETYPE, wx.NORMAL, wx.NORMAL) 
    274         dlg.GetChildren()[0].SetFont(fnt) 
    275         dlg.GetChildren()[0].SetInsertionPoint(0) 
    276         dlg.ShowModal() 
    277         dlg.Destroy() 
     272            return not cancel 
    278273        return True 
    279274 
     
    286281        event.Enable(True) 
    287282        try: 
    288             if id == ID_COMPILE or id == ID_RUN: 
     283            if id == ID_CHECK_MODEL or id == ID_RUN: 
    289284                menu_on = False 
    290285                if self.buffer and self.buffer.doc.filepath: 
Note: See TracChangeset for help on using the changeset viewer.