Skip to content

Commit

Permalink
Preserve order of entries in expand method
Browse files Browse the repository at this point in the history
.expand() in all three Expandables was using `set()` to deduplicate
paths following expansion. This was altering the order of the paths,
preventing predicatable expansion

This fix uses `dict.fromkeys` to deduplicate while preserving order

Resolves #346
  • Loading branch information
pvandyken committed Dec 11, 2023
1 parent 332ee47 commit dd2ce68
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 5 deletions.
5 changes: 3 additions & 2 deletions snakebids/core/datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def expand(
allow_missing=allow_missing
if isinstance(allow_missing, bool)
else list(itx.always_iterable(allow_missing)),
**{self.entity: list(set(self._data))},
**{self.entity: list(dict.fromkeys(self._data))},
**{
wildcard: list(itx.always_iterable(v))
for wildcard, v in wildcards.items()
Expand Down Expand Up @@ -389,7 +389,8 @@ def sequencify(item: bool | str | Iterable[str]) -> bool | list[str]:

allow_missing_seq = sequencify(allow_missing)
inner_expand = list(
set(
# order preserving deduplication
dict.fromkeys(
sn_expand(
list(itx.always_iterable(paths)),
zip,
Expand Down
13 changes: 13 additions & 0 deletions snakebids/tests/test_datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,19 @@ def test_expand_deduplicates_paths(self, component: Expandable):
paths = component.expand(path_tpl)
assert len(paths) == len(set(paths))

@given(
component=sb_st.expandables(
restrict_patterns=True,
path_safe=True,
unique=True,
)
)
def test_expand_preserves_entry_order(self, component: Expandable):
path_tpl = bids(**get_wildcard_dict(component.zip_lists))
paths = component.expand(path_tpl)
for path, entity_vals in zip(paths, zip(*component.zip_lists.values())):
assert bids(**dict(zip(component.zip_lists.keys(), entity_vals))) == path


class TestBidsComponentExpand:
"""
Expand Down
9 changes: 6 additions & 3 deletions typings/bids/layout/utils.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
This type stub file was generated by pyright.
"""

"""Miscellaneous layout-related utilities."""
from typing import Sequence

class BIDSMetadata(dict):
"""Metadata dictionary that reports the associated file on lookup failures."""
Expand Down Expand Up @@ -66,8 +66,11 @@ class PaddedInt(int):
def __hash__(self) -> int: ...

def parse_file_entities(
filename, entities=..., config=..., include_unmatched=...
): # -> dict[Unknown, Unknown]:
filename: str,
entities: Sequence[str] = ...,
config: str = ...,
include_unmatched: bool = ...,
) -> dict[str, str]:
"""Parse the passed filename for entity/value pairs.
Parameters
Expand Down

0 comments on commit dd2ce68

Please sign in to comment.