Skip to content

Commit a9e6068

Browse files
committed
Merge remote-tracking branch 'upstream/main'
2 parents d52e4aa + 1028791 commit a9e6068

File tree

9 files changed

+61
-35
lines changed

9 files changed

+61
-35
lines changed

doc/source/whatsnew/v3.0.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,7 @@ Bug fixes
933933
Categorical
934934
^^^^^^^^^^^
935935
- Bug in :func:`Series.apply` where ``nan`` was ignored for :class:`CategoricalDtype` (:issue:`59938`)
936+
- Bug in :func:`testing.assert_index_equal` raising ``TypeError`` instead of ``AssertionError`` for incomparable ``CategoricalIndex`` when ``check_categorical=True`` and ``exact=False`` (:issue:`61935`)
936937
- Bug in :meth:`Categorical.astype` where ``copy=False`` would still trigger a copy of the codes (:issue:`62000`)
937938
- Bug in :meth:`DataFrame.pivot` and :meth:`DataFrame.set_index` raising an ``ArrowNotImplementedError`` for columns with pyarrow dictionary dtype (:issue:`53051`)
938939
- Bug in :meth:`Series.convert_dtypes` with ``dtype_backend="pyarrow"`` where empty :class:`CategoricalDtype` :class:`Series` raised an error or got converted to ``null[pyarrow]`` (:issue:`59934`)

pandas/_testing/asserters.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,17 @@ def _check_types(left, right, obj: str = "Index") -> None:
325325
# skip exact index checking when `check_categorical` is False
326326
elif check_exact and check_categorical:
327327
if not left.equals(right):
328-
mismatch = left._values != right._values
328+
# _values compare can raise TypeError (non-comparable
329+
# categoricals (GH#61935)
330+
try:
331+
mismatch = left._values != right._values
332+
except TypeError:
333+
raise_assert_detail(
334+
obj,
335+
"types are not comparable (non-matching categorical categories)",
336+
left,
337+
right,
338+
)
329339

330340
if not isinstance(mismatch, np.ndarray):
331341
mismatch = cast("ExtensionArray", mismatch).fillna(True)

pandas/tests/frame/test_arithmetic.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
import numpy as np
1212
import pytest
1313

14+
from pandas.compat._optional import import_optional_dependency
15+
1416
import pandas as pd
1517
from pandas import (
1618
DataFrame,
@@ -24,6 +26,7 @@
2426
_check_mixed_float,
2527
_check_mixed_int,
2628
)
29+
from pandas.util.version import Version
2730

2831

2932
@pytest.fixture
@@ -1114,6 +1117,8 @@ def test_binop_other(self, op, value, dtype, switch_numexpr_min_elements):
11141117
(operator.mod, "complex128"),
11151118
}
11161119

