From 9f818bb82cb87aaad6485bb9b20d179f4ee55a06 Mon Sep 17 00:00:00 2001 From: Peter Van Dyken Date: Thu, 9 May 2024 14:29:56 -0400 Subject: [PATCH] Prevent _run-{values} with leading 0s When used with `run`, the leading 0 gets stripped because run is converted into an int. This breaks tests that instantiate a datset on the filesystem and re-parse it using generate_inputs. Adds a `type` field to run in `bids_tags.json` and uses this to filter integers with leading 0s in the zip_lists strategy --- snakebids/resources/bids_tags.json | 3 ++- snakebids/tests/strategies.py | 12 +++++++++++- snakebids/utils/utils.py | 11 +++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/snakebids/resources/bids_tags.json b/snakebids/resources/bids_tags.json index 783e55c1..e11eb1fc 100644 --- a/snakebids/resources/bids_tags.json +++ b/snakebids/resources/bids_tags.json @@ -52,7 +52,8 @@ "run": { "tag": "run", "before": "[_/\\\\]+run-", - "match": "[0-9]{1,5}" + "match": "[0-9]{1,5}", + "type": "int" }, "proc": { "tag": "proc", diff --git a/snakebids/tests/strategies.py b/snakebids/tests/strategies.py index c75678b2..d6bbde15 100644 --- a/snakebids/tests/strategies.py +++ b/snakebids/tests/strategies.py @@ -283,10 +283,20 @@ def zip_lists( ) ) + def filter_ints(type_: str | None): + def inner(s: str): + if type_ == "int": + return int(s) > 0 and not s.startswith("0") + return True + + return inner + values = { entity: draw( st.lists( - bids_value(entity.match if restrict_patterns else ".*"), + bids_value(entity.match if restrict_patterns else ".*").filter( + filter_ints(entity.type if restrict_patterns else None) + ), min_size=min_values, max_size=max_values, unique=(cull or unique), diff --git a/snakebids/utils/utils.py b/snakebids/utils/utils.py index 268a98e2..cd0774ac 100644 --- a/snakebids/utils/utils.py +++ b/snakebids/utils/utils.py @@ -156,6 +156,17 @@ def wildcard(self) -> str: return self.entity return self.tag + @property + def type(self) -> str | None: + """Get the type of the entity. + + Returns None if type unspecified. + """ + tags = read_bids_tags() + # See note in .before + _def: dict[Any, Any] = {} + return tags.get(self.entity, _def).get("type") + @classmethod def from_tag(cls, tag: str) -> BidsEntity: """Return the entity associated with the given tag, if found.