From 7dd5e53a20c93955118ec365da8a642620349b50 Mon Sep 17 00:00:00 2001 From: Matthias Schabel Date: Sun, 9 Aug 2026 14:30:54 -0700 Subject: [PATCH] fix: don't mutate the source stops in ColorStops.reversed() `self._stops[::-1]` is a view, so rewriting the position column wrote through to the object being reversed: its positions became `1 - p` while its colors stayed put, leaving stops in descending order that the constructor itself rejects. Evaluating the original colormap afterwards gave a wrong ramp, and a second `.reversed()` call disagreed with the first. `__init__` stores arrays uncopied, so the returned object aliased the same buffer. Copying the reversed view first fixes both, and matches `shifted()`, which already copies before rewriting positions. Co-Authored-By: Claude Opus 5 (1M context) Reviewed-By: Codex (gpt-5.6-sol, reasoning effort xhigh) --- src/cmap/_colormap.py | 2 +- tests/test_colormap.py | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/cmap/_colormap.py b/src/cmap/_colormap.py index c20371cbd..4821f2895 100644 --- a/src/cmap/_colormap.py +++ b/src/cmap/_colormap.py @@ -1161,7 +1161,7 @@ def reversed(self) -> ColorStops: rev_lutfunc = partial(self._reverser, lut_func) return type(self)(lut_func=rev_lutfunc) # invert the positions in the stops - rev_stops = self._stops[::-1] + rev_stops = self._stops[::-1].copy() rev_stops[:, 0] = 1 - rev_stops[:, 0] return type(self)(rev_stops, interpolation=self._interpolation) diff --git a/tests/test_colormap.py b/tests/test_colormap.py index d1550136b..62911f808 100644 --- a/tests/test_colormap.py +++ b/tests/test_colormap.py @@ -90,6 +90,15 @@ def test_colorstops() -> None: assert reversed(cmap.color_stops) == ColorStops.parse(["b", "m", "r"]) +def test_colorstops_reversed_does_not_mutate_source() -> None: + stops = ColorStops.parse(["red", "green", "blue"]) + before = np.asarray(stops).copy() + + stops.reversed() + + npt.assert_array_equal(np.asarray(stops), before) + + def test_colormap_copy() -> None: """Test Colormap copy.""" import pickle