Skip to content

Commit 7d84fba

Browse files
committed
implemented chris's suggestions
1 parent 5e01f5e commit 7d84fba

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

pydra/engine/helpers.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,3 +735,22 @@ def parse_copyfile(fld: attr.Attribute, default_collation=FileSet.CopyCollation.
735735
f"Unrecognised type for collation copyfile metadata of {fld}, {collation}"
736736
)
737737
return mode, collation
738+
739+
740+
def parse_format_string(fmtstr):
741+
"""Parse a argstr format string and return all keywords used in it."""
742+
identifier = r"[a-zA-Z_]\w*"
743+
attribute = rf"\.{identifier}"
744+
item = r"\[\w+\]"
745+
# Example: var.attr[key][0].attr2 (capture "var")
746+
field_with_lookups = (
747+
f"({identifier})(?:{attribute}|{item})*" # Capture only the keyword
748+
)
749+
conversion = "(?:!r|!s)"
750+
nobrace = "[^{}]*"
751+
# Example: 0{pads[hex]}x (capture "pads")
752+
fmtspec = f"{nobrace}(?:{{({identifier}){nobrace}}}{nobrace})?" # Capture keywords in spec
753+
full_field = f"{{{field_with_lookups}{conversion}?(?::{fmtspec})?}}"
754+
755+
all_keywords = re.findall(full_field, fmtstr)
756+
return set().union(*all_keywords) - {""}

pydra/engine/tests/test_helpers.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from pathlib import Path
44
import random
55
import platform
6+
import typing as ty
67
import pytest
78
import attrs
89
import cloudpickle as cp
@@ -17,6 +18,7 @@
1718
position_sort,
1819
parse_copyfile,
1920
argstr_formatting,
21+
parse_format_string,
2022
)
2123
from ...utils.hash import hash_function
2224
from ..core import Workflow
@@ -51,7 +53,7 @@ def test_hash_file(tmpdir):
5153
with open(outdir / "test.file", "w") as fp:
5254
fp.write("test")
5355
assert (
54-
hash_function(File(outdir / "test.file")) == "37fcc546dce7e59585f3217bb4c30299"
56+
hash_function(File(outdir / "test.file")) == "f32ab20c4a86616e32bf2504e1ac5a22"
5557
)
5658

5759

@@ -330,3 +332,33 @@ class Inputs:
330332
)
331333
== "1 2.000000 -test 3 -me 4"
332334
)
335+
336+
337+
def test_parse_format_string1():
338+
assert parse_format_string("{a}") == {"a"}
339+
340+
341+
def test_parse_format_string2():
342+
assert parse_format_string("{abc}") == {"abc"}
343+
344+
345+
def test_parse_format_string3():
346+
assert parse_format_string("{a:{b}}") == {"a", "b"}
347+
348+
349+
def test_parse_format_string4():
350+
assert parse_format_string("{a:{b[2]}}") == {"a", "b"}
351+
352+
353+
def test_parse_format_string5():
354+
assert parse_format_string("{a.xyz[somekey].abc:{b[a][b].d[0]}}") == {"a", "b"}
355+
356+
357+
def test_parse_format_string6():
358+
assert parse_format_string("{a:05{b[a 2][b].e}}") == {"a", "b"}
359+
360+
361+
def test_parse_format_string7():
362+
assert parse_format_string(
363+
"{a1_field} {b2_field:02f} -test {c3_field[c]} -me {d4_field[0]}"
364+
) == {"a1_field", "b2_field", "c3_field", "d4_field"}

0 commit comments

Comments
 (0)