Skip to content

Commit

Permalink
ENH Debug break points. Variable substitution minus string formating.
Browse files Browse the repository at this point in the history
  • Loading branch information
gadorlhiac committed May 2, 2024
1 parent bafd152 commit 2b631ad
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 13 deletions.
59 changes: 59 additions & 0 deletions lute/execution/debug_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
"""Functions to assist in debugging execution of LUTE.
Functions:
LUTE_DEBUG_EXIT(env_var: str, str_dump: Optional[str]): Exits the program if
the provided `env_var` is set. Optionally, also prints a message if
provided.
Exceptions:
ValidationError: Error raised by pydantic during data validation. (From
Pydantic)
"""

__all__ = ["LUTE_DEBUG_EXIT"]
__author__ = "Gabriel Dorlhiac"

import os
import sys
import types
from typing import Optional


def _stack_inspect(msg: str, str_dump: Optional[str] = None) -> None:
import inspect

curr_frame: Optional[types.FrameType] = inspect.currentframe()
frame: Optional[types.FrameType]
if curr_frame:
frame = curr_frame.f_back
if frame:
frame = frame.f_back # Go back two stack frames...
else:
frame = None
if frame:
file_name: str = frame.f_code.co_filename
line_no: int = frame.f_lineno
msg = f"{msg} {file_name}, line: {line_no}"
else:
msg = f"{msg} Stack frame not retrievable..."
if str_dump is not None:
msg = f"{msg}\n{str_dump}"

print(msg, flush=True)


def LUTE_DEBUG_EXIT(env_var: str, str_dump: Optional[str] = None) -> None:
if os.getenv(env_var, None):
msg: str = "LUTE_DEBUG_EXIT -"
_stack_inspect(msg, str_dump)
sys.exit(0)


def LUTE_DEBUG_PAUSE(env_var: str, str_dump: Optional[str] = None) -> None:
# Need custom signal handlers to implement resume
if os.getenv(env_var, None):
import signal

msg: str = "LUTE_DEBUG_PAUSE -"
_stack_inspect(msg, str_dump)
signal.pause()
43 changes: 30 additions & 13 deletions lute/io/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import warnings
from typing import List, Dict, Iterator, Dict, Any

import yaml
import pprint
import yaml
from pydantic import (
BaseModel,
Expand All @@ -34,10 +34,11 @@
from pydantic.dataclasses import dataclass

from .models import *
from lute.execution.debug_utils import LUTE_DEBUG_EXIT


def substitute_variables(
config: Dict[str, Any], curr_key: Optional[str] = None
header: Dict[str, Any], config: Dict[str, Any], curr_key: Optional[str] = None
) -> None:
"""Performs variable substitutions on a dictionary read from config YAML file.
Expand Down Expand Up @@ -74,30 +75,45 @@ def substitute_variables(
have been made. May be identical to the input if no substitutions are
needed.
"""
_sub_pattern = "\{\{.*\}\}"
iterable: Dict[str, Any]
_sub_pattern = r"\{\{.*\}\}"
iterable: Dict[str, Any] = config
if curr_key is not None:
# Need to handle nested levels by interpreting curr_key
iterable = config[curr_key]
keys_by_level: List[str] = curr_key.split(".")
for key in keys_by_level:
iterable = iterable[key]
else:
iterable = config
...
# iterable = config
for param, value in iterable.items():
if isinstance(value, dict):
substitute_variables(config, curr_key=param)
new_key: str
if curr_key is None:
new_key = param
else:
new_key = f"{curr_key}.{param}"
substitute_variables(header, config, curr_key=new_key)
elif isinstance(value, list):
...
# Scalars str - we skip numeric types
elif isinstance(value, str):
matches: List[str] = re.findall(_sub_pattern, value)
for m in matches:
key_to_sub: str = m[2:-2].strip()
key_to_sub_maybe_with_fmt: List[str] = m[2:-2].strip().split(":")
key_to_sub: str = key_to_sub_maybe_with_fmt[0]
fmt: Optional[str] = None
if len(key_to_sub_maybe_with_fmt) == 2:
fmt = key_to_sub_maybe_with_fmt[1]
sub: str
if key_to_sub[0] == "$":
sub = os.environ.get(key_to_sub[1:], "")
else:
sub = config[key_to_sub]
pattern: str = m.replace("{{", "\{\{").replace("}}", "\}\}")
iterable[param] = re.sub(pattern, sub, value)
try:
sub = config[key_to_sub]
except KeyError:
sub = header[key_to_sub]
pattern: str = m.replace("{{", r"\{\{").replace("}}", r"\}\}")
iterable[param] = re.sub(pattern, str(sub), value)


def parse_config(task_name: str = "test", config_path: str = "") -> TaskParameters:
Expand All @@ -123,7 +139,9 @@ def parse_config(task_name: str = "test", config_path: str = "") -> TaskParamete
docs: Iterator[Dict[str, Any]] = yaml.load_all(stream=f, Loader=yaml.FullLoader)
header: Dict[str, Any] = next(docs)
config: Dict[str, Any] = next(docs)

# pprint.pprint(config)
substitute_variables(header, config)
LUTE_DEBUG_EXIT("LUTE_DEBUG_EXIT_AT_YAML", pprint.pformat(config))
lute_config: Dict[str, AnalysisHeader] = {"lute_config": AnalysisHeader(**header)}
try:
task_config: Dict[str, Any] = dict(config[task_name])
Expand All @@ -136,5 +154,4 @@ def parse_config(task_name: str = "test", config_path: str = "") -> TaskParamete
)
)
parsed_parameters: TaskParameters = globals()[task_config_name](**lute_config)

return parsed_parameters
2 changes: 2 additions & 0 deletions lute/tasks/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
AnalysisHeader,
)
from ..execution.ipc import *
from ..execution.debug_utils import LUTE_DEBUG_EXIT
from .dataclasses import *

if __debug__:
Expand Down Expand Up @@ -344,6 +345,7 @@ def _run(self) -> None:
time.sleep(0.1)
msg: Message = Message(contents=self._formatted_command())
self._report_to_executor(msg)
LUTE_DEBUG_EXIT("LUTE_DEBUG_BEFORE_TPP_EXEC")
os.execvp(file=self._cmd, args=self._args_list)

def _formatted_command(self) -> str:
Expand Down

0 comments on commit 2b631ad

Please sign in to comment.