diff --git a/pytools/__init__.py b/pytools/__init__.py index a2c167c4d0b5b4c2a34e58a2cb4efce68476bfbd..25de9268f14a0426fe69341964026b223165d701 100644 --- a/pytools/__init__.py +++ b/pytools/__init__.py @@ -2970,8 +2970,9 @@ def to_identifier(s: str) -> str: # {{{ unique -def unique(seq: Sequence[T]) -> Iterator[T]: - """Yield unique elements in *seq*, removing all duplicates. See also +def unique(seq: Iterable[T]) -> Iterator[T]: + """Yield unique elements in *seq*, removing all duplicates. The internal + order of the elements is preserved. See also :func:`itertools.groupby` (which removes consecutive duplicates).""" return iter(dict.fromkeys(seq)) diff --git a/pytools/test/test_pytools.py b/pytools/test/test_pytools.py index 3ca30a4aa84781701c5f09f95d4be54b77082831..9e393a78f5826d0a6822fe8f8159fdcf46a864a5 100644 --- a/pytools/test/test_pytools.py +++ b/pytools/test/test_pytools.py @@ -805,6 +805,12 @@ def test_unique(): assert next(unique([1, 2, 1, 3])) == 1 assert next(unique([]), None) is None + # Also test strings since their ordering would be thrown off by + # set-based 'unique' implementations. + assert list(unique(["A", "B", "A"])) == ["A", "B"] + assert tuple(unique(("A", "B", "A"))) == ("A", "B") + assert next(unique(["A", "B", "A", "C"])) == "A" + # This class must be defined globally to be picklable class SimpleRecord(Record):