From 8575d962c390bc0f3eb851038c56e04fae489ae5 Mon Sep 17 00:00:00 2001 From: cvanelteren Date: Thu, 14 Aug 2025 18:09:59 +0200 Subject: [PATCH 1/4] fix issue where double decorator does not parse function name --- ultraplot/internals/inputs.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/ultraplot/internals/inputs.py b/ultraplot/internals/inputs.py index f35df5c3..25bcbf6e 100644 --- a/ultraplot/internals/inputs.py +++ b/ultraplot/internals/inputs.py @@ -282,16 +282,22 @@ def _parse_triangulation_with_preprocess(*keys, keywords=None, allow_extra=True) """ def _decorator(func): - @_preprocess_or_redirect(*keys, keywords=keywords, allow_extra=allow_extra) - def wrapper(self, *args, **kwargs): - # Parse triangulation inputs after preprocessing + def triangulation_wrapper(self, *args, **kwargs): triangulation, z, remaining_args, updated_kwargs = ( _parse_triangulation_inputs(*args, **kwargs) ) - # Call the original function with parsed inputs return func(self, triangulation, z, *remaining_args, **updated_kwargs) - return wrapper + # Manually set the name to the original function's name + triangulation_wrapper.__name__ = func.__name__ + + final_wrapper = _preprocess_or_redirect( + *keys, keywords=keywords, allow_extra=allow_extra + )(triangulation_wrapper) + + # Finally make sure all other metadata is correct + functools.update_wrapper(final_wrapper, func) + return final_wrapper return _decorator From 9484c00271ff78e22d671d31152e4d724558e0c4 Mon Sep 17 00:00:00 2001 From: cvanelteren Date: Thu, 14 Aug 2025 18:37:25 +0200 Subject: [PATCH 2/4] add unittest --- ultraplot/tests/test_inputs.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/ultraplot/tests/test_inputs.py b/ultraplot/tests/test_inputs.py index 8e257f50..c314fbcf 100644 --- a/ultraplot/tests/test_inputs.py +++ b/ultraplot/tests/test_inputs.py @@ -1,4 +1,5 @@ import ultraplot as uplt, pytest, numpy as np +from unittest.mock import patch, Mock @pytest.mark.parametrize( @@ -16,3 +17,19 @@ def test_to_numpy_array(data, dtype): """ arr = uplt.internals.inputs._to_numpy_array(data) assert arr.dtype == dtype, f"Expected dtype {dtype}, got {arr.dtype}" + + +def test_name_preserved_and_args_processed(): + """ + Check if the name is preserved across nested decoration + for tri-related functions + """ + parser_mock = Mock(return_value=("triang", "zval", None, None)) + + def tripcolor(self, tri, z, extra=None, kw=None): + return "ok" + + decorated = uplt.internals.inputs._parse_triangulation_with_preprocess()(tripcolor) + + # Test that the decorator preserves the function name + assert decorated.__name__ == "tripcolor" From 03fd4d0266ac80de966db6e2ac6592f36d289e07 Mon Sep 17 00:00:00 2001 From: cvanelteren Date: Thu, 14 Aug 2025 18:38:24 +0200 Subject: [PATCH 3/4] fixup imports --- ultraplot/tests/test_inputs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ultraplot/tests/test_inputs.py b/ultraplot/tests/test_inputs.py index c314fbcf..00ad9be9 100644 --- a/ultraplot/tests/test_inputs.py +++ b/ultraplot/tests/test_inputs.py @@ -1,5 +1,5 @@ import ultraplot as uplt, pytest, numpy as np -from unittest.mock import patch, Mock +from unittest.mock import Mock @pytest.mark.parametrize( From e100f470aa34c6fe0d0d3072d50736b9c6e4c34c Mon Sep 17 00:00:00 2001 From: cvanelteren Date: Sat, 16 Aug 2025 02:20:42 +0200 Subject: [PATCH 4/4] remove double preprocessing --- ultraplot/axes/plot.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/ultraplot/axes/plot.py b/ultraplot/axes/plot.py index 1cc70a1b..3f29d190 100644 --- a/ultraplot/axes/plot.py +++ b/ultraplot/axes/plot.py @@ -5266,7 +5266,6 @@ def streamplot(self, x, y, u, v, c, **kwargs): return m @inputs._parse_triangulation_with_preprocess("x", "y", "z", keywords=["triangles"]) - @inputs._preprocess_or_redirect("x", "y", "z") @docstring._concatenate_inherited @docstring._snippet_manager def tricontour(self, *args, **kwargs): @@ -5308,7 +5307,6 @@ def tricontour(self, *args, **kwargs): return m @inputs._parse_triangulation_with_preprocess("x", "y", "z", keywords=["triangles"]) - @inputs._preprocess_or_redirect("x", "y", "z") @docstring._concatenate_inherited @docstring._snippet_manager def tricontourf(self, *args, **kwargs):