From 915884dda35bd11418aae6319b30b4cfdb449d2d Mon Sep 17 00:00:00 2001 From: Elizabeth Thompson Date: Fri, 2 Dec 2022 13:40:20 -0800 Subject: [PATCH] convert values to None instead of stringifying --- superset/result_set.py | 6 ++++- tests/unit_tests/result_set_test.py | 41 +++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/superset/result_set.py b/superset/result_set.py index cf57ddc84af54..a6f39f76bf4df 100644 --- a/superset/result_set.py +++ b/superset/result_set.py @@ -67,7 +67,11 @@ def stringify_values(array: np.ndarray) -> np.ndarray: with np.nditer(result, flags=["refs_ok"], op_flags=["readwrite"]) as it: for obj in it: - obj[...] = stringify(obj) + if pd.isna(obj): + # pandas type cannot be converted to string + obj[pd.isna(obj)] = None + else: + obj[...] = stringify(obj) return result diff --git a/tests/unit_tests/result_set_test.py b/tests/unit_tests/result_set_test.py index 48b9576a4ca79..e7371f5c0fa3d 100644 --- a/tests/unit_tests/result_set_test.py +++ b/tests/unit_tests/result_set_test.py @@ -18,6 +18,13 @@ # pylint: disable=import-outside-toplevel, unused-argument +import numpy as np +import pandas as pd +from numpy.core.multiarray import array + +from superset.result_set import stringify_values + + def test_column_names_as_bytes() -> None: """ Test that we can handle column names as bytes. @@ -65,3 +72,37 @@ def test_column_names_as_bytes() -> None: | 1 | 2016-01-27 | 392.444 | 396.843 | 391.782 | 394.972 | 394.972 | 47424400 | """.strip() ) + + +def test_stringify_with_null_integers(): + """ + Test that we can safely handle type errors when an integer column has a null value + """ + + data = [ + ("foo", "bar", pd.NA, None), + ("foo", "bar", pd.NA, True), + ("foo", "bar", pd.NA, None), + ] + numpy_dtype = [ + ("id", "object"), + ("value", "object"), + ("num", "object"), + ("bool", "object"), + ] + + array2 = np.array(data, dtype=numpy_dtype) + column_names = ["id", "value", "num", "bool"] + + result_set = np.array([stringify_values(array2[column]) for column in column_names]) + + expected = np.array( + [ + array(['"foo"', '"foo"', '"foo"'], dtype=object), + array(['"bar"', '"bar"', '"bar"'], dtype=object), + array([None, None, None], dtype=object), + array([None, "true", None], dtype=object), + ] + ) + + assert np.array_equal(result_set, expected)