From 1268cebae53815b961e575bc9c63d54958d22875 Mon Sep 17 00:00:00 2001 From: theOehrly <23384863+theOehrly@users.noreply.github.com> Date: Sun, 8 Oct 2023 18:41:16 +0200 Subject: [PATCH 1/3] FIX: handle potential TypeError when determining variable type --- seaborn/_base.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/seaborn/_base.py b/seaborn/_base.py index e312923f5d..b659300078 100644 --- a/seaborn/_base.py +++ b/seaborn/_base.py @@ -1520,8 +1520,13 @@ def variable_type(vector, boolean_type="numeric"): warnings.simplefilter( action='ignore', category=(FutureWarning, DeprecationWarning) ) - if np.isin(vector, [0, 1]).all(): - return VariableType(boolean_type) + try: + if np.isin(vector, [0, 1]).all(): + return VariableType(boolean_type) + except TypeError: + # .isin comparison is not guaranteed to be possible under NumPy + # casting rules, depending on the (unknown) dtype of 'vector' + pass # Defer to positive pandas tests if pd.api.types.is_numeric_dtype(vector): From 91828baf25f1c343674ae758b36dedfdc584eb9f Mon Sep 17 00:00:00 2001 From: Michael Waskom Date: Sat, 4 Nov 2023 12:56:43 -0400 Subject: [PATCH 2/3] Handle edge case in duplicated _core code --- seaborn/_core/rules.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/seaborn/_core/rules.py b/seaborn/_core/rules.py index 5057221f65..de6c651d97 100644 --- a/seaborn/_core/rules.py +++ b/seaborn/_core/rules.py @@ -97,7 +97,12 @@ def variable_type( boolean_dtypes = ["bool"] boolean_vector = vector.dtype in boolean_dtypes else: - boolean_vector = bool(np.isin(vector, [0, 1]).all()) + try: + boolean_vector = bool(np.isin(vector, [0, 1]).all()) + except TypeError: + # .isin comparison is not guaranteed to be possible under NumPy + # casting rules, depending on the (unknown) dtype of 'vector' + boolean_vector = False if boolean_vector: return VarType(boolean_type) From 3b6e1a7faabff0c184846b9caeadf17252cac610 Mon Sep 17 00:00:00 2001 From: Michael Waskom Date: Sat, 4 Nov 2023 12:56:48 -0400 Subject: [PATCH 3/3] Add tests --- tests/_core/test_rules.py | 8 ++++++++ tests/test_base.py | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/tests/_core/test_rules.py b/tests/_core/test_rules.py index 714d5ead5c..161d2af292 100644 --- a/tests/_core/test_rules.py +++ b/tests/_core/test_rules.py @@ -52,6 +52,11 @@ def test_variable_type(): assert variable_type(s, boolean_type="categorical") == "categorical" assert variable_type(s, boolean_type="boolean") == "boolean" + # This should arguably be datmetime, but we don't currently handle it correctly + # Test is mainly asserting that this doesn't fail on the boolean check. + s = pd.timedelta_range(1, periods=3, freq="D").to_series() + assert variable_type(s) == "categorical" + s_cat = s.astype("category") assert variable_type(s_cat, boolean_type="categorical") == "categorical" assert variable_type(s_cat, boolean_type="numeric") == "categorical" @@ -61,6 +66,9 @@ def test_variable_type(): assert variable_type(s, boolean_type="boolean") == "boolean" assert variable_type(s, boolean_type="boolean", strict_boolean=True) == "numeric" + s = pd.Series([1, 0, 0]) + assert variable_type(s, boolean_type="boolean") == "boolean" + s = pd.Series([pd.Timestamp(1), pd.Timestamp(2)]) assert variable_type(s) == "datetime" assert variable_type(s.astype(object)) == "datetime" diff --git a/tests/test_base.py b/tests/test_base.py index eea967cf93..4dfb3edfb4 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -1508,6 +1508,11 @@ def test_variable_type(self): assert variable_type(s.to_numpy()) == "categorical" assert variable_type(s.to_list()) == "categorical" + # This should arguably be datmetime, but we don't currently handle it correctly + # Test is mainly asserting that this doesn't fail on the boolean check. + s = pd.timedelta_range(1, periods=3, freq="D").to_series() + assert variable_type(s) == "categorical" + s = pd.Series([True, False, False]) assert variable_type(s) == "numeric" assert variable_type(s, boolean_type="categorical") == "categorical"