diff --git a/src/damaris/gui/DamarisGUI.py b/src/damaris/gui/DamarisGUI.py index c952364..c42e304 100644 --- a/src/damaris/gui/DamarisGUI.py +++ b/src/damaris/gui/DamarisGUI.py @@ -1186,7 +1186,6 @@ get_ylabel set_ylabel""" compexp.add_provider(self.compwexp) compres.add_provider(self.compwres) - # script fonts are atlered by configuration # clipboard self.main_clipboard = gtk.Clipboard( ) @@ -1194,13 +1193,12 @@ get_ylabel set_ylabel""" self.experiment_script_statusbar_label = self.xml_gui.get_object( "statusbar_experiment_script_label" ) self.data_handling_statusbar_label = self.xml_gui.get_object( "statusbar_data_handling_label" ) - # footline with line and col indicators + # footer with line and col indicators self.experiment_script_line_indicator = self.xml_gui.get_object( "experiment_script_line_textfield" ) self.experiment_script_column_indicator = self.xml_gui.get_object( "experiment_script_column_textfield" ) self.data_handling_line_indicator = self.xml_gui.get_object( "data_handling_line_textfield" ) self.data_handling_column_indicator = self.xml_gui.get_object( "data_handling_column_textfield" ) - # some event handlers self.experiment_script_textbuffer.connect( "modified-changed", self.textviews_modified ) self.experiment_script_textview.connect_after( "move-cursor", self.textviews_moved ) @@ -1211,8 +1209,7 @@ get_ylabel set_ylabel""" self.data_handling_textview.connect( "key-press-event", self.textviews_keypress ) self.data_handling_textview.connect( "button-release-event", self.textviews_clicked ) - # and the editing toolbar part - # buttons + # and the editing toolbar buttons self.toolbar_new_button = self.xml_gui.get_object( "toolbar_new_button" ) self.toolbar_open_button = self.xml_gui.get_object( "toolbar_open_file_button" ) self.toolbar_save_button = self.xml_gui.get_object( "toolbar_save_file_button" ) @@ -1223,8 +1220,9 @@ get_ylabel set_ylabel""" self.toolbar_redo_button = self.xml_gui.get_object( "toolbar_redo_button" ) self.toolbar_search_button = self.xml_gui.get_object("toolbar_search_button") - # my notebook + # main notebook self.main_notebook = self.xml_gui.get_object( "main_notebook" ) + # config toolbar self.main_notebook.connect_after( "switch_page", self.notebook_page_switched ) diff --git a/src/damaris/gui/ExperimentHandling.py b/src/damaris/gui/ExperimentHandling.py index d3b2da0..2172b70 100644 --- a/src/damaris/gui/ExperimentHandling.py +++ b/src/damaris/gui/ExperimentHandling.py @@ -3,6 +3,7 @@ import io import traceback import sys import time +import ast from damaris.experiments.Experiment import Quit from damaris.experiments import Experiment @@ -48,8 +49,32 @@ class ExperimentHandling(threading.Thread): self.raised_exception = None self.location = None exp_iterator=None + + # check for time.sleep() + try: + tree = ast.parse(self.script) + for node in ast.walk(tree): + found_blocking_sleep = False + if isinstance(node, ast.Call): + func = node.func + if isinstance(func, ast.Attribute) and func.attr == 'sleep': + if isinstance(func.value, ast.Name) and func.value.id == 'time': + found_blocking_sleep = True + elif isinstance(node, ast.ImportFrom) and node.module == 'time': + for alias in node.names: + if alias.name == 'sleep': + found_blocking_sleep = True + + if found_blocking_sleep: + print("Warning: time.sleep() detected in experiment script. This is blocking and not interruptible. Please use sleep() instead.") + break + except Exception: + pass + try: exec(self.script, dataspace) + except StopExperiment: + return except Exception as e: self.raised_exception=e self.location=traceback.extract_tb(sys.exc_info()[2])[-1][1:3] @@ -61,6 +86,8 @@ class ExperimentHandling(threading.Thread): if "experiment" in dataspace: try: exp_iterator=dataspace["experiment"]() + except StopExperiment: + return except Exception as e: self.raised_exception=e self.location=traceback.extract_tb(sys.exc_info()[2])[-1][1:3] diff --git a/src/damaris/gui/ResultHandling.py b/src/damaris/gui/ResultHandling.py index bf9aafb..44d9ea7 100644 --- a/src/damaris/gui/ResultHandling.py +++ b/src/damaris/gui/ResultHandling.py @@ -4,7 +4,9 @@ import sys import os import os.path import traceback +import ast from damaris.data import Resultable +from damaris.gui.ExperimentHandling import StopExperiment class ResultHandling(threading.Thread): """ @@ -30,10 +32,35 @@ class ResultHandling(threading.Thread): del data_classes dataspace["results"]=self dataspace["data"]=self.data_space + dataspace["sleep"]=self.sleep self.raised_exception=None self.location = None + + # check for time.sleep() + try: + tree = ast.parse(self.script) + for node in ast.walk(tree): + found_blocking_sleep = False + if isinstance(node, ast.Call): + func = node.func + if isinstance(func, ast.Attribute) and func.attr == 'sleep': + if isinstance(func.value, ast.Name) and func.value.id == 'time': + found_blocking_sleep = True + elif isinstance(node, ast.ImportFrom) and node.module == 'time': + for alias in node.names: + if alias.name == 'sleep': + found_blocking_sleep = True + + if found_blocking_sleep: + print("Warning: time.sleep() detected in result script. This is blocking and not interruptible. Please use sleep() instead.") + break + except Exception: + pass + try: exec(self.script, dataspace) + except StopExperiment: + return except Exception as e: self.raised_exception=e self.location=traceback.extract_tb(sys.exc_info()[2])[-1][1:3] @@ -47,6 +74,8 @@ class ResultHandling(threading.Thread): return try: dataspace["result"]() + except StopExperiment: + pass except Exception as e: self.raised_exception=e self.location=traceback.extract_tb(sys.exc_info()[2])[-1][1:3] @@ -56,6 +85,11 @@ class ResultHandling(threading.Thread): traceback_file=None dataspace=None + def sleep(self, seconds): + self.quit_flag.wait(seconds) + if self.quit_flag.isSet(): + raise StopExperiment + def __iter__(self): if self.quit_flag.isSet(): self.results=None