You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by jl...@apache.org on 2026/08/06 00:45:14 UTC
(superset) 08/10: fix(reports): guard AUTO currency against sparse-pivot NaN context
This is an automated email from the ASF dual-hosted git repository.
sadpandajoe pushed a commit to branch fix-reports-text-number-formatting
in repository https://gitbox.apache.org/repos/asf/superset.git
commit 7c305e0a9a6536ffa936146f992b09305e9fae65
Author: sadpandajoe <jc...@gmail.com>
AuthorDate: Thu Aug 6 00:38:17 2026 +0000
fix(reports): guard AUTO currency against sparse-pivot NaN context
A pivot with both `groupbyRows` and `groupbyColumns` has empty cross-product
cells. `pivot_table` never runs the currency `union` aggregator for a missing
combination, so it fills those cells with a scalar `NaN` rather than an empty
tuple. That `NaN` reached `resolve_auto_currency`, whose `list(currency_context)`
raised `TypeError: 'float' object is not iterable`. Because the call sits outside
the formatting try/except, it propagated out of the post-processor and failed the
whole report instead of degrading to the raw value like every other formatting
path.
Coerce a non-iterable or `NaN` context to an empty context inside
`resolve_auto_currency` itself, where no caller can bypass it, so AUTO resolution
follows the existing empty-context path (single currency -> that symbol, mixed ->
neutral, empty -> detected fallback).
Co-Authored-By: Claude Opus 4.8 <no...@anthropic.com>
---
superset/utils/number_format.py | 10 +++++++++-
tests/unit_tests/utils/number_format_test.py | 27 +++++++++++++++++++++++++++
2 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/superset/utils/number_format.py b/superset/utils/number_format.py
index 1a15d44da15..8b3fa120591 100644
--- a/superset/utils/number_format.py
+++ b/superset/utils/number_format.py
@@ -117,7 +117,15 @@ def resolve_auto_currency(
return currency
if currency_context is not None:
- context_values = list(currency_context)
+ # A dense pivot cell carries an iterable of currency codes, but a sparse
+ # 2D pivot leaves missing cross-product cells as a scalar ``NaN`` (pandas
+ # never runs the union aggregator for them). Coerce any non-iterable or
+ # NaN context to empty so AUTO resolution follows the empty-context path
+ # instead of raising and taking down the whole report.
+ try:
+ context_values = list(currency_context)
+ except TypeError:
+ context_values = []
normalized_currencies = {
normalized
for value in context_values
diff --git a/tests/unit_tests/utils/number_format_test.py b/tests/unit_tests/utils/number_format_test.py
index 60a6bc7ef34..0a013fdfd54 100644
--- a/tests/unit_tests/utils/number_format_test.py
+++ b/tests/unit_tests/utils/number_format_test.py
@@ -122,6 +122,33 @@ def test_resolve_auto_currency_prefers_cell_context_and_detects_mixed() -> None:
)
+def test_resolve_auto_currency_coerces_non_iterable_context() -> None:
+ """
+ A sparse 2D pivot leaves missing cells as scalar ``NaN`` rather than an
+ empty tuple, so AUTO resolution must treat a non-iterable context as empty
+ instead of raising ``TypeError`` on ``list(context)``.
+ """
+ currency = {"symbol": "AUTO", "symbolPosition": "prefix"}
+
+ # NaN context with fallback enabled behaves like an empty context and uses
+ # the query-wide detected currency.
+ assert resolve_auto_currency(currency, "GBP", currency_context=float("nan")) == {
+ "symbol": "GBP",
+ "symbolPosition": "prefix",
+ }
+
+ # NaN context without fallback keeps AUTO, matching the empty-context path.
+ assert (
+ resolve_auto_currency(
+ currency,
+ "GBP",
+ currency_context=float("nan"),
+ fallback_to_detected=False,
+ )
+ is currency
+ )
+
+
@pytest.mark.parametrize(
"value,expected",
[