FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Merge feat/692-D-float-string-window-count (#785) · dkackman/diffusers-workflow@926f96b · GitHub

Repository navigation

Commit 926f96b

Browse files
andcommitted
Merge feat/692-D-float-string-window-count (#785)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 parents c0d1c0b + fb7324d commit 926f96b

2 files changed

Lines changed: 62 additions & 19 deletions

File tree

‎dw/window_count_errors.py‎

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@
1414
knowable without running anything: `source` is an `asset:`/`output:`
1515
reference or a literal path the run may read (`dw/probe_paths.py`), probed
1616
header-only (`probe_metadata`, B9); `num_frames` and `overlap` are literal
17-
after substitution; and `videos` is a list - which is what `gather:<step>`
18-
becomes once `for_each` has expanded, one entry per member. The rule itself
17+
whole numbers after substitution - an int, an integral float or a numeric
18+
string, read by `whole_number` as the run reads them (#785); and `videos` is
19+
a list - which is what `gather:<step>` becomes once `for_each` has expanded,
20+
one entry per member. The rule itself
1921
is `window_count_problem` in `dw/task_domains.py`, the one the task calls at
2022
run time, so the two cannot drift.
2123
@@ -28,24 +30,23 @@
2830
report, so it is skipped here rather than reported twice.
2931
"""
3032

31-
import numbers
32-
3333
from .for_each import MEMBER_SEPARATOR, render_path
3434
from .media import probe_metadata
3535
from .probe_paths import resolve_probe_path
3636
from .references import author_index
37-
from .task_domains import window_count_problem
38-
39-
40-
def _literal_whole(value):
41-
"""`value` as an int when it is a literal whole number, else None."""
42-
if isinstance(value, bool):
37+
from .task_domains import whole_number, window_count_problem
38+
39+
40+
def _literal_whole(value, name):
41+
"""`value` as an int when it is a literal whole number, read by
42+
`whole_number`'s rules (`33`, `33.0`, `"33"`, `"33.0"` are all 33), else
43+
None. A value that is not a whole number - a fraction, a bool, an
44+
unresolved reference - is skipped here: `join_windows_errors` refuses it
45+
with the "whole number" message, so it is not reported twice (#785)."""
46+
try:
47+
return whole_number(value, name, "join_windows")
48+
except ValueError:
4349
return None
44-
if isinstance(value, numbers.Integral):
45-
return int(value)
46-
if isinstance(value, float) and value.is_integer():
47-
return int(value)
48-
return None
4950

5051

5152
def _frame_count(path, probe):
@@ -87,8 +88,8 @@ def window_count_errors(
8788
videos = arguments.get("videos")
8889
if not isinstance(videos, list) or not videos:
8990
continue
90-
num_frames = _literal_whole(arguments.get("num_frames"))
91-
overlap = _literal_whole(arguments.get("overlap"))
91+
num_frames = _literal_whole(arguments.get("num_frames"), "num_frames")
92+
overlap = _literal_whole(arguments.get("overlap"), "overlap")
9293
if num_frames is None or overlap is None:
9394
continue
9495
if num_frames <= 0 or overlap < 0 or overlap >= num_frames:

‎tests/test_window_count_errors.py‎

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
step) rather than a template.
77
"""
88

9+
import pytest
10+
911
from dw.media import probe_metadata
1012
from dw.window_count_errors import window_count_errors
1113
from dw.workflow import workflow_from_definition
@@ -55,12 +57,13 @@ def window_workflow(window_count, num_frames=NUM_FRAMES, overlap=OVERLAP):
5557
}
5658

5759

58-
def validate(monkeypatch, tmp_path, window_count, frames=50):
60+
def validate(monkeypatch, tmp_path, window_count, frames=50, **numbers):
5961
import os
6062

6163
base_dir = workflow_dir_with_asset(monkeypatch, tmp_path, ("long.mp4", frames))
6264
workflow = workflow_from_definition(
63-
window_workflow(window_count), os.path.join(base_dir, "workflow.json")
65+
window_workflow(window_count, **numbers),
66+
os.path.join(base_dir, "workflow.json"),
6467
)
6568
return [
6669
problem
@@ -110,6 +113,45 @@ def test_a_long_list_names_the_drop(self, monkeypatch, tmp_path):
110113
assert "got 5" in problems[0]["message"]
111114
assert "drop 1 entry (index 4)" in problems[0]["message"]
112115

116+
@pytest.mark.parametrize(
117+
"num_frames, overlap",
118+
[
119+
(NUM_FRAMES, OVERLAP),
120+
(str(NUM_FRAMES), str(OVERLAP)),
121+
(float(NUM_FRAMES), float(OVERLAP)),
122+
(f"{NUM_FRAMES}.0", float(OVERLAP)),
123+
(f"{NUM_FRAMES}.0", f"{OVERLAP}.0"),
124+
],
125+
ids=["int", "string", "float", "float-string+float", "float-strings"],
126+
)
127+
def test_every_whole_number_form_gets_the_int_refusal(
128+
self, monkeypatch, tmp_path, num_frames, overlap
129+
):
130+
"""C-F354h (#785): "17", 17.0 and "17.0" are read by whole_number's
131+
rules, as the run reads them, so validate refuses the short list the
132+
same way it does for 17 instead of skipping the check."""
133+
problems = validate(
134+
monkeypatch, tmp_path, 3, num_frames=num_frames, overlap=overlap
135+
)
136+
137+
assert problems == [
138+
{
139+
"path": "steps[1]",
140+
"message": "join_windows needs 4 windows for a 50-frame source"
141+
" with num_frames 17 and overlap 4 (stride 13), got 3"
142+
" - add 1 entry (index 3)",
143+
}
144+
]
145+
146+
def test_a_fractional_string_is_left_to_the_whole_number_refusal(
147+
self, monkeypatch, tmp_path
148+
):
149+
"""A non-whole value names no count; the domain check refuses it."""
150+
problems = validate(monkeypatch, tmp_path, 3, num_frames="17.5")
151+
152+
assert not [p for p in problems if "windows for a" in p["message"]]
153+
assert any("whole number for 'num_frames'" in p["message"] for p in problems)
154+
113155
def test_an_unreadable_literal_source_is_refused_at_its_path(
114156
self, monkeypatch, tmp_path
115157
):

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL