Skip to content

Commit bd364b2

Browse files
committed
🎨 format: change dryrun logic on caller stage.
1 parent a9d1eec commit bd364b2

File tree

3 files changed

+98
-18
lines changed

3 files changed

+98
-18
lines changed

src/ddeutil/workflow/stages.py

Lines changed: 79 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -680,12 +680,19 @@ def dryrun(
680680
params, run_id, context, parent_run_id=parent_run_id, event=event
681681
)
682682

683-
def to_empty(self, sleep: int = 0.35) -> EmptyStage:
683+
def to_empty(
684+
self,
685+
sleep: int = 0.35,
686+
*,
687+
message: Optional[str] = None,
688+
) -> EmptyStage:
684689
"""Convert the current Stage model to the EmptyStage model for dry-run
685690
mode if the `action_stage` class attribute has set.
686691
687692
Args:
688693
sleep (int, default 0.35): An adjustment sleep time.
694+
message (str, default None): A message that want to override default
695+
message on EmptyStage model.
689696
690697
Returns:
691698
EmptyStage: An EmptyStage model that passing itself model data to
@@ -699,7 +706,10 @@ def to_empty(self, sleep: int = 0.35) -> EmptyStage:
699706
"id": self.id,
700707
"desc": self.desc,
701708
"if": self.condition,
702-
"echo": f"Convert from {self.__class__.__name__} to EmptyStage",
709+
"echo": (
710+
message
711+
or f"Convert from {self.__class__.__name__} to EmptyStage"
712+
),
703713
"sleep": sleep,
704714
}
705715
)
@@ -1853,7 +1863,7 @@ def process(
18531863
extras=self.extras,
18541864
),
18551865
"extras": self.extras,
1856-
} | param2template(self.args, params, extras=self.extras)
1866+
} | self.pass_template(self.args, params)
18571867
sig = inspect.signature(call_func)
18581868
necessary_params: list[str] = []
18591869
has_keyword: bool = False
@@ -1868,6 +1878,7 @@ def process(
18681878
elif v.kind == Parameter.VAR_KEYWORD:
18691879
has_keyword = True
18701880

1881+
# NOTE: Validate private parameter should exist in the args field.
18711882
if any(
18721883
(k.removeprefix("_") not in args and k not in args)
18731884
for k in necessary_params
@@ -1885,11 +1896,12 @@ def process(
18851896
f"does not set to args. It already set {list(args.keys())}."
18861897
)
18871898

1888-
if "result" not in sig.parameters and not has_keyword:
1889-
args.pop("result")
1899+
if not has_keyword:
1900+
if "result" not in sig.parameters:
1901+
args.pop("result")
18901902

1891-
if "extras" not in sig.parameters and not has_keyword:
1892-
args.pop("extras")
1903+
if "extras" not in sig.parameters:
1904+
args.pop("extras")
18931905

18941906
if event and event.is_set():
18951907
raise StageCancelError("Cancel before start call process.")
@@ -1972,7 +1984,7 @@ async def async_process(
19721984
extras=self.extras,
19731985
),
19741986
"extras": self.extras,
1975-
} | param2template(self.args, params, extras=self.extras)
1987+
} | self.pass_template(self.args, params)
19761988
sig = inspect.signature(call_func)
19771989
necessary_params: list[str] = []
19781990
has_keyword: bool = False
@@ -2003,11 +2015,13 @@ async def async_process(
20032015
f"Necessary params, ({', '.join(necessary_params)}, ), "
20042016
f"does not set to args. It already set {list(args.keys())}."
20052017
)
2006-
if "result" not in sig.parameters and not has_keyword:
2007-
args.pop("result")
20082018

2009-
if "extras" not in sig.parameters and not has_keyword:
2010-
args.pop("extras")
2019+
if not has_keyword:
2020+
if "result" not in sig.parameters:
2021+
args.pop("result")
2022+
2023+
if "extras" not in sig.parameters:
2024+
args.pop("extras")
20112025

20122026
if event and event.is_set():
20132027
raise StageCancelError("Cancel before start call process.")
@@ -2057,11 +2071,14 @@ def validate_model_args(
20572071
"""Validate an input arguments before passing to the caller function.
20582072
20592073
Args:
2060-
func: (TagFunc) A tag function that want to get typing.
2061-
args: (DictData) An arguments before passing to this tag func.
2062-
run_id: A running stage ID.
2074+
func (TagFunc): A tag function object that want to get typing.
2075+
args (DictData): An arguments before passing to this tag func.
2076+
run_id (str): A running ID.
2077+
parent_run_id (str, default None): A parent running ID.
2078+
extras (DictData, default None): An extra parameters.
20632079
2064-
:rtype: DictData
2080+
Returns:
2081+
DictData: A prepared args paramter that validate with model args.
20652082
"""
20662083
try:
20672084
override: DictData = dict(
@@ -2109,8 +2126,52 @@ def dryrun(
21092126
- Pre-hook caller function that exist.
21102127
- Show function parameters
21112128
"""
2112-
return super().dryrun(
2113-
params, run_id, context, parent_run_id=parent_run_id, event=event
2129+
trace: Trace = get_trace(
2130+
run_id, parent_run_id=parent_run_id, extras=self.extras
2131+
)
2132+
call_func: TagFunc = self.get_caller(params=params)()
2133+
trace.info(f"[STAGE]: Caller Func: '{call_func.name}@{call_func.tag}'")
2134+
2135+
args: DictData = {
2136+
"result": Result(
2137+
run_id=run_id,
2138+
parent_run_id=parent_run_id,
2139+
status=WAIT,
2140+
context=context,
2141+
extras=self.extras,
2142+
),
2143+
"extras": self.extras,
2144+
} | self.pass_template(self.args, params)
2145+
sig = inspect.signature(call_func)
2146+
trace.debug(f"[STAGE]: {sig.parameters}")
2147+
necessary_params: list[str] = []
2148+
has_keyword: bool = False
2149+
for k in sig.parameters:
2150+
if (
2151+
v := sig.parameters[k]
2152+
).default == Parameter.empty and v.kind not in (
2153+
Parameter.VAR_KEYWORD,
2154+
Parameter.VAR_POSITIONAL,
2155+
):
2156+
necessary_params.append(k)
2157+
elif v.kind == Parameter.VAR_KEYWORD:
2158+
has_keyword = True
2159+
func_typed = get_type_hints(call_func)
2160+
trace.debug(
2161+
f"[STAGE]: Details"
2162+
f"||Necessary Params: {necessary_params}"
2163+
f"||Argument Params: {list(args.keys())}"
2164+
f"||Return Type: {func_typed['return']}"
2165+
f"||"
2166+
)
2167+
if has_keyword:
2168+
trace.debug("[STAGE]: This caller function support keyword param.")
2169+
return Result(
2170+
run_id=run_id,
2171+
parent_run_id=parent_run_id,
2172+
status=SUCCESS,
2173+
context=catch(context=context, status=SUCCESS),
2174+
extras=self.extras,
21142175
)
21152176

21162177

tests/stages/test_stage_call.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,19 @@ def test_call_stage_validate_args():
3535
)
3636

3737

38+
def test_call_stage_dryrun():
39+
stage: Stage = CallStage.model_validate(
40+
{
41+
"name": "Necessary argument do not pass",
42+
"id": "private-args",
43+
"uses": "tasks/private-args-task@demo",
44+
"with": {"params": {"run_mode": "T"}, "exec": "test"},
45+
}
46+
)
47+
rs: Result = stage.dryrun(params={}, run_id="01", context={})
48+
assert rs.status == SUCCESS
49+
50+
3851
def test_call_stage_exec_necessary_args():
3952
stage: Stage = CallStage.model_validate(
4053
{

tests/stages/test_stage_empty.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ def test_empty_stage():
5353
assert empty_stage.sleep == 10
5454

5555

56+
def test_empty_stage_dryrun():
57+
stage: EmptyStage = EmptyStage(name="Empty Stage", echo="hello world")
58+
rs: Result = stage.dryrun(params={}, run_id="01", context={})
59+
assert rs.status == SUCCESS
60+
61+
5662
def test_empty_stage_execute():
5763
stage: EmptyStage = EmptyStage(name="Empty Stage", echo="hello world")
5864
rs: Result = stage.execute(params={})

0 commit comments

Comments
 (0)