Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions pyflow/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

from __future__ import absolute_import

import warnings

warnings.formatwarning = (
lambda mess, category, filename, lineno, *args: f"\033[93m[{category.__name__}] {filename}:{lineno}\n{mess}\n\033[0m"
)
warnings.filterwarnings("default", category=DeprecationWarning)
warn = warnings.warn

from .attributes import (
Aviso,
Complete,
Expand Down
8 changes: 6 additions & 2 deletions pyflow/anchor.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import os

from . import warn


class AnchorMixin:
"""
Expand All @@ -12,8 +14,10 @@ def __init__(self, *args, **kwargs):
variables.update(kwargs)

if "out" in kwargs:
print(
"WARNING! out option is deprecated for nodes, use the log_directory option in the host instead"
warn(
"'out' option is deprecated for nodes, use the log_directory option in the host instead",
DeprecationWarning,
stacklevel=2,
)

for control_variable in ("files", "include", "home", "out", "extn"):
Expand Down
3 changes: 2 additions & 1 deletion pyflow/deployment.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import os
import shutil

from pyflow import warn
from pyflow.html import FileListHTMLWrapper


Expand Down Expand Up @@ -232,7 +233,7 @@ def create_directory(self, path):
try:
os.makedirs(path)
except Exception:
print("WARNING: Couldn't create directory: {}".format(path))
warn("Couldn't create directory: {}".format(path), stacklevel=0)

def check(self, target):
"""
Expand Down
20 changes: 15 additions & 5 deletions pyflow/host.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
import shutil
import textwrap

from . import warn
from .attributes import Label, Limit
from .base import STACK
from .inspect import get_value_at_caller
from .nodes import DuplicateNodeError, Family, ecflow_name

SET_ECF_VARIABLES = """
Expand Down Expand Up @@ -307,9 +309,13 @@ def build_label(self):

def script_submit_arguments(self, submit_arguments):
if len(submit_arguments) > 0:
print(
f"Host {self.__class__.__name__} does not support scheduler submission arguments. \
Submission arguments will be ignored in the script generation",
node = get_value_at_caller("self", 2)
name = getattr(node, "fullname", getattr(node, "name", node))
warn(
f"{name}: Host {self.__class__.__name__} does not support scheduler submission arguments, which "
f"will be ignored in the script generation. ",
UserWarning,
stacklevel=0,
)
return []

Expand Down Expand Up @@ -1169,8 +1175,12 @@ def _translate_sthost(val):
args.append(pragma)
else:
if arg in deprecated:
print(
f"WARNING! '{arg}' is deprecated, use '{deprecated[arg]}' instead"
node = get_value_at_caller("self", stacklevel=2)
name = getattr(node, "fullname", getattr(node, "name", node))
warn(
f"{name}: {arg}' is deprecated in TroikaHost, use '{deprecated[arg]}' instead",
DeprecationWarning,
stacklevel=0,
)
arg = deprecated[arg]
if arg is not None:
Expand Down
23 changes: 23 additions & 0 deletions pyflow/inspect.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import inspect


def get_value_at_caller(target="self", stacklevel=2):
"""
returns the value of a variable in the caller's frame. Useful for getting
caller objects or variables at caller level, e.g, a Task name when defining its
submit arguments on its Host.
:param target: The name of the variable to retrieve from the caller's frame.
Defaults to "self", which is common in class methods.
:param stacklevel: The number of frames to go back in the call stack.
Defaults to 2, which means it will look at the frame of immediate caller.
"""

frame = inspect.stack()[1].frame
for _ in range(stacklevel - 1):
if frame is None:
raise ValueError(f"No caller frame found with stacklevel {stacklevel}.")
frame = frame.f_back
# Get local variables in the caller's frame
locals_ = frame.f_locals

return locals_.get(target, None)
4 changes: 2 additions & 2 deletions pyflow/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1161,9 +1161,9 @@ def deploy_suite(self, target=FileSystem, node=None, **options):
script, includes = t.generate_script()
try:
target.deploy_task(t.deploy_path, script, includes)
except RuntimeError:
except Exception as e:
print(f"\nERROR when deploying task: {t.fullname}\n")
raise
raise (e)
for f in node.all_families:
manual = self.generate_stub(f.manual)
if manual:
Expand Down
1 change: 0 additions & 1 deletion tests/test_host.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,6 @@ def test_troika_host():


def test_host_submit_args():

submit_args = {
"troika": {
"tasks": 2, # deprecated option, will be translated to total_tasks
Expand Down
Loading