From b3ed3f9848bb4c87193e8153aa5329dac1458868 Mon Sep 17 00:00:00 2001 From: cvanelteren Date: Mon, 15 Sep 2025 09:15:01 +0200 Subject: [PATCH] sanitize and add tests --- ultraplot/axes/cartesian.py | 10 +++++ ultraplot/tests/test_axes.py | 82 ++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) diff --git a/ultraplot/axes/cartesian.py b/ultraplot/axes/cartesian.py index f55380502..46685b5df 100644 --- a/ultraplot/axes/cartesian.py +++ b/ultraplot/axes/cartesian.py @@ -20,6 +20,8 @@ from . import plot, shared import matplotlib.axis as maxis +from ..utils import units + __all__ = ["CartesianAxes"] @@ -1391,6 +1393,14 @@ def format( scale = constructor.Scale(scale, **scale_kw) getattr(self, f"set_{s}scale")(scale) + # Explicitly sanitize unit-accepting arguments for this axis + ticklen = units(ticklen) + ticklabelpad = units(ticklabelpad) + labelpad = units(labelpad) + tickwidth = units(tickwidth) + labelsize = units(labelsize) + ticklabelsize = units(ticklabelsize) + # Axis limits self._update_limits(s, min_=min_, max_=max_, lim=lim, reverse=reverse) if margin is not None: diff --git a/ultraplot/tests/test_axes.py b/ultraplot/tests/test_axes.py index fdd021579..a04c2233a 100644 --- a/ultraplot/tests/test_axes.py +++ b/ultraplot/tests/test_axes.py @@ -8,6 +8,88 @@ from ultraplot.internals.warnings import UltraPlotWarning +@pytest.mark.parametrize( + "value", + [ + 5, # int + 5.0, # float + "1em", # string with unit + "10pt", # string with unit + "2px", # string with unit + ], +) +@pytest.mark.parametrize( + "kw", + [ + "xticklen", + "yticklen", + "xticklabelpad", + "yticklabelpad", + "xlabelpad", + "ylabelpad", + "xtickwidth", + "ytickwidth", + "xlabelsize", + "ylabelsize", + "xticklabelsize", + "yticklabelsize", + ], +) +def test_cartesian_format_units_accepts_various_types(kw, value): + """ + Test that CartesianAxes.format() accepts int, float, and string with units + for all relevant padding/size/width/len arguments. + """ + fig, ax = uplt.subplots(proj="cart") + kwargs = {kw: value} + ax.format(**kwargs) + + +@pytest.mark.parametrize( + "kw", + [ + "xticklen", + "yticklen", + "xticklabelpad", + "yticklabelpad", + "xlabelpad", + "ylabelpad", + "xtickwidth", + "ytickwidth", + "xlabelsize", + "ylabelsize", + "xticklabelsize", + "yticklabelsize", + ], +) +def test_cartesian_format_units_invalid_type_raises(kw): + fig, ax = uplt.subplots(proj="cart") + with pytest.raises((TypeError, ValueError)): + ax.format(**{kw: object()}) + + +def test_cartesian_format_all_units_types(): + """ + Test that all relevant unit/padding/size/width/len arguments accept int, float, and string. + """ + fig, ax = uplt.subplots(proj="cart") + kwargs = { + "xticklen": "1em", + "yticklen": 5, + "xticklabelpad": 2.5, + "yticklabelpad": "2px", + "xlabelpad": 3, + "ylabelpad": "10pt", + "xtickwidth": 1.5, + "ytickwidth": "2px", + "xlabelsize": "12pt", + "ylabelsize": 14, + "xticklabelsize": "1em", + "yticklabelsize": 10.0, + } + ax.format(**kwargs) + + def test_axis_access(): # attempt to access the ax object 2d and linearly fig, ax = uplt.subplots(ncols=2, nrows=2)