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):