1120+
ne = import_optional_dependency("numexpr", errors="ignore")
1121+
ne_warns_on_op = ne is not None and Version(ne.__version__) < Version("2.13.1")
11171122
if (op, dtype) in invalid:
11181123
warn = None
11191124
if (dtype == "<M8[ns]" and op == operator.add) or (
@@ -1142,7 +1147,11 @@ def test_binop_other(self, op, value, dtype, switch_numexpr_min_elements):
11421147

11431148
elif (op, dtype) in skip:
11441149
if op in [operator.add, operator.mul]:
1145-
if expr.USE_NUMEXPR and switch_numexpr_min_elements == 0:
1150+
if (
1151+
expr.USE_NUMEXPR
1152+
and switch_numexpr_min_elements == 0
1153+
and ne_warns_on_op
1154+
):
11461155
warn = UserWarning
11471156
else:
11481157
warn = None

pandas/tests/io/excel/test_style.py

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import contextlib
2-
import time
32
import uuid
43

54
import numpy as np
@@ -324,18 +323,10 @@ def test_styler_to_s3(s3_bucket_public, s3so):
324323
target_file = f"{uuid.uuid4()}.xlsx"
325324
df = DataFrame({"x": [1, 2, 3], "y": [2, 4, 6]})
326325
styler = df.style.set_sticky(axis="index")
327-
styler.to_excel(f"s3://{mock_bucket_name}/{target_file}", storage_options=s3so)
328-
timeout = 5
329-
while True:
330-
if target_file in (obj.key for obj in s3_bucket_public.objects.all()):
331-
break
332-
time.sleep(0.1)
333-
timeout -= 0.1
334-
assert timeout > 0, "Timed out waiting for file to appear on moto"
335-
result = read_excel(
336-
f"s3://{mock_bucket_name}/{target_file}", index_col=0, storage_options=s3so
337-
)
338-
tm.assert_frame_equal(result, df)
326+
uri = f"s3://{mock_bucket_name}/{target_file}"
327+
styler.to_excel(uri, storage_options=s3so)
328+
result = read_excel(uri, index_col=0, storage_options=s3so)
329+
tm.assert_frame_equal(result, df)
339330

340331

341332
@pytest.mark.parametrize("merge_cells", [True, False, "columns"])

pandas/tests/io/json/test_pandas.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import json
88
import os
99
import sys
10-
import time
1110
import uuid
1211

1312
import numpy as np
@@ -2016,14 +2015,10 @@ def test_to_s3(self, s3_bucket_public, s3so):
20162015
mock_bucket_name = s3_bucket_public.name
20172016
target_file = f"{uuid.uuid4()}.json"
20182017
df = DataFrame({"x": [1, 2, 3], "y": [2, 4, 6]})
2019-
df.to_json(f"s3://{mock_bucket_name}/{target_file}", storage_options=s3so)
2020-
timeout = 5
2021-
while True:
2022-
if target_file in (obj.key for obj in s3_bucket_public.objects.all()):
2023-
break
2024-
time.sleep(0.1)
2025-
timeout -= 0.1
2026-
assert timeout > 0, "Timed out waiting for file to appear on moto"
2018+
uri = f"s3://{mock_bucket_name}/{target_file}"
2019+
df.to_json(uri, storage_options=s3so)
2020+
result = read_json(uri, storage_options=s3so)
2021+
tm.assert_frame_equal(result, df)
20272022

20282023
def test_json_pandas_nulls(self, nulls_fixture):
20292024
# GH 31615

pandas/tests/io/test_compression.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import sys
66
import tarfile
77
import textwrap
8-
import time
98
import zipfile
109

1110
import numpy as np
@@ -193,7 +192,6 @@ def test_gzip_reproducibility_file_name(temp_file):
193192
# test for filename
194193
path = temp_file
195194
df.to_csv(path, compression=compression_options)
196-
time.sleep(0.1)
197195
output = path.read_bytes()
198196
df.to_csv(path, compression=compression_options)
199197
assert output == path.read_bytes()
@@ -216,7 +214,6 @@ def test_gzip_reproducibility_file_object():
216214
buffer = io.BytesIO()
217215
df.to_csv(buffer, compression=compression_options, mode="wb")
218216
output = buffer.getvalue()
219-
time.sleep(0.1)
220217
buffer = io.BytesIO()
221218
df.to_csv(buffer, compression=compression_options, mode="wb")
222219
assert output == buffer.getvalue()

pandas/tests/series/test_arithmetic.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import pytest
1111

1212
from pandas._libs import lib
13+
from pandas.compat._optional import import_optional_dependency
1314

1415
import pandas as pd
1516
from pandas import (
@@ -25,7 +26,7 @@
2526
import pandas._testing as tm
2627
from pandas.core import ops
2728
from pandas.core.computation import expressions as expr
28-
from pandas.core.computation.check import NUMEXPR_INSTALLED
29+
from pandas.util.version import Version
2930

3031

3132
@pytest.fixture(autouse=True, params=[0, 1000000], ids=["numexpr", "python"])
@@ -348,9 +349,12 @@ def test_add_list_to_masked_array(self, val, dtype):
348349

349350
def test_add_list_to_masked_array_boolean(self, request):
350351
# GH#22962
352+
ne = import_optional_dependency("numexpr", errors="ignore")
351353
warning = (
352354
UserWarning
353-
if request.node.callspec.id == "numexpr" and NUMEXPR_INSTALLED
355+
if request.node.callspec.id == "numexpr"
356+
and ne
357+
and Version(ne.__version__) < Version("2.13.1")
354358
else None
355359
)
356360
ser = Series([True, None, False], dtype="boolean")

pandas/tests/test_expressions.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
44
import numpy as np
55
import pytest
66

7+
from pandas.compat._optional import import_optional_dependency
8+
79
from pandas import option_context
810
import pandas._testing as tm
911
from pandas.core.api import DataFrame
1012
from pandas.core.computation import expressions as expr
13+
from pandas.util.version import Version
1114

1215

1316
@pytest.fixture
@@ -340,35 +343,43 @@ def test_bool_ops_warn_on_arithmetic(self, op_str, opname, monkeypatch):
340343
return
341344

342345
msg = "operator is not supported by numexpr"
346+
ne = import_optional_dependency("numexpr", errors="ignore")
347+
warning = (
348+
UserWarning
349+
if ne
350+
and op_str in {"+", "*"}
351+
and Version(ne.__version__) < Version("2.13.1")
352+
else None
353+
)
343354
with monkeypatch.context() as m:
344355
m.setattr(expr, "_MIN_ELEMENTS", 5)
345356
with option_context("compute.use_numexpr", True):
346-
with tm.assert_produces_warning(UserWarning, match=msg):
357+
with tm.assert_produces_warning(warning, match=msg):
347358
r = f(df, df)
348359
e = fe(df, df)
349360
tm.assert_frame_equal(r, e)
350361

351-
with tm.assert_produces_warning(UserWarning, match=msg):
362+
with tm.assert_produces_warning(warning, match=msg):
352363
r = f(df.a, df.b)
353364
e = fe(df.a, df.b)
354365
tm.assert_series_equal(r, e)
355366

356-
with tm.assert_produces_warning(UserWarning, match=msg):
367+
with tm.assert_produces_warning(warning, match=msg):
357368
r = f(df.a, True)
358369
e = fe(df.a, True)
359370
tm.assert_series_equal(r, e)
360371

361-
with tm.assert_produces_warning(UserWarning, match=msg):
372+
with tm.assert_produces_warning(warning, match=msg):
362373
r = f(False, df.a)
363374
e = fe(False, df.a)
364375
tm.assert_series_equal(r, e)
365376

366-
with tm.assert_produces_warning(UserWarning, match=msg):
377+
with tm.assert_produces_warning(warning, match=msg):
367378
r = f(False, df)
368379
e = fe(False, df)
369380
tm.assert_frame_equal(r, e)
370381

371-
with tm.assert_produces_warning(UserWarning, match=msg):
382+
with tm.assert_produces_warning(warning, match=msg):
372383
r = f(df, True)
373384
e = fe(df, True)
374385
tm.assert_frame_equal(r, e)

pandas/tests/util/test_assert_index_equal.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,3 +317,11 @@ def test_assert_multi_index_dtype_check_categorical(check_categorical):
317317
tm.assert_index_equal(idx1, idx2, check_categorical=check_categorical)
318318
else:
319319
tm.assert_index_equal(idx1, idx2, check_categorical=check_categorical)
320+
321+
322+
def test_assert_index_equal_categorical_incomparable_categories():
323+
# GH#61935
324+
left = Index([1, 2, 3], name="a", dtype="category")
325+
right = Index([1, 2, 6], name="a", dtype="category")
326+
with pytest.raises(AssertionError, match="types are not comparable"):
327+
tm.assert_index_equal(left, right, check_categorical=True, exact=False)

0 commit comments

Comments
 (0)