diff --git a/Makefile b/Makefile index 6dbcbf4..e179049 100644 --- a/Makefile +++ b/Makefile @@ -96,7 +96,7 @@ dist: clean ## builds source and wheel package python setup.py bdist_wheel ls -l dist -install: clean ## install the package to the active Python's site-packages +install: uninstall ## install the package to the active Python's site-packages python setup.py install uninstall: clean ## uninstall the package diff --git a/loop_step/loop.py b/loop_step/loop.py index 300da8b..b8556e7 100644 --- a/loop_step/loop.py +++ b/loop_step/loop.py @@ -2,6 +2,7 @@ """Non-graphical part of the Loop step in a SEAMM flowchart""" +import configargparse import logging import loop_step import seamm @@ -29,6 +30,41 @@ def __init__(self, flowchart=None, extension=None): self._loop_value = None self._loop_length = None + # Argument/config parsing + self.parser = configargparse.ArgParser( + auto_env_var_prefix='', + default_config_files=[ + '/etc/seamm/loop.ini', + '/etc/seamm/seamm.ini', + '~/.seamm/loop.ini', + '~/.seamm/seamm.ini', + ] + ) + + self.parser.add_argument( + '--seamm-configfile', + is_config_file=True, + default=None, + help='a configuration file to override others' + ) + + # Options for this plugin + self.parser.add_argument( + "--loop-log-level", + default=configargparse.SUPPRESS, + choices=[ + 'CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG', 'NOTSET' + ], + type=lambda string: string.upper(), + help="the logging level for the Loop step" + ) + + self.options, self.unknown = self.parser.parse_known_args() + + # Set the logging level for this module if requested + if 'loop_log_level' in self.options: + logger.setLevel(self.options.loop_log_level) + super().__init__( flowchart=flowchart, title='Loop', extension=extension ) @@ -270,11 +306,16 @@ def run(self): return self.exit_node() # Set up the index variables + logger.debug(' _loop_value = {}'.format(self._loop_value)) tmp = self.get_variable('_loop_indices') + logger.debug(' _loop_indices = {}'.format(tmp)) self.set_variable( '_loop_indices', (*tmp[0:-1], self.table.index[self._loop_value]) ) + logger.debug( + ' --> {}'.format(self.get_variable('_loop_indices')) + ) self.set_variable( '_loop_index', self.table.index[self._loop_value] ) @@ -284,6 +325,7 @@ def run(self): row = self.table.iloc[self._loop_value] self.set_variable('_row', row) + logger.debug(' _row = {}'.format(row)) for edge in self.flowchart.edges(self, direction='out'): if edge.edge_subtype == 'loop': @@ -296,11 +338,10 @@ def run(self): self.set_subids( (*self._id, 'iter_{}'.format(self._loop_value)) ) - return edge.node2 - - # No loop body? just go on? - return self.exit_node() + else: + # No loop body? just go on? + return self.exit_node() def default_edge_subtype(self): """Return the default subtype of the edge. Usually this is 'next' @@ -349,8 +390,6 @@ def set_subids(self, node_id=()): next_node = next_node.set_id((*node_id, str(n))) n += 1 - logger.debug('end of loop') - def exit_node(self): """The next node after the loop, if any""" diff --git a/loop_step/loop_parameters.py b/loop_step/loop_parameters.py index 4e75aea..e972787 100644 --- a/loop_step/loop_parameters.py +++ b/loop_step/loop_parameters.py @@ -20,7 +20,6 @@ class LoopParameters(seamm.Parameters): "For", "Foreach", "For rows in table", - "While", ), "format_string": "s", "description": "", diff --git a/loop_step/tk_loop.py b/loop_step/tk_loop.py index 7ca3ec7..858a693 100644 --- a/loop_step/tk_loop.py +++ b/loop_step/tk_loop.py @@ -2,12 +2,11 @@ """The graphical part of a Loop step""" +import configargparse import logging import seamm import loop_step -import Pmw import tkinter as tk -import tkinter.ttk as ttk logger = logging.getLogger(__name__) @@ -27,14 +26,55 @@ def __init__( x=120, y=20, w=200, - h=50 + h=50, + my_logger=logger ): - '''Initialize a node + """Initialize the graphical Tk Loop node Keyword arguments: - ''' - self.dialog = None + """ + + self.node_type = 'loop' + + # Argument/config parsing + self.parser = configargparse.ArgParser( + auto_env_var_prefix='', + default_config_files=[ + '/etc/seamm/tk_loop.ini', + '/etc/seamm/seamm.ini', + '~/.seamm/tk_loop.ini', + '~/.seamm/seamm.ini', + ] + ) + + self.parser.add_argument( + '--seamm-configfile', + is_config_file=True, + default=None, + help='a configuration file to override others' + ) + + # Options for this plugin + self.parser.add_argument( + "--tk-loop-log-level", + default=configargparse.SUPPRESS, + choices=[ + 'CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG', 'NOTSET' + ], + type=lambda string: string.upper(), + help="the logging level for the Tk_Loop step" + ) + + self.options, self.unknown = self.parser.parse_known_args() + + # Set the logging level for this module if requested + if 'tk_loop_log_level' in self.options: + logger.setLevel(self.options.tk_loop_log_level) + logger.critical( + 'Set log level to {}'.format(self.options.tk_loop_log_level) + ) + # Call the constructor for the energy super().__init__( tk_flowchart=tk_flowchart, node=node, @@ -42,26 +82,13 @@ def __init__( x=x, y=y, w=w, - h=h + h=h, + my_logger=my_logger ) - self.node_type = 'loop' - def create_dialog(self): """Create the dialog!""" - self.dialog = Pmw.Dialog( - self.toplevel, - buttons=('OK', 'Help', 'Cancel'), - master=self.toplevel, - title='Edit Loop step', - command=self.handle_dialog - ) - self.dialog.withdraw() - - # Create a frame to hold everything - frame = ttk.Frame(self.dialog.interior()) - frame.pack(expand=tk.YES, fill=tk.BOTH) - self['frame'] = frame + frame = super().create_dialog(title='Edit Loop Step') # Create the widgets and grid them in P = self.node.parameters @@ -70,12 +97,10 @@ def create_dialog(self): self['type'].combobox.bind("<>", self.reset_dialog) - self.reset_dialog() - def reset_dialog(self, widget=None): + """Lay out the edit dialog according to the type of loop.""" - # and get the method, which in this example controls - # how the widgets are laid out. + # Get the type of loop currently requested loop_type = self['type'].get() logger.debug('Updating edit loop dialog: {}'.format(loop_type)) @@ -99,7 +124,6 @@ def reset_dialog(self, widget=None): self['values'].grid(row=row, column=3, sticky=tk.W) elif loop_type == 'For rows in table': self['table'].grid(row=row, column=2, sticky=tk.W) - self['variable'].grid(row=row, column=3, sticky=tk.W) else: raise RuntimeError( "Don't recognize the loop_type {}".format(loop_type) @@ -115,41 +139,6 @@ def right_click(self, event): self.popup_menu.tk_popup(event.x_root, event.y_root, 0) - def edit(self): - """Present a dialog for editing the Loop input - """ - if self.dialog is None: - self.create_dialog() - - self.dialog.activate(geometry='centerscreenfirst') - - def handle_dialog(self, result): - if result is None or result == 'Cancel': - self.dialog.deactivate(result) - return - - if result == 'Help': - # display help!!! - return - - if result != "OK": - self.dialog.deactivate(result) - raise RuntimeError( - "Don't recognize dialog result '{}'".format(result) - ) - - self.dialog.deactivate(result) - - # Shortcut for parameters - P = self.node.parameters - - for key in P: - P[key].set_from_widget() - - def handle_help(self): - """Not implemented yet ... you'll need to fill this out!""" - print('Help!') - def default_edge_subtype(self): """Return the default subtype of the edge. Usually this is 'next' but for nodes with two or more edges leaving them, such as a loop, this