Repository navigation
Fix validate_colors and convert_colors_to_same_type modifying the colors passed to them - #5836
Conversation
…nput Both helpers rewrote the list passed to them in place, which also changed DEFAULT_PLOTLY_COLORS (e.g. after create_trisurf without a colormap) and built-in sequences such as plotly.colors.sequential.Inferno. Copy the list before converting it.
|
Thanks for the PR! Can you please create an issue that describes the problem and how you encountered this issue in your day-to-day usage of plotly.py? |
|
Thanks for taking a look! I opened #5846 with a description and a short reproduction, and linked it from this PR. To be transparent: I came across this while reading the color utilities rather than hitting it in a project. The most visible effect is that a built-in sequence such as |
camdecoster
left a comment
There was a problem hiding this comment.
Thanks for the fix! Could you do a pass to see if there are any other similar mutations that need to be addressed? It looks like convert_dict_colors_to_same_type would need the same update (and maybe others).
| - Fix `convert_dash` mapping dotted lines (`linestyle=':'`) to invalid `'circle'` in Plotly, correctly converting them to `'dot'` and preserving custom dash patterns as pixel lists, [[#5719](https://github.com/plotly/plotly.py/pull/5719)] with thanks to @robertoffmoura for the contribution! | ||
| - Fix `px.sunburst`, `px.treemap` and `px.icicle` listing sectors in a different order on every run when `path` is used with a Polars DataFrame; sectors now follow their order of first appearance for all dataframe backends [[#5766](https://github.com/plotly/plotly.py/pull/5766)], with thanks to @Irahan2 for the contribution! | ||
| - Fix `mpl_to_plotly` conversion of matplotlib contour lines and line collections: close contour rings ending with `Z` codes, support dash styles, convert date x-axes, separate disjoint subpaths with `None` separators, hide line collection traces from the legend by default, and group consecutive same-style lines into single traces [[#5770](https://github.com/plotly/plotly.py/pull/5770)], with thanks to @robertoffmoura for the contribution! | ||
| - Fix `plotly.colors.validate_colors` and `plotly.colors.convert_colors_to_same_type` modifying the list of colors passed to them in place, which also changed `plotly.colors.DEFAULT_PLOTLY_COLORS` (for example after calling `create_trisurf` without a `colormap`) and built-in color sequences such as `plotly.colors.sequential.Inferno` [[#5836](https://github.com/plotly/plotly.py/pull/5836)], with thanks to @Enesuygurs for the contribution! |
There was a problem hiding this comment.
| - Fix `plotly.colors.validate_colors` and `plotly.colors.convert_colors_to_same_type` modifying the list of colors passed to them in place, which also changed `plotly.colors.DEFAULT_PLOTLY_COLORS` (for example after calling `create_trisurf` without a `colormap`) and built-in color sequences such as `plotly.colors.sequential.Inferno` [[#5836](https://github.com/plotly/plotly.py/pull/5836)], with thanks to @Enesuygurs for the contribution! | |
| - Fix color utilities mutating the list of colors passed to them [[#5836](https://github.com/plotly/plotly.py/pull/5836)], with thanks to @Enesuygurs for the contribution! |
…t_colorscale_to_rgb modifying their input
|
Thanks for the review! I went through every function in |
…ating-input # Conflicts: # CHANGELOG.md
camdecoster
left a comment
There was a problem hiding this comment.
Thanks for getting this fixed!
Link to issue
Fixes #5846
Description of change
plotly.colors.validate_colorsandplotly.colors.convert_colors_to_same_typerewrite the list they are given in place.validate_colors: when called withNone, it usesDEFAULT_PLOTLY_COLORSitself, so the module-level default colors become float tuples for the rest of the session.create_trisurfdoes this whenevercolormapis left asNone. When a user passes acolormaplist instead, that list is converted to tuples.convert_colors_to_same_type: it aliases a list argument the same way, so passing a built-in sequence rewrites it:Both functions now copy the list before converting it. The return values are unchanged.
Testing strategy
I added
test_color_conversions_do_not_modify_input. It checks thatDEFAULT_PLOTLY_COLORSand a user list are unchanged after calling both helpers. It fails onmainand passes with this change.Locally,
tests/test_core/test_colors,tests/test_plotly_utilsandtests/test_optional/test_figure_factorypass. The exception is thecreate_ternary_contourtests: they need scikit-image, which isn't installed here, and they fail the same way onmain.ruff format --check .passes.Additional information (optional)
This also fixes cross-test pollution in the existing suite.
test_sample_colorscalecallsconvert_colors_to_same_type(colors.sequential.Inferno, ...), which rewroteInferno. As a result, runningtests/test_core/test_colorsbeforetests/test_plotly_utilsmadetest_colorscale_validator.py::test_acceptance_named[Inferno_r]fail onmain. It passes with this change.Guidelines