done
This commit is contained in:
		
							
								
								
									
										26
									
								
								lib/python3.11/site-packages/pandas/tests/util/conftest.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								lib/python3.11/site-packages/pandas/tests/util/conftest.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| import pytest | ||||
|  | ||||
|  | ||||
| @pytest.fixture(params=[True, False]) | ||||
| def check_dtype(request): | ||||
|     return request.param | ||||
|  | ||||
|  | ||||
| @pytest.fixture(params=[True, False]) | ||||
| def check_exact(request): | ||||
|     return request.param | ||||
|  | ||||
|  | ||||
| @pytest.fixture(params=[True, False]) | ||||
| def check_index_type(request): | ||||
|     return request.param | ||||
|  | ||||
|  | ||||
| @pytest.fixture(params=[0.5e-3, 0.5e-5]) | ||||
| def rtol(request): | ||||
|     return request.param | ||||
|  | ||||
|  | ||||
| @pytest.fixture(params=[True, False]) | ||||
| def check_categorical(request): | ||||
|     return request.param | ||||
| @ -0,0 +1,586 @@ | ||||
| import numpy as np | ||||
| import pytest | ||||
|  | ||||
| from pandas import ( | ||||
|     NA, | ||||
|     DataFrame, | ||||
|     Index, | ||||
|     NaT, | ||||
|     Series, | ||||
|     Timestamp, | ||||
| ) | ||||
| import pandas._testing as tm | ||||
|  | ||||
|  | ||||
| def _assert_almost_equal_both(a, b, **kwargs): | ||||
|     """ | ||||
|     Check that two objects are approximately equal. | ||||
|  | ||||
|     This check is performed commutatively. | ||||
|  | ||||
|     Parameters | ||||
|     ---------- | ||||
|     a : object | ||||
|         The first object to compare. | ||||
|     b : object | ||||
|         The second object to compare. | ||||
|     **kwargs | ||||
|         The arguments passed to `tm.assert_almost_equal`. | ||||
|     """ | ||||
|     tm.assert_almost_equal(a, b, **kwargs) | ||||
|     tm.assert_almost_equal(b, a, **kwargs) | ||||
|  | ||||
|  | ||||
| def _assert_not_almost_equal(a, b, **kwargs): | ||||
|     """ | ||||
|     Check that two objects are not approximately equal. | ||||
|  | ||||
|     Parameters | ||||
|     ---------- | ||||
|     a : object | ||||
|         The first object to compare. | ||||
|     b : object | ||||
|         The second object to compare. | ||||
|     **kwargs | ||||
|         The arguments passed to `tm.assert_almost_equal`. | ||||
|     """ | ||||
|     try: | ||||
|         tm.assert_almost_equal(a, b, **kwargs) | ||||
|         msg = f"{a} and {b} were approximately equal when they shouldn't have been" | ||||
|         pytest.fail(reason=msg) | ||||
|     except AssertionError: | ||||
|         pass | ||||
|  | ||||
|  | ||||
| def _assert_not_almost_equal_both(a, b, **kwargs): | ||||
|     """ | ||||
|     Check that two objects are not approximately equal. | ||||
|  | ||||
|     This check is performed commutatively. | ||||
|  | ||||
|     Parameters | ||||
|     ---------- | ||||
|     a : object | ||||
|         The first object to compare. | ||||
|     b : object | ||||
|         The second object to compare. | ||||
|     **kwargs | ||||
|         The arguments passed to `tm.assert_almost_equal`. | ||||
|     """ | ||||
|     _assert_not_almost_equal(a, b, **kwargs) | ||||
|     _assert_not_almost_equal(b, a, **kwargs) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "a,b", | ||||
|     [ | ||||
|         (1.1, 1.1), | ||||
|         (1.1, 1.100001), | ||||
|         (np.int16(1), 1.000001), | ||||
|         (np.float64(1.1), 1.1), | ||||
|         (np.uint32(5), 5), | ||||
|     ], | ||||
| ) | ||||
| def test_assert_almost_equal_numbers(a, b): | ||||
|     _assert_almost_equal_both(a, b) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "a,b", | ||||
|     [ | ||||
|         (1.1, 1), | ||||
|         (1.1, True), | ||||
|         (1, 2), | ||||
|         (1.0001, np.int16(1)), | ||||
|         # The following two examples are not "almost equal" due to tol. | ||||
|         (0.1, 0.1001), | ||||
|         (0.0011, 0.0012), | ||||
|     ], | ||||
| ) | ||||
| def test_assert_not_almost_equal_numbers(a, b): | ||||
|     _assert_not_almost_equal_both(a, b) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "a,b", | ||||
|     [ | ||||
|         (1.1, 1.1), | ||||
|         (1.1, 1.100001), | ||||
|         (1.1, 1.1001), | ||||
|         (0.000001, 0.000005), | ||||
|         (1000.0, 1000.0005), | ||||
|         # Testing this example, as per #13357 | ||||
|         (0.000011, 0.000012), | ||||
|     ], | ||||
| ) | ||||
| def test_assert_almost_equal_numbers_atol(a, b): | ||||
|     # Equivalent to the deprecated check_less_precise=True, enforced in 2.0 | ||||
|     _assert_almost_equal_both(a, b, rtol=0.5e-3, atol=0.5e-3) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("a,b", [(1.1, 1.11), (0.1, 0.101), (0.000011, 0.001012)]) | ||||
| def test_assert_not_almost_equal_numbers_atol(a, b): | ||||
|     _assert_not_almost_equal_both(a, b, atol=1e-3) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "a,b", | ||||
|     [ | ||||
|         (1.1, 1.1), | ||||
|         (1.1, 1.100001), | ||||
|         (1.1, 1.1001), | ||||
|         (1000.0, 1000.0005), | ||||
|         (1.1, 1.11), | ||||
|         (0.1, 0.101), | ||||
|     ], | ||||
| ) | ||||
| def test_assert_almost_equal_numbers_rtol(a, b): | ||||
|     _assert_almost_equal_both(a, b, rtol=0.05) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("a,b", [(0.000011, 0.000012), (0.000001, 0.000005)]) | ||||
| def test_assert_not_almost_equal_numbers_rtol(a, b): | ||||
|     _assert_not_almost_equal_both(a, b, rtol=0.05) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "a,b,rtol", | ||||
|     [ | ||||
|         (1.00001, 1.00005, 0.001), | ||||
|         (-0.908356 + 0.2j, -0.908358 + 0.2j, 1e-3), | ||||
|         (0.1 + 1.009j, 0.1 + 1.006j, 0.1), | ||||
|         (0.1001 + 2.0j, 0.1 + 2.001j, 0.01), | ||||
|     ], | ||||
| ) | ||||
| def test_assert_almost_equal_complex_numbers(a, b, rtol): | ||||
|     _assert_almost_equal_both(a, b, rtol=rtol) | ||||
|     _assert_almost_equal_both(np.complex64(a), np.complex64(b), rtol=rtol) | ||||
|     _assert_almost_equal_both(np.complex128(a), np.complex128(b), rtol=rtol) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "a,b,rtol", | ||||
|     [ | ||||
|         (0.58310768, 0.58330768, 1e-7), | ||||
|         (-0.908 + 0.2j, -0.978 + 0.2j, 0.001), | ||||
|         (0.1 + 1j, 0.1 + 2j, 0.01), | ||||
|         (-0.132 + 1.001j, -0.132 + 1.005j, 1e-5), | ||||
|         (0.58310768j, 0.58330768j, 1e-9), | ||||
|     ], | ||||
| ) | ||||
| def test_assert_not_almost_equal_complex_numbers(a, b, rtol): | ||||
|     _assert_not_almost_equal_both(a, b, rtol=rtol) | ||||
|     _assert_not_almost_equal_both(np.complex64(a), np.complex64(b), rtol=rtol) | ||||
|     _assert_not_almost_equal_both(np.complex128(a), np.complex128(b), rtol=rtol) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("a,b", [(0, 0), (0, 0.0), (0, np.float64(0)), (0.00000001, 0)]) | ||||
| def test_assert_almost_equal_numbers_with_zeros(a, b): | ||||
|     _assert_almost_equal_both(a, b) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("a,b", [(0.001, 0), (1, 0)]) | ||||
| def test_assert_not_almost_equal_numbers_with_zeros(a, b): | ||||
|     _assert_not_almost_equal_both(a, b) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("a,b", [(1, "abc"), (1, [1]), (1, object())]) | ||||
| def test_assert_not_almost_equal_numbers_with_mixed(a, b): | ||||
|     _assert_not_almost_equal_both(a, b) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "left_dtype", ["M8[ns]", "m8[ns]", "float64", "int64", "object"] | ||||
| ) | ||||
| @pytest.mark.parametrize( | ||||
|     "right_dtype", ["M8[ns]", "m8[ns]", "float64", "int64", "object"] | ||||
| ) | ||||
| def test_assert_almost_equal_edge_case_ndarrays(left_dtype, right_dtype): | ||||
|     # Empty compare. | ||||
|     _assert_almost_equal_both( | ||||
|         np.array([], dtype=left_dtype), | ||||
|         np.array([], dtype=right_dtype), | ||||
|         check_dtype=False, | ||||
|     ) | ||||
|  | ||||
|  | ||||
| def test_assert_almost_equal_sets(): | ||||
|     # GH#51727 | ||||
|     _assert_almost_equal_both({1, 2, 3}, {1, 2, 3}) | ||||
|  | ||||
|  | ||||
| def test_assert_almost_not_equal_sets(): | ||||
|     # GH#51727 | ||||
|     msg = r"{1, 2, 3} != {1, 2, 4}" | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         _assert_almost_equal_both({1, 2, 3}, {1, 2, 4}) | ||||
|  | ||||
|  | ||||
| def test_assert_almost_equal_dicts(): | ||||
|     _assert_almost_equal_both({"a": 1, "b": 2}, {"a": 1, "b": 2}) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "a,b", | ||||
|     [ | ||||
|         ({"a": 1, "b": 2}, {"a": 1, "b": 3}), | ||||
|         ({"a": 1, "b": 2}, {"a": 1, "b": 2, "c": 3}), | ||||
|         ({"a": 1}, 1), | ||||
|         ({"a": 1}, "abc"), | ||||
|         ({"a": 1}, [1]), | ||||
|     ], | ||||
| ) | ||||
| def test_assert_not_almost_equal_dicts(a, b): | ||||
|     _assert_not_almost_equal_both(a, b) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("val", [1, 2]) | ||||
| def test_assert_almost_equal_dict_like_object(val): | ||||
|     dict_val = 1 | ||||
|     real_dict = {"a": val} | ||||
|  | ||||
|     class DictLikeObj: | ||||
|         def keys(self): | ||||
|             return ("a",) | ||||
|  | ||||
|         def __getitem__(self, item): | ||||
|             if item == "a": | ||||
|                 return dict_val | ||||
|  | ||||
|     func = ( | ||||
|         _assert_almost_equal_both if val == dict_val else _assert_not_almost_equal_both | ||||
|     ) | ||||
|     func(real_dict, DictLikeObj(), check_dtype=False) | ||||
|  | ||||
|  | ||||
| def test_assert_almost_equal_strings(): | ||||
|     _assert_almost_equal_both("abc", "abc") | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "a,b", [("abc", "abcd"), ("abc", "abd"), ("abc", 1), ("abc", [1])] | ||||
| ) | ||||
| def test_assert_not_almost_equal_strings(a, b): | ||||
|     _assert_not_almost_equal_both(a, b) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "a,b", [([1, 2, 3], [1, 2, 3]), (np.array([1, 2, 3]), np.array([1, 2, 3]))] | ||||
| ) | ||||
| def test_assert_almost_equal_iterables(a, b): | ||||
|     _assert_almost_equal_both(a, b) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "a,b", | ||||
|     [ | ||||
|         # Class is different. | ||||
|         (np.array([1, 2, 3]), [1, 2, 3]), | ||||
|         # Dtype is different. | ||||
|         (np.array([1, 2, 3]), np.array([1.0, 2.0, 3.0])), | ||||
|         # Can't compare generators. | ||||
|         (iter([1, 2, 3]), [1, 2, 3]), | ||||
|         ([1, 2, 3], [1, 2, 4]), | ||||
|         ([1, 2, 3], [1, 2, 3, 4]), | ||||
|         ([1, 2, 3], 1), | ||||
|     ], | ||||
| ) | ||||
| def test_assert_not_almost_equal_iterables(a, b): | ||||
|     _assert_not_almost_equal(a, b) | ||||
|  | ||||
|  | ||||
| def test_assert_almost_equal_null(): | ||||
|     _assert_almost_equal_both(None, None) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("a,b", [(None, np.nan), (None, 0), (np.nan, 0)]) | ||||
| def test_assert_not_almost_equal_null(a, b): | ||||
|     _assert_not_almost_equal(a, b) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "a,b", | ||||
|     [ | ||||
|         (np.inf, np.inf), | ||||
|         (np.inf, float("inf")), | ||||
|         (np.array([np.inf, np.nan, -np.inf]), np.array([np.inf, np.nan, -np.inf])), | ||||
|     ], | ||||
| ) | ||||
| def test_assert_almost_equal_inf(a, b): | ||||
|     _assert_almost_equal_both(a, b) | ||||
|  | ||||
|  | ||||
| objs = [NA, np.nan, NaT, None, np.datetime64("NaT"), np.timedelta64("NaT")] | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("left", objs) | ||||
| @pytest.mark.parametrize("right", objs) | ||||
| def test_mismatched_na_assert_almost_equal_deprecation(left, right): | ||||
|     left_arr = np.array([left], dtype=object) | ||||
|     right_arr = np.array([right], dtype=object) | ||||
|  | ||||
|     msg = "Mismatched null-like values" | ||||
|  | ||||
|     if left is right: | ||||
|         _assert_almost_equal_both(left, right, check_dtype=False) | ||||
|         tm.assert_numpy_array_equal(left_arr, right_arr) | ||||
|         tm.assert_index_equal( | ||||
|             Index(left_arr, dtype=object), Index(right_arr, dtype=object) | ||||
|         ) | ||||
|         tm.assert_series_equal( | ||||
|             Series(left_arr, dtype=object), Series(right_arr, dtype=object) | ||||
|         ) | ||||
|         tm.assert_frame_equal( | ||||
|             DataFrame(left_arr, dtype=object), DataFrame(right_arr, dtype=object) | ||||
|         ) | ||||
|  | ||||
|     else: | ||||
|         with tm.assert_produces_warning(FutureWarning, match=msg): | ||||
|             _assert_almost_equal_both(left, right, check_dtype=False) | ||||
|  | ||||
|         # TODO: to get the same deprecation in assert_numpy_array_equal we need | ||||
|         #  to change/deprecate the default for strict_nan to become True | ||||
|         # TODO: to get the same deprecation in assert_index_equal we need to | ||||
|         #  change/deprecate array_equivalent_object to be stricter, as | ||||
|         #  assert_index_equal uses Index.equal which uses array_equivalent. | ||||
|         with tm.assert_produces_warning(FutureWarning, match=msg): | ||||
|             tm.assert_series_equal( | ||||
|                 Series(left_arr, dtype=object), Series(right_arr, dtype=object) | ||||
|             ) | ||||
|         with tm.assert_produces_warning(FutureWarning, match=msg): | ||||
|             tm.assert_frame_equal( | ||||
|                 DataFrame(left_arr, dtype=object), DataFrame(right_arr, dtype=object) | ||||
|             ) | ||||
|  | ||||
|  | ||||
| def test_assert_not_almost_equal_inf(): | ||||
|     _assert_not_almost_equal_both(np.inf, 0) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "a,b", | ||||
|     [ | ||||
|         (Index([1.0, 1.1]), Index([1.0, 1.100001])), | ||||
|         (Series([1.0, 1.1]), Series([1.0, 1.100001])), | ||||
|         (np.array([1.1, 2.000001]), np.array([1.1, 2.0])), | ||||
|         (DataFrame({"a": [1.0, 1.1]}), DataFrame({"a": [1.0, 1.100001]})), | ||||
|     ], | ||||
| ) | ||||
| def test_assert_almost_equal_pandas(a, b): | ||||
|     _assert_almost_equal_both(a, b) | ||||
|  | ||||
|  | ||||
| def test_assert_almost_equal_object(): | ||||
|     a = [Timestamp("2011-01-01"), Timestamp("2011-01-01")] | ||||
|     b = [Timestamp("2011-01-01"), Timestamp("2011-01-01")] | ||||
|     _assert_almost_equal_both(a, b) | ||||
|  | ||||
|  | ||||
| def test_assert_almost_equal_value_mismatch(): | ||||
|     msg = "expected 2\\.00000 but got 1\\.00000, with rtol=1e-05, atol=1e-08" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_almost_equal(1, 2) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "a,b,klass1,klass2", | ||||
|     [(np.array([1]), 1, "ndarray", "int"), (1, np.array([1]), "int", "ndarray")], | ||||
| ) | ||||
| def test_assert_almost_equal_class_mismatch(a, b, klass1, klass2): | ||||
|     msg = f"""numpy array are different | ||||
|  | ||||
| numpy array classes are different | ||||
| \\[left\\]:  {klass1} | ||||
| \\[right\\]: {klass2}""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_almost_equal(a, b) | ||||
|  | ||||
|  | ||||
| def test_assert_almost_equal_value_mismatch1(): | ||||
|     msg = """numpy array are different | ||||
|  | ||||
| numpy array values are different \\(66\\.66667 %\\) | ||||
| \\[left\\]:  \\[nan, 2\\.0, 3\\.0\\] | ||||
| \\[right\\]: \\[1\\.0, nan, 3\\.0\\]""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_almost_equal(np.array([np.nan, 2, 3]), np.array([1, np.nan, 3])) | ||||
|  | ||||
|  | ||||
| def test_assert_almost_equal_value_mismatch2(): | ||||
|     msg = """numpy array are different | ||||
|  | ||||
| numpy array values are different \\(50\\.0 %\\) | ||||
| \\[left\\]:  \\[1, 2\\] | ||||
| \\[right\\]: \\[1, 3\\]""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_almost_equal(np.array([1, 2]), np.array([1, 3])) | ||||
|  | ||||
|  | ||||
| def test_assert_almost_equal_value_mismatch3(): | ||||
|     msg = """numpy array are different | ||||
|  | ||||
| numpy array values are different \\(16\\.66667 %\\) | ||||
| \\[left\\]:  \\[\\[1, 2\\], \\[3, 4\\], \\[5, 6\\]\\] | ||||
| \\[right\\]: \\[\\[1, 3\\], \\[3, 4\\], \\[5, 6\\]\\]""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_almost_equal( | ||||
|             np.array([[1, 2], [3, 4], [5, 6]]), np.array([[1, 3], [3, 4], [5, 6]]) | ||||
|         ) | ||||
|  | ||||
|  | ||||
| def test_assert_almost_equal_value_mismatch4(): | ||||
|     msg = """numpy array are different | ||||
|  | ||||
| numpy array values are different \\(25\\.0 %\\) | ||||
| \\[left\\]:  \\[\\[1, 2\\], \\[3, 4\\]\\] | ||||
| \\[right\\]: \\[\\[1, 3\\], \\[3, 4\\]\\]""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_almost_equal(np.array([[1, 2], [3, 4]]), np.array([[1, 3], [3, 4]])) | ||||
|  | ||||
|  | ||||
| def test_assert_almost_equal_shape_mismatch_override(): | ||||
|     msg = """Index are different | ||||
|  | ||||
| Index shapes are different | ||||
| \\[left\\]:  \\(2L*,\\) | ||||
| \\[right\\]: \\(3L*,\\)""" | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_almost_equal(np.array([1, 2]), np.array([3, 4, 5]), obj="Index") | ||||
|  | ||||
|  | ||||
| def test_assert_almost_equal_unicode(): | ||||
|     # see gh-20503 | ||||
|     msg = """numpy array are different | ||||
|  | ||||
| numpy array values are different \\(33\\.33333 %\\) | ||||
| \\[left\\]:  \\[á, à, ä\\] | ||||
| \\[right\\]: \\[á, à, å\\]""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_almost_equal(np.array(["á", "à", "ä"]), np.array(["á", "à", "å"])) | ||||
|  | ||||
|  | ||||
| def test_assert_almost_equal_timestamp(): | ||||
|     a = np.array([Timestamp("2011-01-01"), Timestamp("2011-01-01")]) | ||||
|     b = np.array([Timestamp("2011-01-01"), Timestamp("2011-01-02")]) | ||||
|  | ||||
|     msg = """numpy array are different | ||||
|  | ||||
| numpy array values are different \\(50\\.0 %\\) | ||||
| \\[left\\]:  \\[2011-01-01 00:00:00, 2011-01-01 00:00:00\\] | ||||
| \\[right\\]: \\[2011-01-01 00:00:00, 2011-01-02 00:00:00\\]""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_almost_equal(a, b) | ||||
|  | ||||
|  | ||||
| def test_assert_almost_equal_iterable_length_mismatch(): | ||||
|     msg = """Iterable are different | ||||
|  | ||||
| Iterable length are different | ||||
| \\[left\\]:  2 | ||||
| \\[right\\]: 3""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_almost_equal([1, 2], [3, 4, 5]) | ||||
|  | ||||
|  | ||||
| def test_assert_almost_equal_iterable_values_mismatch(): | ||||
|     msg = """Iterable are different | ||||
|  | ||||
| Iterable values are different \\(50\\.0 %\\) | ||||
| \\[left\\]:  \\[1, 2\\] | ||||
| \\[right\\]: \\[1, 3\\]""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_almost_equal([1, 2], [1, 3]) | ||||
|  | ||||
|  | ||||
| subarr = np.empty(2, dtype=object) | ||||
| subarr[:] = [np.array([None, "b"], dtype=object), np.array(["c", "d"], dtype=object)] | ||||
|  | ||||
| NESTED_CASES = [ | ||||
|     # nested array | ||||
|     ( | ||||
|         np.array([np.array([50, 70, 90]), np.array([20, 30])], dtype=object), | ||||
|         np.array([np.array([50, 70, 90]), np.array([20, 30])], dtype=object), | ||||
|     ), | ||||
|     # >1 level of nesting | ||||
|     ( | ||||
|         np.array( | ||||
|             [ | ||||
|                 np.array([np.array([50, 70]), np.array([90])], dtype=object), | ||||
|                 np.array([np.array([20, 30])], dtype=object), | ||||
|             ], | ||||
|             dtype=object, | ||||
|         ), | ||||
|         np.array( | ||||
|             [ | ||||
|                 np.array([np.array([50, 70]), np.array([90])], dtype=object), | ||||
|                 np.array([np.array([20, 30])], dtype=object), | ||||
|             ], | ||||
|             dtype=object, | ||||
|         ), | ||||
|     ), | ||||
|     # lists | ||||
|     ( | ||||
|         np.array([[50, 70, 90], [20, 30]], dtype=object), | ||||
|         np.array([[50, 70, 90], [20, 30]], dtype=object), | ||||
|     ), | ||||
|     # mixed array/list | ||||
|     ( | ||||
|         np.array([np.array([1, 2, 3]), np.array([4, 5])], dtype=object), | ||||
|         np.array([[1, 2, 3], [4, 5]], dtype=object), | ||||
|     ), | ||||
|     ( | ||||
|         np.array( | ||||
|             [ | ||||
|                 np.array([np.array([1, 2, 3]), np.array([4, 5])], dtype=object), | ||||
|                 np.array( | ||||
|                     [np.array([6]), np.array([7, 8]), np.array([9])], dtype=object | ||||
|                 ), | ||||
|             ], | ||||
|             dtype=object, | ||||
|         ), | ||||
|         np.array([[[1, 2, 3], [4, 5]], [[6], [7, 8], [9]]], dtype=object), | ||||
|     ), | ||||
|     # same-length lists | ||||
|     ( | ||||
|         np.array([subarr, None], dtype=object), | ||||
|         np.array([[[None, "b"], ["c", "d"]], None], dtype=object), | ||||
|     ), | ||||
|     # dicts | ||||
|     ( | ||||
|         np.array([{"f1": 1, "f2": np.array(["a", "b"], dtype=object)}], dtype=object), | ||||
|         np.array([{"f1": 1, "f2": np.array(["a", "b"], dtype=object)}], dtype=object), | ||||
|     ), | ||||
|     ( | ||||
|         np.array([{"f1": 1, "f2": np.array(["a", "b"], dtype=object)}], dtype=object), | ||||
|         np.array([{"f1": 1, "f2": ["a", "b"]}], dtype=object), | ||||
|     ), | ||||
|     # array/list of dicts | ||||
|     ( | ||||
|         np.array( | ||||
|             [ | ||||
|                 np.array( | ||||
|                     [{"f1": 1, "f2": np.array(["a", "b"], dtype=object)}], dtype=object | ||||
|                 ), | ||||
|                 np.array([], dtype=object), | ||||
|             ], | ||||
|             dtype=object, | ||||
|         ), | ||||
|         np.array([[{"f1": 1, "f2": ["a", "b"]}], []], dtype=object), | ||||
|     ), | ||||
| ] | ||||
|  | ||||
|  | ||||
| @pytest.mark.filterwarnings("ignore:elementwise comparison failed:DeprecationWarning") | ||||
| @pytest.mark.parametrize("a,b", NESTED_CASES) | ||||
| def test_assert_almost_equal_array_nested(a, b): | ||||
|     _assert_almost_equal_both(a, b) | ||||
| @ -0,0 +1,33 @@ | ||||
| from types import SimpleNamespace | ||||
|  | ||||
| import pytest | ||||
|  | ||||
| from pandas.core.dtypes.common import is_float | ||||
|  | ||||
| import pandas._testing as tm | ||||
|  | ||||
|  | ||||
| def test_assert_attr_equal(nulls_fixture): | ||||
|     obj = SimpleNamespace() | ||||
|     obj.na_value = nulls_fixture | ||||
|     tm.assert_attr_equal("na_value", obj, obj) | ||||
|  | ||||
|  | ||||
| def test_assert_attr_equal_different_nulls(nulls_fixture, nulls_fixture2): | ||||
|     obj = SimpleNamespace() | ||||
|     obj.na_value = nulls_fixture | ||||
|  | ||||
|     obj2 = SimpleNamespace() | ||||
|     obj2.na_value = nulls_fixture2 | ||||
|  | ||||
|     if nulls_fixture is nulls_fixture2: | ||||
|         tm.assert_attr_equal("na_value", obj, obj2) | ||||
|     elif is_float(nulls_fixture) and is_float(nulls_fixture2): | ||||
|         # we consider float("nan") and np.float64("nan") to be equivalent | ||||
|         tm.assert_attr_equal("na_value", obj, obj2) | ||||
|     elif type(nulls_fixture) is type(nulls_fixture2): | ||||
|         # e.g. Decimal("NaN") | ||||
|         tm.assert_attr_equal("na_value", obj, obj2) | ||||
|     else: | ||||
|         with pytest.raises(AssertionError, match='"na_value" are different'): | ||||
|             tm.assert_attr_equal("na_value", obj, obj2) | ||||
| @ -0,0 +1,90 @@ | ||||
| import pytest | ||||
|  | ||||
| from pandas import Categorical | ||||
| import pandas._testing as tm | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "c", | ||||
|     [Categorical([1, 2, 3, 4]), Categorical([1, 2, 3, 4], categories=[1, 2, 3, 4, 5])], | ||||
| ) | ||||
| def test_categorical_equal(c): | ||||
|     tm.assert_categorical_equal(c, c) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("check_category_order", [True, False]) | ||||
| def test_categorical_equal_order_mismatch(check_category_order): | ||||
|     c1 = Categorical([1, 2, 3, 4], categories=[1, 2, 3, 4]) | ||||
|     c2 = Categorical([1, 2, 3, 4], categories=[4, 3, 2, 1]) | ||||
|     kwargs = {"check_category_order": check_category_order} | ||||
|  | ||||
|     if check_category_order: | ||||
|         msg = """Categorical\\.categories are different | ||||
|  | ||||
| Categorical\\.categories values are different \\(100\\.0 %\\) | ||||
| \\[left\\]:  Index\\(\\[1, 2, 3, 4\\], dtype='int64'\\) | ||||
| \\[right\\]: Index\\(\\[4, 3, 2, 1\\], dtype='int64'\\)""" | ||||
|         with pytest.raises(AssertionError, match=msg): | ||||
|             tm.assert_categorical_equal(c1, c2, **kwargs) | ||||
|     else: | ||||
|         tm.assert_categorical_equal(c1, c2, **kwargs) | ||||
|  | ||||
|  | ||||
| def test_categorical_equal_categories_mismatch(): | ||||
|     msg = """Categorical\\.categories are different | ||||
|  | ||||
| Categorical\\.categories values are different \\(25\\.0 %\\) | ||||
| \\[left\\]:  Index\\(\\[1, 2, 3, 4\\], dtype='int64'\\) | ||||
| \\[right\\]: Index\\(\\[1, 2, 3, 5\\], dtype='int64'\\)""" | ||||
|  | ||||
|     c1 = Categorical([1, 2, 3, 4]) | ||||
|     c2 = Categorical([1, 2, 3, 5]) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_categorical_equal(c1, c2) | ||||
|  | ||||
|  | ||||
| def test_categorical_equal_codes_mismatch(): | ||||
|     categories = [1, 2, 3, 4] | ||||
|     msg = """Categorical\\.codes are different | ||||
|  | ||||
| Categorical\\.codes values are different \\(50\\.0 %\\) | ||||
| \\[left\\]:  \\[0, 1, 3, 2\\] | ||||
| \\[right\\]: \\[0, 1, 2, 3\\]""" | ||||
|  | ||||
|     c1 = Categorical([1, 2, 4, 3], categories=categories) | ||||
|     c2 = Categorical([1, 2, 3, 4], categories=categories) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_categorical_equal(c1, c2) | ||||
|  | ||||
|  | ||||
| def test_categorical_equal_ordered_mismatch(): | ||||
|     data = [1, 2, 3, 4] | ||||
|     msg = """Categorical are different | ||||
|  | ||||
| Attribute "ordered" are different | ||||
| \\[left\\]:  False | ||||
| \\[right\\]: True""" | ||||
|  | ||||
|     c1 = Categorical(data, ordered=False) | ||||
|     c2 = Categorical(data, ordered=True) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_categorical_equal(c1, c2) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("obj", ["index", "foo", "pandas"]) | ||||
| def test_categorical_equal_object_override(obj): | ||||
|     data = [1, 2, 3, 4] | ||||
|     msg = f"""{obj} are different | ||||
|  | ||||
| Attribute "ordered" are different | ||||
| \\[left\\]:  False | ||||
| \\[right\\]: True""" | ||||
|  | ||||
|     c1 = Categorical(data, ordered=False) | ||||
|     c2 = Categorical(data, ordered=True) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_categorical_equal(c1, c2, obj=obj) | ||||
| @ -0,0 +1,126 @@ | ||||
| import numpy as np | ||||
| import pytest | ||||
|  | ||||
| from pandas import ( | ||||
|     Timestamp, | ||||
|     array, | ||||
| ) | ||||
| import pandas._testing as tm | ||||
| from pandas.core.arrays.sparse import SparseArray | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "kwargs", | ||||
|     [ | ||||
|         {},  # Default is check_exact=False | ||||
|         {"check_exact": False}, | ||||
|         {"check_exact": True}, | ||||
|     ], | ||||
| ) | ||||
| def test_assert_extension_array_equal_not_exact(kwargs): | ||||
|     # see gh-23709 | ||||
|     arr1 = SparseArray([-0.17387645482451206, 0.3414148016424936]) | ||||
|     arr2 = SparseArray([-0.17387645482451206, 0.3414148016424937]) | ||||
|  | ||||
|     if kwargs.get("check_exact", False): | ||||
|         msg = """\ | ||||
| ExtensionArray are different | ||||
|  | ||||
| ExtensionArray values are different \\(50\\.0 %\\) | ||||
| \\[left\\]:  \\[-0\\.17387645482.*, 0\\.341414801642.*\\] | ||||
| \\[right\\]: \\[-0\\.17387645482.*, 0\\.341414801642.*\\]""" | ||||
|  | ||||
|         with pytest.raises(AssertionError, match=msg): | ||||
|             tm.assert_extension_array_equal(arr1, arr2, **kwargs) | ||||
|     else: | ||||
|         tm.assert_extension_array_equal(arr1, arr2, **kwargs) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("decimals", range(10)) | ||||
| def test_assert_extension_array_equal_less_precise(decimals): | ||||
|     rtol = 0.5 * 10**-decimals | ||||
|     arr1 = SparseArray([0.5, 0.123456]) | ||||
|     arr2 = SparseArray([0.5, 0.123457]) | ||||
|  | ||||
|     if decimals >= 5: | ||||
|         msg = """\ | ||||
| ExtensionArray are different | ||||
|  | ||||
| ExtensionArray values are different \\(50\\.0 %\\) | ||||
| \\[left\\]:  \\[0\\.5, 0\\.123456\\] | ||||
| \\[right\\]: \\[0\\.5, 0\\.123457\\]""" | ||||
|  | ||||
|         with pytest.raises(AssertionError, match=msg): | ||||
|             tm.assert_extension_array_equal(arr1, arr2, rtol=rtol) | ||||
|     else: | ||||
|         tm.assert_extension_array_equal(arr1, arr2, rtol=rtol) | ||||
|  | ||||
|  | ||||
| def test_assert_extension_array_equal_dtype_mismatch(check_dtype): | ||||
|     end = 5 | ||||
|     kwargs = {"check_dtype": check_dtype} | ||||
|  | ||||
|     arr1 = SparseArray(np.arange(end, dtype="int64")) | ||||
|     arr2 = SparseArray(np.arange(end, dtype="int32")) | ||||
|  | ||||
|     if check_dtype: | ||||
|         msg = """\ | ||||
| ExtensionArray are different | ||||
|  | ||||
| Attribute "dtype" are different | ||||
| \\[left\\]:  Sparse\\[int64, 0\\] | ||||
| \\[right\\]: Sparse\\[int32, 0\\]""" | ||||
|  | ||||
|         with pytest.raises(AssertionError, match=msg): | ||||
|             tm.assert_extension_array_equal(arr1, arr2, **kwargs) | ||||
|     else: | ||||
|         tm.assert_extension_array_equal(arr1, arr2, **kwargs) | ||||
|  | ||||
|  | ||||
| def test_assert_extension_array_equal_missing_values(): | ||||
|     arr1 = SparseArray([np.nan, 1, 2, np.nan]) | ||||
|     arr2 = SparseArray([np.nan, 1, 2, 3]) | ||||
|  | ||||
|     msg = """\ | ||||
| ExtensionArray NA mask are different | ||||
|  | ||||
| ExtensionArray NA mask values are different \\(25\\.0 %\\) | ||||
| \\[left\\]:  \\[True, False, False, True\\] | ||||
| \\[right\\]: \\[True, False, False, False\\]""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_extension_array_equal(arr1, arr2) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("side", ["left", "right"]) | ||||
| def test_assert_extension_array_equal_non_extension_array(side): | ||||
|     numpy_array = np.arange(5) | ||||
|     extension_array = SparseArray(numpy_array) | ||||
|  | ||||
|     msg = f"{side} is not an ExtensionArray" | ||||
|     args = ( | ||||
|         (numpy_array, extension_array) | ||||
|         if side == "left" | ||||
|         else (extension_array, numpy_array) | ||||
|     ) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_extension_array_equal(*args) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("right_dtype", ["Int32", "int64"]) | ||||
| def test_assert_extension_array_equal_ignore_dtype_mismatch(right_dtype): | ||||
|     # https://github.com/pandas-dev/pandas/issues/35715 | ||||
|     left = array([1, 2, 3], dtype="Int64") | ||||
|     right = array([1, 2, 3], dtype=right_dtype) | ||||
|     tm.assert_extension_array_equal(left, right, check_dtype=False) | ||||
|  | ||||
|  | ||||
| def test_assert_extension_array_equal_time_units(): | ||||
|     # https://github.com/pandas-dev/pandas/issues/55730 | ||||
|     timestamp = Timestamp("2023-11-04T12") | ||||
|     naive = array([timestamp], dtype="datetime64[ns]") | ||||
|     utc = array([timestamp], dtype="datetime64[ns, UTC]") | ||||
|  | ||||
|     tm.assert_extension_array_equal(naive, utc, check_dtype=False) | ||||
|     tm.assert_extension_array_equal(utc, naive, check_dtype=False) | ||||
| @ -0,0 +1,393 @@ | ||||
| import pytest | ||||
|  | ||||
| import pandas as pd | ||||
| from pandas import DataFrame | ||||
| import pandas._testing as tm | ||||
|  | ||||
|  | ||||
| @pytest.fixture(params=[True, False]) | ||||
| def by_blocks_fixture(request): | ||||
|     return request.param | ||||
|  | ||||
|  | ||||
| @pytest.fixture(params=["DataFrame", "Series"]) | ||||
| def obj_fixture(request): | ||||
|     return request.param | ||||
|  | ||||
|  | ||||
| def _assert_frame_equal_both(a, b, **kwargs): | ||||
|     """ | ||||
|     Check that two DataFrame equal. | ||||
|  | ||||
|     This check is performed commutatively. | ||||
|  | ||||
|     Parameters | ||||
|     ---------- | ||||
|     a : DataFrame | ||||
|         The first DataFrame to compare. | ||||
|     b : DataFrame | ||||
|         The second DataFrame to compare. | ||||
|     kwargs : dict | ||||
|         The arguments passed to `tm.assert_frame_equal`. | ||||
|     """ | ||||
|     tm.assert_frame_equal(a, b, **kwargs) | ||||
|     tm.assert_frame_equal(b, a, **kwargs) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("check_like", [True, False]) | ||||
| def test_frame_equal_row_order_mismatch(check_like, obj_fixture): | ||||
|     df1 = DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]}, index=["a", "b", "c"]) | ||||
|     df2 = DataFrame({"A": [3, 2, 1], "B": [6, 5, 4]}, index=["c", "b", "a"]) | ||||
|  | ||||
|     if not check_like:  # Do not ignore row-column orderings. | ||||
|         msg = f"{obj_fixture}.index are different" | ||||
|         with pytest.raises(AssertionError, match=msg): | ||||
|             tm.assert_frame_equal(df1, df2, check_like=check_like, obj=obj_fixture) | ||||
|     else: | ||||
|         _assert_frame_equal_both(df1, df2, check_like=check_like, obj=obj_fixture) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "df1,df2", | ||||
|     [ | ||||
|         (DataFrame({"A": [1, 2, 3]}), DataFrame({"A": [1, 2, 3, 4]})), | ||||
|         (DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]}), DataFrame({"A": [1, 2, 3]})), | ||||
|     ], | ||||
| ) | ||||
| def test_frame_equal_shape_mismatch(df1, df2, obj_fixture): | ||||
|     msg = f"{obj_fixture} are different" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_frame_equal(df1, df2, obj=obj_fixture) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "df1,df2,msg", | ||||
|     [ | ||||
|         # Index | ||||
|         ( | ||||
|             DataFrame.from_records({"a": [1, 2], "c": ["l1", "l2"]}, index=["a"]), | ||||
|             DataFrame.from_records({"a": [1.0, 2.0], "c": ["l1", "l2"]}, index=["a"]), | ||||
|             "DataFrame\\.index are different", | ||||
|         ), | ||||
|         # MultiIndex | ||||
|         ( | ||||
|             DataFrame.from_records( | ||||
|                 {"a": [1, 2], "b": [2.1, 1.5], "c": ["l1", "l2"]}, index=["a", "b"] | ||||
|             ), | ||||
|             DataFrame.from_records( | ||||
|                 {"a": [1.0, 2.0], "b": [2.1, 1.5], "c": ["l1", "l2"]}, index=["a", "b"] | ||||
|             ), | ||||
|             "MultiIndex level \\[0\\] are different", | ||||
|         ), | ||||
|     ], | ||||
| ) | ||||
| def test_frame_equal_index_dtype_mismatch(df1, df2, msg, check_index_type): | ||||
|     kwargs = {"check_index_type": check_index_type} | ||||
|  | ||||
|     if check_index_type: | ||||
|         with pytest.raises(AssertionError, match=msg): | ||||
|             tm.assert_frame_equal(df1, df2, **kwargs) | ||||
|     else: | ||||
|         tm.assert_frame_equal(df1, df2, **kwargs) | ||||
|  | ||||
|  | ||||
| def test_empty_dtypes(check_dtype): | ||||
|     columns = ["col1", "col2"] | ||||
|     df1 = DataFrame(columns=columns) | ||||
|     df2 = DataFrame(columns=columns) | ||||
|  | ||||
|     kwargs = {"check_dtype": check_dtype} | ||||
|     df1["col1"] = df1["col1"].astype("int64") | ||||
|  | ||||
|     if check_dtype: | ||||
|         msg = r"Attributes of DataFrame\..* are different" | ||||
|         with pytest.raises(AssertionError, match=msg): | ||||
|             tm.assert_frame_equal(df1, df2, **kwargs) | ||||
|     else: | ||||
|         tm.assert_frame_equal(df1, df2, **kwargs) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("check_like", [True, False]) | ||||
| def test_frame_equal_index_mismatch(check_like, obj_fixture, using_infer_string): | ||||
|     if using_infer_string: | ||||
|         dtype = "str" | ||||
|     else: | ||||
|         dtype = "object" | ||||
|     msg = f"""{obj_fixture}\\.index are different | ||||
|  | ||||
| {obj_fixture}\\.index values are different \\(33\\.33333 %\\) | ||||
| \\[left\\]:  Index\\(\\['a', 'b', 'c'\\], dtype='{dtype}'\\) | ||||
| \\[right\\]: Index\\(\\['a', 'b', 'd'\\], dtype='{dtype}'\\) | ||||
| At positional index 2, first diff: c != d""" | ||||
|  | ||||
|     df1 = DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]}, index=["a", "b", "c"]) | ||||
|     df2 = DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]}, index=["a", "b", "d"]) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_frame_equal(df1, df2, check_like=check_like, obj=obj_fixture) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("check_like", [True, False]) | ||||
| def test_frame_equal_columns_mismatch(check_like, obj_fixture, using_infer_string): | ||||
|     if using_infer_string: | ||||
|         dtype = "str" | ||||
|     else: | ||||
|         dtype = "object" | ||||
|     msg = f"""{obj_fixture}\\.columns are different | ||||
|  | ||||
| {obj_fixture}\\.columns values are different \\(50\\.0 %\\) | ||||
| \\[left\\]:  Index\\(\\['A', 'B'\\], dtype='{dtype}'\\) | ||||
| \\[right\\]: Index\\(\\['A', 'b'\\], dtype='{dtype}'\\)""" | ||||
|  | ||||
|     df1 = DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]}, index=["a", "b", "c"]) | ||||
|     df2 = DataFrame({"A": [1, 2, 3], "b": [4, 5, 6]}, index=["a", "b", "c"]) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_frame_equal(df1, df2, check_like=check_like, obj=obj_fixture) | ||||
|  | ||||
|  | ||||
| def test_frame_equal_block_mismatch(by_blocks_fixture, obj_fixture): | ||||
|     obj = obj_fixture | ||||
|     msg = f"""{obj}\\.iloc\\[:, 1\\] \\(column name="B"\\) are different | ||||
|  | ||||
| {obj}\\.iloc\\[:, 1\\] \\(column name="B"\\) values are different \\(33\\.33333 %\\) | ||||
| \\[index\\]: \\[0, 1, 2\\] | ||||
| \\[left\\]:  \\[4, 5, 6\\] | ||||
| \\[right\\]: \\[4, 5, 7\\]""" | ||||
|  | ||||
|     df1 = DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]}) | ||||
|     df2 = DataFrame({"A": [1, 2, 3], "B": [4, 5, 7]}) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_frame_equal(df1, df2, by_blocks=by_blocks_fixture, obj=obj_fixture) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "df1,df2,msg", | ||||
|     [ | ||||
|         ( | ||||
|             DataFrame({"A": ["á", "à", "ä"], "E": ["é", "è", "ë"]}), | ||||
|             DataFrame({"A": ["á", "à", "ä"], "E": ["é", "è", "e̊"]}), | ||||
|             """{obj}\\.iloc\\[:, 1\\] \\(column name="E"\\) are different | ||||
|  | ||||
| {obj}\\.iloc\\[:, 1\\] \\(column name="E"\\) values are different \\(33\\.33333 %\\) | ||||
| \\[index\\]: \\[0, 1, 2\\] | ||||
| \\[left\\]:  \\[é, è, ë\\] | ||||
| \\[right\\]: \\[é, è, e̊\\]""", | ||||
|         ), | ||||
|         ( | ||||
|             DataFrame({"A": ["á", "à", "ä"], "E": ["é", "è", "ë"]}), | ||||
|             DataFrame({"A": ["a", "a", "a"], "E": ["e", "e", "e"]}), | ||||
|             """{obj}\\.iloc\\[:, 0\\] \\(column name="A"\\) are different | ||||
|  | ||||
| {obj}\\.iloc\\[:, 0\\] \\(column name="A"\\) values are different \\(100\\.0 %\\) | ||||
| \\[index\\]: \\[0, 1, 2\\] | ||||
| \\[left\\]:  \\[á, à, ä\\] | ||||
| \\[right\\]: \\[a, a, a\\]""", | ||||
|         ), | ||||
|     ], | ||||
| ) | ||||
| def test_frame_equal_unicode(df1, df2, msg, by_blocks_fixture, obj_fixture): | ||||
|     # see gh-20503 | ||||
|     # | ||||
|     # Test ensures that `tm.assert_frame_equals` raises the right exception | ||||
|     # when comparing DataFrames containing differing unicode objects. | ||||
|     msg = msg.format(obj=obj_fixture) | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_frame_equal(df1, df2, by_blocks=by_blocks_fixture, obj=obj_fixture) | ||||
|  | ||||
|  | ||||
| def test_assert_frame_equal_extension_dtype_mismatch(): | ||||
|     # https://github.com/pandas-dev/pandas/issues/32747 | ||||
|     left = DataFrame({"a": [1, 2, 3]}, dtype="Int64") | ||||
|     right = left.astype(int) | ||||
|  | ||||
|     msg = ( | ||||
|         "Attributes of DataFrame\\.iloc\\[:, 0\\] " | ||||
|         '\\(column name="a"\\) are different\n\n' | ||||
|         'Attribute "dtype" are different\n' | ||||
|         "\\[left\\]:  Int64\n" | ||||
|         "\\[right\\]: int[32|64]" | ||||
|     ) | ||||
|  | ||||
|     tm.assert_frame_equal(left, right, check_dtype=False) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_frame_equal(left, right, check_dtype=True) | ||||
|  | ||||
|  | ||||
| def test_assert_frame_equal_interval_dtype_mismatch(): | ||||
|     # https://github.com/pandas-dev/pandas/issues/32747 | ||||
|     left = DataFrame({"a": [pd.Interval(0, 1)]}, dtype="interval") | ||||
|     right = left.astype(object) | ||||
|  | ||||
|     msg = ( | ||||
|         "Attributes of DataFrame\\.iloc\\[:, 0\\] " | ||||
|         '\\(column name="a"\\) are different\n\n' | ||||
|         'Attribute "dtype" are different\n' | ||||
|         "\\[left\\]:  interval\\[int64, right\\]\n" | ||||
|         "\\[right\\]: object" | ||||
|     ) | ||||
|  | ||||
|     tm.assert_frame_equal(left, right, check_dtype=False) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_frame_equal(left, right, check_dtype=True) | ||||
|  | ||||
|  | ||||
| def test_assert_frame_equal_ignore_extension_dtype_mismatch(): | ||||
|     # https://github.com/pandas-dev/pandas/issues/35715 | ||||
|     left = DataFrame({"a": [1, 2, 3]}, dtype="Int64") | ||||
|     right = DataFrame({"a": [1, 2, 3]}, dtype="Int32") | ||||
|     tm.assert_frame_equal(left, right, check_dtype=False) | ||||
|  | ||||
|  | ||||
| def test_assert_frame_equal_ignore_extension_dtype_mismatch_cross_class(): | ||||
|     # https://github.com/pandas-dev/pandas/issues/35715 | ||||
|     left = DataFrame({"a": [1, 2, 3]}, dtype="Int64") | ||||
|     right = DataFrame({"a": [1, 2, 3]}, dtype="int64") | ||||
|     tm.assert_frame_equal(left, right, check_dtype=False) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "dtype", | ||||
|     [ | ||||
|         ("timedelta64[ns]"), | ||||
|         ("datetime64[ns, UTC]"), | ||||
|         ("Period[D]"), | ||||
|     ], | ||||
| ) | ||||
| def test_assert_frame_equal_datetime_like_dtype_mismatch(dtype): | ||||
|     df1 = DataFrame({"a": []}, dtype=dtype) | ||||
|     df2 = DataFrame({"a": []}) | ||||
|     tm.assert_frame_equal(df1, df2, check_dtype=False) | ||||
|  | ||||
|  | ||||
| def test_allows_duplicate_labels(): | ||||
|     left = DataFrame() | ||||
|     right = DataFrame().set_flags(allows_duplicate_labels=False) | ||||
|     tm.assert_frame_equal(left, left) | ||||
|     tm.assert_frame_equal(right, right) | ||||
|     tm.assert_frame_equal(left, right, check_flags=False) | ||||
|     tm.assert_frame_equal(right, left, check_flags=False) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match="<Flags"): | ||||
|         tm.assert_frame_equal(left, right) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match="<Flags"): | ||||
|         tm.assert_frame_equal(left, right) | ||||
|  | ||||
|  | ||||
| def test_assert_frame_equal_columns_mixed_dtype(): | ||||
|     # GH#39168 | ||||
|     df = DataFrame([[0, 1, 2]], columns=["foo", "bar", 42], index=[1, "test", 2]) | ||||
|     tm.assert_frame_equal(df, df, check_like=True) | ||||
|  | ||||
|  | ||||
| def test_frame_equal_extension_dtype(frame_or_series, any_numeric_ea_dtype): | ||||
|     # GH#39410 | ||||
|     obj = frame_or_series([1, 2], dtype=any_numeric_ea_dtype) | ||||
|     tm.assert_equal(obj, obj, check_exact=True) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("indexer", [(0, 1), (1, 0)]) | ||||
| def test_frame_equal_mixed_dtypes(frame_or_series, any_numeric_ea_dtype, indexer): | ||||
|     dtypes = (any_numeric_ea_dtype, "int64") | ||||
|     obj1 = frame_or_series([1, 2], dtype=dtypes[indexer[0]]) | ||||
|     obj2 = frame_or_series([1, 2], dtype=dtypes[indexer[1]]) | ||||
|     tm.assert_equal(obj1, obj2, check_exact=True, check_dtype=False) | ||||
|  | ||||
|  | ||||
| def test_assert_frame_equal_check_like_different_indexes(): | ||||
|     # GH#39739 | ||||
|     df1 = DataFrame(index=pd.Index([], dtype="object")) | ||||
|     df2 = DataFrame(index=pd.RangeIndex(start=0, stop=0, step=1)) | ||||
|     with pytest.raises(AssertionError, match="DataFrame.index are different"): | ||||
|         tm.assert_frame_equal(df1, df2, check_like=True) | ||||
|  | ||||
|  | ||||
| def test_assert_frame_equal_checking_allow_dups_flag(): | ||||
|     # GH#45554 | ||||
|     left = DataFrame([[1, 2], [3, 4]]) | ||||
|     left.flags.allows_duplicate_labels = False | ||||
|  | ||||
|     right = DataFrame([[1, 2], [3, 4]]) | ||||
|     right.flags.allows_duplicate_labels = True | ||||
|     tm.assert_frame_equal(left, right, check_flags=False) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match="allows_duplicate_labels"): | ||||
|         tm.assert_frame_equal(left, right, check_flags=True) | ||||
|  | ||||
|  | ||||
| def test_assert_frame_equal_check_like_categorical_midx(): | ||||
|     # GH#48975 | ||||
|     left = DataFrame( | ||||
|         [[1], [2], [3]], | ||||
|         index=pd.MultiIndex.from_arrays( | ||||
|             [ | ||||
|                 pd.Categorical(["a", "b", "c"]), | ||||
|                 pd.Categorical(["a", "b", "c"]), | ||||
|             ] | ||||
|         ), | ||||
|     ) | ||||
|     right = DataFrame( | ||||
|         [[3], [2], [1]], | ||||
|         index=pd.MultiIndex.from_arrays( | ||||
|             [ | ||||
|                 pd.Categorical(["c", "b", "a"]), | ||||
|                 pd.Categorical(["c", "b", "a"]), | ||||
|             ] | ||||
|         ), | ||||
|     ) | ||||
|     tm.assert_frame_equal(left, right, check_like=True) | ||||
|  | ||||
|  | ||||
| def test_assert_frame_equal_ea_column_definition_in_exception_mask(): | ||||
|     # GH#50323 | ||||
|     df1 = DataFrame({"a": pd.Series([pd.NA, 1], dtype="Int64")}) | ||||
|     df2 = DataFrame({"a": pd.Series([1, 1], dtype="Int64")}) | ||||
|  | ||||
|     msg = r'DataFrame.iloc\[:, 0\] \(column name="a"\) NA mask values are different' | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_frame_equal(df1, df2) | ||||
|  | ||||
|  | ||||
| def test_assert_frame_equal_ea_column_definition_in_exception(): | ||||
|     # GH#50323 | ||||
|     df1 = DataFrame({"a": pd.Series([pd.NA, 1], dtype="Int64")}) | ||||
|     df2 = DataFrame({"a": pd.Series([pd.NA, 2], dtype="Int64")}) | ||||
|  | ||||
|     msg = r'DataFrame.iloc\[:, 0\] \(column name="a"\) values are different' | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_frame_equal(df1, df2) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_frame_equal(df1, df2, check_exact=True) | ||||
|  | ||||
|  | ||||
| def test_assert_frame_equal_ts_column(): | ||||
|     # GH#50323 | ||||
|     df1 = DataFrame({"a": [pd.Timestamp("2019-12-31"), pd.Timestamp("2020-12-31")]}) | ||||
|     df2 = DataFrame({"a": [pd.Timestamp("2020-12-31"), pd.Timestamp("2020-12-31")]}) | ||||
|  | ||||
|     msg = r'DataFrame.iloc\[:, 0\] \(column name="a"\) values are different' | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_frame_equal(df1, df2) | ||||
|  | ||||
|  | ||||
| def test_assert_frame_equal_set(): | ||||
|     # GH#51727 | ||||
|     df1 = DataFrame({"set_column": [{1, 2, 3}, {4, 5, 6}]}) | ||||
|     df2 = DataFrame({"set_column": [{1, 2, 3}, {4, 5, 6}]}) | ||||
|     tm.assert_frame_equal(df1, df2) | ||||
|  | ||||
|  | ||||
| def test_assert_frame_equal_set_mismatch(): | ||||
|     # GH#51727 | ||||
|     df1 = DataFrame({"set_column": [{1, 2, 3}, {4, 5, 6}]}) | ||||
|     df2 = DataFrame({"set_column": [{1, 2, 3}, {4, 5, 7}]}) | ||||
|  | ||||
|     msg = r'DataFrame.iloc\[:, 0\] \(column name="set_column"\) values are different' | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_frame_equal(df1, df2) | ||||
| @ -0,0 +1,319 @@ | ||||
| import numpy as np | ||||
| import pytest | ||||
|  | ||||
| from pandas import ( | ||||
|     NA, | ||||
|     Categorical, | ||||
|     CategoricalIndex, | ||||
|     Index, | ||||
|     MultiIndex, | ||||
|     NaT, | ||||
|     RangeIndex, | ||||
| ) | ||||
| import pandas._testing as tm | ||||
|  | ||||
|  | ||||
| def test_index_equal_levels_mismatch(): | ||||
|     msg = """Index are different | ||||
|  | ||||
| Index levels are different | ||||
| \\[left\\]:  1, Index\\(\\[1, 2, 3\\], dtype='int64'\\) | ||||
| \\[right\\]: 2, MultiIndex\\(\\[\\('A', 1\\), | ||||
|             \\('A', 2\\), | ||||
|             \\('B', 3\\), | ||||
|             \\('B', 4\\)\\], | ||||
|            \\)""" | ||||
|  | ||||
|     idx1 = Index([1, 2, 3]) | ||||
|     idx2 = MultiIndex.from_tuples([("A", 1), ("A", 2), ("B", 3), ("B", 4)]) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_index_equal(idx1, idx2, exact=False) | ||||
|  | ||||
|  | ||||
| def test_index_equal_values_mismatch(check_exact): | ||||
|     msg = """MultiIndex level \\[1\\] are different | ||||
|  | ||||
| MultiIndex level \\[1\\] values are different \\(25\\.0 %\\) | ||||
| \\[left\\]:  Index\\(\\[2, 2, 3, 4\\], dtype='int64'\\) | ||||
| \\[right\\]: Index\\(\\[1, 2, 3, 4\\], dtype='int64'\\)""" | ||||
|  | ||||
|     idx1 = MultiIndex.from_tuples([("A", 2), ("A", 2), ("B", 3), ("B", 4)]) | ||||
|     idx2 = MultiIndex.from_tuples([("A", 1), ("A", 2), ("B", 3), ("B", 4)]) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_index_equal(idx1, idx2, check_exact=check_exact) | ||||
|  | ||||
|  | ||||
| def test_index_equal_length_mismatch(check_exact): | ||||
|     msg = """Index are different | ||||
|  | ||||
| Index length are different | ||||
| \\[left\\]:  3, Index\\(\\[1, 2, 3\\], dtype='int64'\\) | ||||
| \\[right\\]: 4, Index\\(\\[1, 2, 3, 4\\], dtype='int64'\\)""" | ||||
|  | ||||
|     idx1 = Index([1, 2, 3]) | ||||
|     idx2 = Index([1, 2, 3, 4]) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_index_equal(idx1, idx2, check_exact=check_exact) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("exact", [False, "equiv"]) | ||||
| def test_index_equal_class(exact): | ||||
|     idx1 = Index([0, 1, 2]) | ||||
|     idx2 = RangeIndex(3) | ||||
|  | ||||
|     tm.assert_index_equal(idx1, idx2, exact=exact) | ||||
|  | ||||
|  | ||||
| def test_int_float_index_equal_class_mismatch(check_exact): | ||||
|     msg = """Index are different | ||||
|  | ||||
| Attribute "inferred_type" are different | ||||
| \\[left\\]:  integer | ||||
| \\[right\\]: floating""" | ||||
|  | ||||
|     idx1 = Index([1, 2, 3]) | ||||
|     idx2 = Index([1, 2, 3], dtype=np.float64) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_index_equal(idx1, idx2, exact=True, check_exact=check_exact) | ||||
|  | ||||
|  | ||||
| def test_range_index_equal_class_mismatch(check_exact): | ||||
|     msg = """Index are different | ||||
|  | ||||
| Index classes are different | ||||
| \\[left\\]:  Index\\(\\[1, 2, 3\\], dtype='int64'\\) | ||||
| \\[right\\]: """ | ||||
|  | ||||
|     idx1 = Index([1, 2, 3]) | ||||
|     idx2 = RangeIndex(range(3)) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_index_equal(idx1, idx2, exact=True, check_exact=check_exact) | ||||
|  | ||||
|  | ||||
| def test_index_equal_values_close(check_exact): | ||||
|     idx1 = Index([1, 2, 3.0]) | ||||
|     idx2 = Index([1, 2, 3.0000000001]) | ||||
|  | ||||
|     if check_exact: | ||||
|         msg = """Index are different | ||||
|  | ||||
| Index values are different \\(33\\.33333 %\\) | ||||
| \\[left\\]:  Index\\(\\[1.0, 2.0, 3.0], dtype='float64'\\) | ||||
| \\[right\\]: Index\\(\\[1.0, 2.0, 3.0000000001\\], dtype='float64'\\)""" | ||||
|  | ||||
|         with pytest.raises(AssertionError, match=msg): | ||||
|             tm.assert_index_equal(idx1, idx2, check_exact=check_exact) | ||||
|     else: | ||||
|         tm.assert_index_equal(idx1, idx2, check_exact=check_exact) | ||||
|  | ||||
|  | ||||
| def test_index_equal_values_less_close(check_exact, rtol): | ||||
|     idx1 = Index([1, 2, 3.0]) | ||||
|     idx2 = Index([1, 2, 3.0001]) | ||||
|     kwargs = {"check_exact": check_exact, "rtol": rtol} | ||||
|  | ||||
|     if check_exact or rtol < 0.5e-3: | ||||
|         msg = """Index are different | ||||
|  | ||||
| Index values are different \\(33\\.33333 %\\) | ||||
| \\[left\\]:  Index\\(\\[1.0, 2.0, 3.0], dtype='float64'\\) | ||||
| \\[right\\]: Index\\(\\[1.0, 2.0, 3.0001\\], dtype='float64'\\)""" | ||||
|  | ||||
|         with pytest.raises(AssertionError, match=msg): | ||||
|             tm.assert_index_equal(idx1, idx2, **kwargs) | ||||
|     else: | ||||
|         tm.assert_index_equal(idx1, idx2, **kwargs) | ||||
|  | ||||
|  | ||||
| def test_index_equal_values_too_far(check_exact, rtol): | ||||
|     idx1 = Index([1, 2, 3]) | ||||
|     idx2 = Index([1, 2, 4]) | ||||
|     kwargs = {"check_exact": check_exact, "rtol": rtol} | ||||
|  | ||||
|     msg = """Index are different | ||||
|  | ||||
| Index values are different \\(33\\.33333 %\\) | ||||
| \\[left\\]:  Index\\(\\[1, 2, 3\\], dtype='int64'\\) | ||||
| \\[right\\]: Index\\(\\[1, 2, 4\\], dtype='int64'\\)""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_index_equal(idx1, idx2, **kwargs) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("check_order", [True, False]) | ||||
| def test_index_equal_value_order_mismatch(check_exact, rtol, check_order): | ||||
|     idx1 = Index([1, 2, 3]) | ||||
|     idx2 = Index([3, 2, 1]) | ||||
|  | ||||
|     msg = """Index are different | ||||
|  | ||||
| Index values are different \\(66\\.66667 %\\) | ||||
| \\[left\\]:  Index\\(\\[1, 2, 3\\], dtype='int64'\\) | ||||
| \\[right\\]: Index\\(\\[3, 2, 1\\], dtype='int64'\\)""" | ||||
|  | ||||
|     if check_order: | ||||
|         with pytest.raises(AssertionError, match=msg): | ||||
|             tm.assert_index_equal( | ||||
|                 idx1, idx2, check_exact=check_exact, rtol=rtol, check_order=True | ||||
|             ) | ||||
|     else: | ||||
|         tm.assert_index_equal( | ||||
|             idx1, idx2, check_exact=check_exact, rtol=rtol, check_order=False | ||||
|         ) | ||||
|  | ||||
|  | ||||
| def test_index_equal_level_values_mismatch(check_exact, rtol): | ||||
|     idx1 = MultiIndex.from_tuples([("A", 2), ("A", 2), ("B", 3), ("B", 4)]) | ||||
|     idx2 = MultiIndex.from_tuples([("A", 1), ("A", 2), ("B", 3), ("B", 4)]) | ||||
|     kwargs = {"check_exact": check_exact, "rtol": rtol} | ||||
|  | ||||
|     msg = """MultiIndex level \\[1\\] are different | ||||
|  | ||||
| MultiIndex level \\[1\\] values are different \\(25\\.0 %\\) | ||||
| \\[left\\]:  Index\\(\\[2, 2, 3, 4\\], dtype='int64'\\) | ||||
| \\[right\\]: Index\\(\\[1, 2, 3, 4\\], dtype='int64'\\)""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_index_equal(idx1, idx2, **kwargs) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "name1,name2", | ||||
|     [(None, "x"), ("x", "x"), (np.nan, np.nan), (NaT, NaT), (np.nan, NaT)], | ||||
| ) | ||||
| def test_index_equal_names(name1, name2): | ||||
|     idx1 = Index([1, 2, 3], name=name1) | ||||
|     idx2 = Index([1, 2, 3], name=name2) | ||||
|  | ||||
|     if name1 == name2 or name1 is name2: | ||||
|         tm.assert_index_equal(idx1, idx2) | ||||
|     else: | ||||
|         name1 = "'x'" if name1 == "x" else name1 | ||||
|         name2 = "'x'" if name2 == "x" else name2 | ||||
|         msg = f"""Index are different | ||||
|  | ||||
| Attribute "names" are different | ||||
| \\[left\\]:  \\[{name1}\\] | ||||
| \\[right\\]: \\[{name2}\\]""" | ||||
|  | ||||
|         with pytest.raises(AssertionError, match=msg): | ||||
|             tm.assert_index_equal(idx1, idx2) | ||||
|  | ||||
|  | ||||
| def test_index_equal_category_mismatch(check_categorical, using_infer_string): | ||||
|     if using_infer_string: | ||||
|         dtype = "str" | ||||
|     else: | ||||
|         dtype = "object" | ||||
|     msg = f"""Index are different | ||||
|  | ||||
| Attribute "dtype" are different | ||||
| \\[left\\]:  CategoricalDtype\\(categories=\\['a', 'b'\\], ordered=False, \ | ||||
| categories_dtype={dtype}\\) | ||||
| \\[right\\]: CategoricalDtype\\(categories=\\['a', 'b', 'c'\\], \ | ||||
| ordered=False, categories_dtype={dtype}\\)""" | ||||
|  | ||||
|     idx1 = Index(Categorical(["a", "b"])) | ||||
|     idx2 = Index(Categorical(["a", "b"], categories=["a", "b", "c"])) | ||||
|  | ||||
|     if check_categorical: | ||||
|         with pytest.raises(AssertionError, match=msg): | ||||
|             tm.assert_index_equal(idx1, idx2, check_categorical=check_categorical) | ||||
|     else: | ||||
|         tm.assert_index_equal(idx1, idx2, check_categorical=check_categorical) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("exact", [False, True]) | ||||
| def test_index_equal_range_categories(check_categorical, exact): | ||||
|     # GH41263 | ||||
|     msg = """\ | ||||
| Index are different | ||||
|  | ||||
| Index classes are different | ||||
| \\[left\\]:  RangeIndex\\(start=0, stop=10, step=1\\) | ||||
| \\[right\\]: Index\\(\\[0, 1, 2, 3, 4, 5, 6, 7, 8, 9\\], dtype='int64'\\)""" | ||||
|  | ||||
|     rcat = CategoricalIndex(RangeIndex(10)) | ||||
|     icat = CategoricalIndex(list(range(10))) | ||||
|  | ||||
|     if check_categorical and exact: | ||||
|         with pytest.raises(AssertionError, match=msg): | ||||
|             tm.assert_index_equal(rcat, icat, check_categorical=True, exact=True) | ||||
|     else: | ||||
|         tm.assert_index_equal( | ||||
|             rcat, icat, check_categorical=check_categorical, exact=exact | ||||
|         ) | ||||
|  | ||||
|  | ||||
| def test_assert_index_equal_different_inferred_types(): | ||||
|     # GH#31884 | ||||
|     msg = """\ | ||||
| Index are different | ||||
|  | ||||
| Attribute "inferred_type" are different | ||||
| \\[left\\]:  mixed | ||||
| \\[right\\]: datetime""" | ||||
|  | ||||
|     idx1 = Index([NA, np.datetime64("nat")]) | ||||
|     idx2 = Index([NA, NaT]) | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_index_equal(idx1, idx2) | ||||
|  | ||||
|  | ||||
| def test_assert_index_equal_different_names_check_order_false(): | ||||
|     # GH#47328 | ||||
|     idx1 = Index([1, 3], name="a") | ||||
|     idx2 = Index([3, 1], name="b") | ||||
|     with pytest.raises(AssertionError, match='"names" are different'): | ||||
|         tm.assert_index_equal(idx1, idx2, check_order=False, check_names=True) | ||||
|  | ||||
|  | ||||
| def test_assert_index_equal_mixed_dtype(): | ||||
|     # GH#39168 | ||||
|     idx = Index(["foo", "bar", 42]) | ||||
|     tm.assert_index_equal(idx, idx, check_order=False) | ||||
|  | ||||
|  | ||||
| def test_assert_index_equal_ea_dtype_order_false(any_numeric_ea_dtype): | ||||
|     # GH#47207 | ||||
|     idx1 = Index([1, 3], dtype=any_numeric_ea_dtype) | ||||
|     idx2 = Index([3, 1], dtype=any_numeric_ea_dtype) | ||||
|     tm.assert_index_equal(idx1, idx2, check_order=False) | ||||
|  | ||||
|  | ||||
| def test_assert_index_equal_object_ints_order_false(): | ||||
|     # GH#47207 | ||||
|     idx1 = Index([1, 3], dtype="object") | ||||
|     idx2 = Index([3, 1], dtype="object") | ||||
|     tm.assert_index_equal(idx1, idx2, check_order=False) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("check_categorical", [True, False]) | ||||
| @pytest.mark.parametrize("check_names", [True, False]) | ||||
| def test_assert_ea_index_equal_non_matching_na(check_names, check_categorical): | ||||
|     # GH#48608 | ||||
|     idx1 = Index([1, 2], dtype="Int64") | ||||
|     idx2 = Index([1, NA], dtype="Int64") | ||||
|     with pytest.raises(AssertionError, match="50.0 %"): | ||||
|         tm.assert_index_equal( | ||||
|             idx1, idx2, check_names=check_names, check_categorical=check_categorical | ||||
|         ) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("check_categorical", [True, False]) | ||||
| def test_assert_multi_index_dtype_check_categorical(check_categorical): | ||||
|     # GH#52126 | ||||
|     idx1 = MultiIndex.from_arrays([Categorical(np.array([1, 2], dtype=np.uint64))]) | ||||
|     idx2 = MultiIndex.from_arrays([Categorical(np.array([1, 2], dtype=np.int64))]) | ||||
|     if check_categorical: | ||||
|         with pytest.raises( | ||||
|             AssertionError, match=r"^MultiIndex level \[0\] are different" | ||||
|         ): | ||||
|             tm.assert_index_equal(idx1, idx2, check_categorical=check_categorical) | ||||
|     else: | ||||
|         tm.assert_index_equal(idx1, idx2, check_categorical=check_categorical) | ||||
| @ -0,0 +1,81 @@ | ||||
| import pytest | ||||
|  | ||||
| from pandas import interval_range | ||||
| import pandas._testing as tm | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "kwargs", | ||||
|     [ | ||||
|         {"start": 0, "periods": 4}, | ||||
|         {"start": 1, "periods": 5}, | ||||
|         {"start": 5, "end": 10, "closed": "left"}, | ||||
|     ], | ||||
| ) | ||||
| def test_interval_array_equal(kwargs): | ||||
|     arr = interval_range(**kwargs).values | ||||
|     tm.assert_interval_array_equal(arr, arr) | ||||
|  | ||||
|  | ||||
| def test_interval_array_equal_closed_mismatch(): | ||||
|     kwargs = {"start": 0, "periods": 5} | ||||
|     arr1 = interval_range(closed="left", **kwargs).values | ||||
|     arr2 = interval_range(closed="right", **kwargs).values | ||||
|  | ||||
|     msg = """\ | ||||
| IntervalArray are different | ||||
|  | ||||
| Attribute "closed" are different | ||||
| \\[left\\]:  left | ||||
| \\[right\\]: right""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_interval_array_equal(arr1, arr2) | ||||
|  | ||||
|  | ||||
| def test_interval_array_equal_periods_mismatch(): | ||||
|     kwargs = {"start": 0} | ||||
|     arr1 = interval_range(periods=5, **kwargs).values | ||||
|     arr2 = interval_range(periods=6, **kwargs).values | ||||
|  | ||||
|     msg = """\ | ||||
| IntervalArray.left are different | ||||
|  | ||||
| IntervalArray.left shapes are different | ||||
| \\[left\\]:  \\(5,\\) | ||||
| \\[right\\]: \\(6,\\)""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_interval_array_equal(arr1, arr2) | ||||
|  | ||||
|  | ||||
| def test_interval_array_equal_end_mismatch(): | ||||
|     kwargs = {"start": 0, "periods": 5} | ||||
|     arr1 = interval_range(end=10, **kwargs).values | ||||
|     arr2 = interval_range(end=20, **kwargs).values | ||||
|  | ||||
|     msg = """\ | ||||
| IntervalArray.left are different | ||||
|  | ||||
| IntervalArray.left values are different \\(80.0 %\\) | ||||
| \\[left\\]:  \\[0, 2, 4, 6, 8\\] | ||||
| \\[right\\]: \\[0, 4, 8, 12, 16\\]""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_interval_array_equal(arr1, arr2) | ||||
|  | ||||
|  | ||||
| def test_interval_array_equal_start_mismatch(): | ||||
|     kwargs = {"periods": 4} | ||||
|     arr1 = interval_range(start=0, **kwargs).values | ||||
|     arr2 = interval_range(start=1, **kwargs).values | ||||
|  | ||||
|     msg = """\ | ||||
| IntervalArray.left are different | ||||
|  | ||||
| IntervalArray.left values are different \\(100.0 %\\) | ||||
| \\[left\\]:  \\[0, 1, 2, 3\\] | ||||
| \\[right\\]: \\[1, 2, 3, 4\\]""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_interval_array_equal(arr1, arr2) | ||||
| @ -0,0 +1,223 @@ | ||||
| import copy | ||||
|  | ||||
| import numpy as np | ||||
| import pytest | ||||
|  | ||||
| import pandas as pd | ||||
| from pandas import Timestamp | ||||
| import pandas._testing as tm | ||||
|  | ||||
|  | ||||
| def test_assert_numpy_array_equal_shape_mismatch(): | ||||
|     msg = """numpy array are different | ||||
|  | ||||
| numpy array shapes are different | ||||
| \\[left\\]:  \\(2L*,\\) | ||||
| \\[right\\]: \\(3L*,\\)""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_numpy_array_equal(np.array([1, 2]), np.array([3, 4, 5])) | ||||
|  | ||||
|  | ||||
| def test_assert_numpy_array_equal_bad_type(): | ||||
|     expected = "Expected type" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=expected): | ||||
|         tm.assert_numpy_array_equal(1, 2) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "a,b,klass1,klass2", | ||||
|     [(np.array([1]), 1, "ndarray", "int"), (1, np.array([1]), "int", "ndarray")], | ||||
| ) | ||||
| def test_assert_numpy_array_equal_class_mismatch(a, b, klass1, klass2): | ||||
|     msg = f"""numpy array are different | ||||
|  | ||||
| numpy array classes are different | ||||
| \\[left\\]:  {klass1} | ||||
| \\[right\\]: {klass2}""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_numpy_array_equal(a, b) | ||||
|  | ||||
|  | ||||
| def test_assert_numpy_array_equal_value_mismatch1(): | ||||
|     msg = """numpy array are different | ||||
|  | ||||
| numpy array values are different \\(66\\.66667 %\\) | ||||
| \\[left\\]:  \\[nan, 2\\.0, 3\\.0\\] | ||||
| \\[right\\]: \\[1\\.0, nan, 3\\.0\\]""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_numpy_array_equal(np.array([np.nan, 2, 3]), np.array([1, np.nan, 3])) | ||||
|  | ||||
|  | ||||
| def test_assert_numpy_array_equal_value_mismatch2(): | ||||
|     msg = """numpy array are different | ||||
|  | ||||
| numpy array values are different \\(50\\.0 %\\) | ||||
| \\[left\\]:  \\[1, 2\\] | ||||
| \\[right\\]: \\[1, 3\\]""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_numpy_array_equal(np.array([1, 2]), np.array([1, 3])) | ||||
|  | ||||
|  | ||||
| def test_assert_numpy_array_equal_value_mismatch3(): | ||||
|     msg = """numpy array are different | ||||
|  | ||||
| numpy array values are different \\(16\\.66667 %\\) | ||||
| \\[left\\]:  \\[\\[1, 2\\], \\[3, 4\\], \\[5, 6\\]\\] | ||||
| \\[right\\]: \\[\\[1, 3\\], \\[3, 4\\], \\[5, 6\\]\\]""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_numpy_array_equal( | ||||
|             np.array([[1, 2], [3, 4], [5, 6]]), np.array([[1, 3], [3, 4], [5, 6]]) | ||||
|         ) | ||||
|  | ||||
|  | ||||
| def test_assert_numpy_array_equal_value_mismatch4(): | ||||
|     msg = """numpy array are different | ||||
|  | ||||
| numpy array values are different \\(50\\.0 %\\) | ||||
| \\[left\\]:  \\[1\\.1, 2\\.000001\\] | ||||
| \\[right\\]: \\[1\\.1, 2.0\\]""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_numpy_array_equal(np.array([1.1, 2.000001]), np.array([1.1, 2.0])) | ||||
|  | ||||
|  | ||||
| def test_assert_numpy_array_equal_value_mismatch5(): | ||||
|     msg = """numpy array are different | ||||
|  | ||||
| numpy array values are different \\(16\\.66667 %\\) | ||||
| \\[left\\]:  \\[\\[1, 2\\], \\[3, 4\\], \\[5, 6\\]\\] | ||||
| \\[right\\]: \\[\\[1, 3\\], \\[3, 4\\], \\[5, 6\\]\\]""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_numpy_array_equal( | ||||
|             np.array([[1, 2], [3, 4], [5, 6]]), np.array([[1, 3], [3, 4], [5, 6]]) | ||||
|         ) | ||||
|  | ||||
|  | ||||
| def test_assert_numpy_array_equal_value_mismatch6(): | ||||
|     msg = """numpy array are different | ||||
|  | ||||
| numpy array values are different \\(25\\.0 %\\) | ||||
| \\[left\\]:  \\[\\[1, 2\\], \\[3, 4\\]\\] | ||||
| \\[right\\]: \\[\\[1, 3\\], \\[3, 4\\]\\]""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_numpy_array_equal( | ||||
|             np.array([[1, 2], [3, 4]]), np.array([[1, 3], [3, 4]]) | ||||
|         ) | ||||
|  | ||||
|  | ||||
| def test_assert_numpy_array_equal_shape_mismatch_override(): | ||||
|     msg = """Index are different | ||||
|  | ||||
| Index shapes are different | ||||
| \\[left\\]:  \\(2L*,\\) | ||||
| \\[right\\]: \\(3L*,\\)""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_numpy_array_equal(np.array([1, 2]), np.array([3, 4, 5]), obj="Index") | ||||
|  | ||||
|  | ||||
| def test_numpy_array_equal_unicode(): | ||||
|     # see gh-20503 | ||||
|     # | ||||
|     # Test ensures that `tm.assert_numpy_array_equals` raises the right | ||||
|     # exception when comparing np.arrays containing differing unicode objects. | ||||
|     msg = """numpy array are different | ||||
|  | ||||
| numpy array values are different \\(33\\.33333 %\\) | ||||
| \\[left\\]:  \\[á, à, ä\\] | ||||
| \\[right\\]: \\[á, à, å\\]""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_numpy_array_equal( | ||||
|             np.array(["á", "à", "ä"]), np.array(["á", "à", "å"]) | ||||
|         ) | ||||
|  | ||||
|  | ||||
| def test_numpy_array_equal_object(): | ||||
|     a = np.array([Timestamp("2011-01-01"), Timestamp("2011-01-01")]) | ||||
|     b = np.array([Timestamp("2011-01-01"), Timestamp("2011-01-02")]) | ||||
|  | ||||
|     msg = """numpy array are different | ||||
|  | ||||
| numpy array values are different \\(50\\.0 %\\) | ||||
| \\[left\\]:  \\[2011-01-01 00:00:00, 2011-01-01 00:00:00\\] | ||||
| \\[right\\]: \\[2011-01-01 00:00:00, 2011-01-02 00:00:00\\]""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_numpy_array_equal(a, b) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("other_type", ["same", "copy"]) | ||||
| @pytest.mark.parametrize("check_same", ["same", "copy"]) | ||||
| def test_numpy_array_equal_copy_flag(other_type, check_same): | ||||
|     a = np.array([1, 2, 3]) | ||||
|     msg = None | ||||
|  | ||||
|     if other_type == "same": | ||||
|         other = a.view() | ||||
|     else: | ||||
|         other = a.copy() | ||||
|  | ||||
|     if check_same != other_type: | ||||
|         msg = ( | ||||
|             r"array\(\[1, 2, 3\]\) is not array\(\[1, 2, 3\]\)" | ||||
|             if check_same == "same" | ||||
|             else r"array\(\[1, 2, 3\]\) is array\(\[1, 2, 3\]\)" | ||||
|         ) | ||||
|  | ||||
|     if msg is not None: | ||||
|         with pytest.raises(AssertionError, match=msg): | ||||
|             tm.assert_numpy_array_equal(a, other, check_same=check_same) | ||||
|     else: | ||||
|         tm.assert_numpy_array_equal(a, other, check_same=check_same) | ||||
|  | ||||
|  | ||||
| def test_numpy_array_equal_contains_na(): | ||||
|     # https://github.com/pandas-dev/pandas/issues/31881 | ||||
|     a = np.array([True, False]) | ||||
|     b = np.array([True, pd.NA], dtype=object) | ||||
|  | ||||
|     msg = """numpy array are different | ||||
|  | ||||
| numpy array values are different \\(50.0 %\\) | ||||
| \\[left\\]:  \\[True, False\\] | ||||
| \\[right\\]: \\[True, <NA>\\]""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_numpy_array_equal(a, b) | ||||
|  | ||||
|  | ||||
| def test_numpy_array_equal_identical_na(nulls_fixture): | ||||
|     a = np.array([nulls_fixture], dtype=object) | ||||
|  | ||||
|     tm.assert_numpy_array_equal(a, a) | ||||
|  | ||||
|     # matching but not the identical object | ||||
|     if hasattr(nulls_fixture, "copy"): | ||||
|         other = nulls_fixture.copy() | ||||
|     else: | ||||
|         other = copy.copy(nulls_fixture) | ||||
|     b = np.array([other], dtype=object) | ||||
|     tm.assert_numpy_array_equal(a, b) | ||||
|  | ||||
|  | ||||
| def test_numpy_array_equal_different_na(): | ||||
|     a = np.array([np.nan], dtype=object) | ||||
|     b = np.array([pd.NA], dtype=object) | ||||
|  | ||||
|     msg = """numpy array are different | ||||
|  | ||||
| numpy array values are different \\(100.0 %\\) | ||||
| \\[left\\]:  \\[nan\\] | ||||
| \\[right\\]: \\[<NA>\\]""" | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_numpy_array_equal(a, b) | ||||
| @ -0,0 +1,241 @@ | ||||
| """" | ||||
| Test module for testing ``pandas._testing.assert_produces_warning``. | ||||
| """ | ||||
| import warnings | ||||
|  | ||||
| import pytest | ||||
|  | ||||
| from pandas.errors import ( | ||||
|     DtypeWarning, | ||||
|     PerformanceWarning, | ||||
| ) | ||||
|  | ||||
| import pandas._testing as tm | ||||
|  | ||||
|  | ||||
| @pytest.fixture( | ||||
|     params=[ | ||||
|         RuntimeWarning, | ||||
|         ResourceWarning, | ||||
|         UserWarning, | ||||
|         FutureWarning, | ||||
|         DeprecationWarning, | ||||
|         PerformanceWarning, | ||||
|         DtypeWarning, | ||||
|     ], | ||||
| ) | ||||
| def category(request): | ||||
|     """ | ||||
|     Return unique warning. | ||||
|  | ||||
|     Useful for testing behavior of tm.assert_produces_warning with various categories. | ||||
|     """ | ||||
|     return request.param | ||||
|  | ||||
|  | ||||
| @pytest.fixture( | ||||
|     params=[ | ||||
|         (RuntimeWarning, UserWarning), | ||||
|         (UserWarning, FutureWarning), | ||||
|         (FutureWarning, RuntimeWarning), | ||||
|         (DeprecationWarning, PerformanceWarning), | ||||
|         (PerformanceWarning, FutureWarning), | ||||
|         (DtypeWarning, DeprecationWarning), | ||||
|         (ResourceWarning, DeprecationWarning), | ||||
|         (FutureWarning, DeprecationWarning), | ||||
|     ], | ||||
|     ids=lambda x: type(x).__name__, | ||||
| ) | ||||
| def pair_different_warnings(request): | ||||
|     """ | ||||
|     Return pair or different warnings. | ||||
|  | ||||
|     Useful for testing how several different warnings are handled | ||||
|     in tm.assert_produces_warning. | ||||
|     """ | ||||
|     return request.param | ||||
|  | ||||
|  | ||||
| def f(): | ||||
|     warnings.warn("f1", FutureWarning) | ||||
|     warnings.warn("f2", RuntimeWarning) | ||||
|  | ||||
|  | ||||
| @pytest.mark.filterwarnings("ignore:f1:FutureWarning") | ||||
| def test_assert_produces_warning_honors_filter(): | ||||
|     # Raise by default. | ||||
|     msg = r"Caused unexpected warning\(s\)" | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         with tm.assert_produces_warning(RuntimeWarning): | ||||
|             f() | ||||
|  | ||||
|     with tm.assert_produces_warning(RuntimeWarning, raise_on_extra_warnings=False): | ||||
|         f() | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "message, match", | ||||
|     [ | ||||
|         ("", None), | ||||
|         ("", ""), | ||||
|         ("Warning message", r".*"), | ||||
|         ("Warning message", "War"), | ||||
|         ("Warning message", r"[Ww]arning"), | ||||
|         ("Warning message", "age"), | ||||
|         ("Warning message", r"age$"), | ||||
|         ("Message 12-234 with numbers", r"\d{2}-\d{3}"), | ||||
|         ("Message 12-234 with numbers", r"^Mes.*\d{2}-\d{3}"), | ||||
|         ("Message 12-234 with numbers", r"\d{2}-\d{3}\s\S+"), | ||||
|         ("Message, which we do not match", None), | ||||
|     ], | ||||
| ) | ||||
| def test_catch_warning_category_and_match(category, message, match): | ||||
|     with tm.assert_produces_warning(category, match=match): | ||||
|         warnings.warn(message, category) | ||||
|  | ||||
|  | ||||
| def test_fail_to_match_runtime_warning(): | ||||
|     category = RuntimeWarning | ||||
|     match = "Did not see this warning" | ||||
|     unmatched = ( | ||||
|         r"Did not see warning 'RuntimeWarning' matching 'Did not see this warning'. " | ||||
|         r"The emitted warning messages are " | ||||
|         r"\[RuntimeWarning\('This is not a match.'\), " | ||||
|         r"RuntimeWarning\('Another unmatched warning.'\)\]" | ||||
|     ) | ||||
|     with pytest.raises(AssertionError, match=unmatched): | ||||
|         with tm.assert_produces_warning(category, match=match): | ||||
|             warnings.warn("This is not a match.", category) | ||||
|             warnings.warn("Another unmatched warning.", category) | ||||
|  | ||||
|  | ||||
| def test_fail_to_match_future_warning(): | ||||
|     category = FutureWarning | ||||
|     match = "Warning" | ||||
|     unmatched = ( | ||||
|         r"Did not see warning 'FutureWarning' matching 'Warning'. " | ||||
|         r"The emitted warning messages are " | ||||
|         r"\[FutureWarning\('This is not a match.'\), " | ||||
|         r"FutureWarning\('Another unmatched warning.'\)\]" | ||||
|     ) | ||||
|     with pytest.raises(AssertionError, match=unmatched): | ||||
|         with tm.assert_produces_warning(category, match=match): | ||||
|             warnings.warn("This is not a match.", category) | ||||
|             warnings.warn("Another unmatched warning.", category) | ||||
|  | ||||
|  | ||||
| def test_fail_to_match_resource_warning(): | ||||
|     category = ResourceWarning | ||||
|     match = r"\d+" | ||||
|     unmatched = ( | ||||
|         r"Did not see warning 'ResourceWarning' matching '\\d\+'. " | ||||
|         r"The emitted warning messages are " | ||||
|         r"\[ResourceWarning\('This is not a match.'\), " | ||||
|         r"ResourceWarning\('Another unmatched warning.'\)\]" | ||||
|     ) | ||||
|     with pytest.raises(AssertionError, match=unmatched): | ||||
|         with tm.assert_produces_warning(category, match=match): | ||||
|             warnings.warn("This is not a match.", category) | ||||
|             warnings.warn("Another unmatched warning.", category) | ||||
|  | ||||
|  | ||||
| def test_fail_to_catch_actual_warning(pair_different_warnings): | ||||
|     expected_category, actual_category = pair_different_warnings | ||||
|     match = "Did not see expected warning of class" | ||||
|     with pytest.raises(AssertionError, match=match): | ||||
|         with tm.assert_produces_warning(expected_category): | ||||
|             warnings.warn("warning message", actual_category) | ||||
|  | ||||
|  | ||||
| def test_ignore_extra_warning(pair_different_warnings): | ||||
|     expected_category, extra_category = pair_different_warnings | ||||
|     with tm.assert_produces_warning(expected_category, raise_on_extra_warnings=False): | ||||
|         warnings.warn("Expected warning", expected_category) | ||||
|         warnings.warn("Unexpected warning OK", extra_category) | ||||
|  | ||||
|  | ||||
| def test_raise_on_extra_warning(pair_different_warnings): | ||||
|     expected_category, extra_category = pair_different_warnings | ||||
|     match = r"Caused unexpected warning\(s\)" | ||||
|     with pytest.raises(AssertionError, match=match): | ||||
|         with tm.assert_produces_warning(expected_category): | ||||
|             warnings.warn("Expected warning", expected_category) | ||||
|             warnings.warn("Unexpected warning NOT OK", extra_category) | ||||
|  | ||||
|  | ||||
| def test_same_category_different_messages_first_match(): | ||||
|     category = UserWarning | ||||
|     with tm.assert_produces_warning(category, match=r"^Match this"): | ||||
|         warnings.warn("Match this", category) | ||||
|         warnings.warn("Do not match that", category) | ||||
|         warnings.warn("Do not match that either", category) | ||||
|  | ||||
|  | ||||
| def test_same_category_different_messages_last_match(): | ||||
|     category = DeprecationWarning | ||||
|     with tm.assert_produces_warning(category, match=r"^Match this"): | ||||
|         warnings.warn("Do not match that", category) | ||||
|         warnings.warn("Do not match that either", category) | ||||
|         warnings.warn("Match this", category) | ||||
|  | ||||
|  | ||||
| def test_match_multiple_warnings(): | ||||
|     # https://github.com/pandas-dev/pandas/issues/47829 | ||||
|     category = (FutureWarning, UserWarning) | ||||
|     with tm.assert_produces_warning(category, match=r"^Match this"): | ||||
|         warnings.warn("Match this", FutureWarning) | ||||
|         warnings.warn("Match this too", UserWarning) | ||||
|  | ||||
|  | ||||
| def test_right_category_wrong_match_raises(pair_different_warnings): | ||||
|     target_category, other_category = pair_different_warnings | ||||
|     with pytest.raises(AssertionError, match="Did not see warning.*matching"): | ||||
|         with tm.assert_produces_warning(target_category, match=r"^Match this"): | ||||
|             warnings.warn("Do not match it", target_category) | ||||
|             warnings.warn("Match this", other_category) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("false_or_none", [False, None]) | ||||
| class TestFalseOrNoneExpectedWarning: | ||||
|     def test_raise_on_warning(self, false_or_none): | ||||
|         msg = r"Caused unexpected warning\(s\)" | ||||
|         with pytest.raises(AssertionError, match=msg): | ||||
|             with tm.assert_produces_warning(false_or_none): | ||||
|                 f() | ||||
|  | ||||
|     def test_no_raise_without_warning(self, false_or_none): | ||||
|         with tm.assert_produces_warning(false_or_none): | ||||
|             pass | ||||
|  | ||||
|     def test_no_raise_with_false_raise_on_extra(self, false_or_none): | ||||
|         with tm.assert_produces_warning(false_or_none, raise_on_extra_warnings=False): | ||||
|             f() | ||||
|  | ||||
|  | ||||
| def test_raises_during_exception(): | ||||
|     msg = "Did not see expected warning of class 'UserWarning'" | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         with tm.assert_produces_warning(UserWarning): | ||||
|             raise ValueError | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         with tm.assert_produces_warning(UserWarning): | ||||
|             warnings.warn("FutureWarning", FutureWarning) | ||||
|             raise IndexError | ||||
|  | ||||
|     msg = "Caused unexpected warning" | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         with tm.assert_produces_warning(None): | ||||
|             warnings.warn("FutureWarning", FutureWarning) | ||||
|             raise SystemError | ||||
|  | ||||
|  | ||||
| def test_passes_during_exception(): | ||||
|     with pytest.raises(SyntaxError, match="Error"): | ||||
|         with tm.assert_produces_warning(None): | ||||
|             raise SyntaxError("Error") | ||||
|  | ||||
|     with pytest.raises(ValueError, match="Error"): | ||||
|         with tm.assert_produces_warning(FutureWarning, match="FutureWarning"): | ||||
|             warnings.warn("FutureWarning", FutureWarning) | ||||
|             raise ValueError("Error") | ||||
| @ -0,0 +1,475 @@ | ||||
| import numpy as np | ||||
| import pytest | ||||
|  | ||||
| import pandas as pd | ||||
| from pandas import ( | ||||
|     Categorical, | ||||
|     DataFrame, | ||||
|     Series, | ||||
| ) | ||||
| import pandas._testing as tm | ||||
|  | ||||
|  | ||||
| def _assert_series_equal_both(a, b, **kwargs): | ||||
|     """ | ||||
|     Check that two Series equal. | ||||
|  | ||||
|     This check is performed commutatively. | ||||
|  | ||||
|     Parameters | ||||
|     ---------- | ||||
|     a : Series | ||||
|         The first Series to compare. | ||||
|     b : Series | ||||
|         The second Series to compare. | ||||
|     kwargs : dict | ||||
|         The arguments passed to `tm.assert_series_equal`. | ||||
|     """ | ||||
|     tm.assert_series_equal(a, b, **kwargs) | ||||
|     tm.assert_series_equal(b, a, **kwargs) | ||||
|  | ||||
|  | ||||
| def _assert_not_series_equal(a, b, **kwargs): | ||||
|     """ | ||||
|     Check that two Series are not equal. | ||||
|  | ||||
|     Parameters | ||||
|     ---------- | ||||
|     a : Series | ||||
|         The first Series to compare. | ||||
|     b : Series | ||||
|         The second Series to compare. | ||||
|     kwargs : dict | ||||
|         The arguments passed to `tm.assert_series_equal`. | ||||
|     """ | ||||
|     try: | ||||
|         tm.assert_series_equal(a, b, **kwargs) | ||||
|         msg = "The two Series were equal when they shouldn't have been" | ||||
|  | ||||
|         pytest.fail(msg=msg) | ||||
|     except AssertionError: | ||||
|         pass | ||||
|  | ||||
|  | ||||
| def _assert_not_series_equal_both(a, b, **kwargs): | ||||
|     """ | ||||
|     Check that two Series are not equal. | ||||
|  | ||||
|     This check is performed commutatively. | ||||
|  | ||||
|     Parameters | ||||
|     ---------- | ||||
|     a : Series | ||||
|         The first Series to compare. | ||||
|     b : Series | ||||
|         The second Series to compare. | ||||
|     kwargs : dict | ||||
|         The arguments passed to `tm.assert_series_equal`. | ||||
|     """ | ||||
|     _assert_not_series_equal(a, b, **kwargs) | ||||
|     _assert_not_series_equal(b, a, **kwargs) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("data", [range(3), list("abc"), list("áàä")]) | ||||
| def test_series_equal(data): | ||||
|     _assert_series_equal_both(Series(data), Series(data)) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "data1,data2", | ||||
|     [ | ||||
|         (range(3), range(1, 4)), | ||||
|         (list("abc"), list("xyz")), | ||||
|         (list("áàä"), list("éèë")), | ||||
|         (list("áàä"), list(b"aaa")), | ||||
|         (range(3), range(4)), | ||||
|     ], | ||||
| ) | ||||
| def test_series_not_equal_value_mismatch(data1, data2): | ||||
|     _assert_not_series_equal_both(Series(data1), Series(data2)) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "kwargs", | ||||
|     [ | ||||
|         {"dtype": "float64"},  # dtype mismatch | ||||
|         {"index": [1, 2, 4]},  # index mismatch | ||||
|         {"name": "foo"},  # name mismatch | ||||
|     ], | ||||
| ) | ||||
| def test_series_not_equal_metadata_mismatch(kwargs): | ||||
|     data = range(3) | ||||
|     s1 = Series(data) | ||||
|  | ||||
|     s2 = Series(data, **kwargs) | ||||
|     _assert_not_series_equal_both(s1, s2) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("data1,data2", [(0.12345, 0.12346), (0.1235, 0.1236)]) | ||||
| @pytest.mark.parametrize("dtype", ["float32", "float64", "Float32"]) | ||||
| @pytest.mark.parametrize("decimals", [0, 1, 2, 3, 5, 10]) | ||||
| def test_less_precise(data1, data2, dtype, decimals): | ||||
|     rtol = 10**-decimals | ||||
|     s1 = Series([data1], dtype=dtype) | ||||
|     s2 = Series([data2], dtype=dtype) | ||||
|  | ||||
|     if decimals in (5, 10) or (decimals >= 3 and abs(data1 - data2) >= 0.0005): | ||||
|         msg = "Series values are different" | ||||
|         with pytest.raises(AssertionError, match=msg): | ||||
|             tm.assert_series_equal(s1, s2, rtol=rtol) | ||||
|     else: | ||||
|         _assert_series_equal_both(s1, s2, rtol=rtol) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "s1,s2,msg", | ||||
|     [ | ||||
|         # Index | ||||
|         ( | ||||
|             Series(["l1", "l2"], index=[1, 2]), | ||||
|             Series(["l1", "l2"], index=[1.0, 2.0]), | ||||
|             "Series\\.index are different", | ||||
|         ), | ||||
|         # MultiIndex | ||||
|         ( | ||||
|             DataFrame.from_records( | ||||
|                 {"a": [1, 2], "b": [2.1, 1.5], "c": ["l1", "l2"]}, index=["a", "b"] | ||||
|             ).c, | ||||
|             DataFrame.from_records( | ||||
|                 {"a": [1.0, 2.0], "b": [2.1, 1.5], "c": ["l1", "l2"]}, index=["a", "b"] | ||||
|             ).c, | ||||
|             "MultiIndex level \\[0\\] are different", | ||||
|         ), | ||||
|     ], | ||||
| ) | ||||
| def test_series_equal_index_dtype(s1, s2, msg, check_index_type): | ||||
|     kwargs = {"check_index_type": check_index_type} | ||||
|  | ||||
|     if check_index_type: | ||||
|         with pytest.raises(AssertionError, match=msg): | ||||
|             tm.assert_series_equal(s1, s2, **kwargs) | ||||
|     else: | ||||
|         tm.assert_series_equal(s1, s2, **kwargs) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("check_like", [True, False]) | ||||
| def test_series_equal_order_mismatch(check_like): | ||||
|     s1 = Series([1, 2, 3], index=["a", "b", "c"]) | ||||
|     s2 = Series([3, 2, 1], index=["c", "b", "a"]) | ||||
|  | ||||
|     if not check_like:  # Do not ignore index ordering. | ||||
|         with pytest.raises(AssertionError, match="Series.index are different"): | ||||
|             tm.assert_series_equal(s1, s2, check_like=check_like) | ||||
|     else: | ||||
|         _assert_series_equal_both(s1, s2, check_like=check_like) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("check_index", [True, False]) | ||||
| def test_series_equal_index_mismatch(check_index): | ||||
|     s1 = Series([1, 2, 3], index=["a", "b", "c"]) | ||||
|     s2 = Series([1, 2, 3], index=["c", "b", "a"]) | ||||
|  | ||||
|     if check_index:  # Do not ignore index. | ||||
|         with pytest.raises(AssertionError, match="Series.index are different"): | ||||
|             tm.assert_series_equal(s1, s2, check_index=check_index) | ||||
|     else: | ||||
|         _assert_series_equal_both(s1, s2, check_index=check_index) | ||||
|  | ||||
|  | ||||
| def test_series_invalid_param_combination(): | ||||
|     left = Series(dtype=object) | ||||
|     right = Series(dtype=object) | ||||
|     with pytest.raises( | ||||
|         ValueError, match="check_like must be False if check_index is False" | ||||
|     ): | ||||
|         tm.assert_series_equal(left, right, check_index=False, check_like=True) | ||||
|  | ||||
|  | ||||
| def test_series_equal_length_mismatch(rtol): | ||||
|     msg = """Series are different | ||||
|  | ||||
| Series length are different | ||||
| \\[left\\]:  3, RangeIndex\\(start=0, stop=3, step=1\\) | ||||
| \\[right\\]: 4, RangeIndex\\(start=0, stop=4, step=1\\)""" | ||||
|  | ||||
|     s1 = Series([1, 2, 3]) | ||||
|     s2 = Series([1, 2, 3, 4]) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_series_equal(s1, s2, rtol=rtol) | ||||
|  | ||||
|  | ||||
| def test_series_equal_numeric_values_mismatch(rtol): | ||||
|     msg = """Series are different | ||||
|  | ||||
| Series values are different \\(33\\.33333 %\\) | ||||
| \\[index\\]: \\[0, 1, 2\\] | ||||
| \\[left\\]:  \\[1, 2, 3\\] | ||||
| \\[right\\]: \\[1, 2, 4\\]""" | ||||
|  | ||||
|     s1 = Series([1, 2, 3]) | ||||
|     s2 = Series([1, 2, 4]) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_series_equal(s1, s2, rtol=rtol) | ||||
|  | ||||
|  | ||||
| def test_series_equal_categorical_values_mismatch(rtol, using_infer_string): | ||||
|     dtype = "str" if using_infer_string else "object" | ||||
|     msg = f"""Series are different | ||||
|  | ||||
| Series values are different \\(66\\.66667 %\\) | ||||
| \\[index\\]: \\[0, 1, 2\\] | ||||
| \\[left\\]:  \\['a', 'b', 'c'\\] | ||||
| Categories \\(3, {dtype}\\): \\['a', 'b', 'c'\\] | ||||
| \\[right\\]: \\['a', 'c', 'b'\\] | ||||
| Categories \\(3, {dtype}\\): \\['a', 'b', 'c'\\]""" | ||||
|  | ||||
|     s1 = Series(Categorical(["a", "b", "c"])) | ||||
|     s2 = Series(Categorical(["a", "c", "b"])) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_series_equal(s1, s2, rtol=rtol) | ||||
|  | ||||
|  | ||||
| def test_series_equal_datetime_values_mismatch(rtol): | ||||
|     msg = """Series are different | ||||
|  | ||||
| Series values are different \\(100.0 %\\) | ||||
| \\[index\\]: \\[0, 1, 2\\] | ||||
| \\[left\\]:  \\[1514764800000000000, 1514851200000000000, 1514937600000000000\\] | ||||
| \\[right\\]: \\[1549065600000000000, 1549152000000000000, 1549238400000000000\\]""" | ||||
|  | ||||
|     s1 = Series(pd.date_range("2018-01-01", periods=3, freq="D")) | ||||
|     s2 = Series(pd.date_range("2019-02-02", periods=3, freq="D")) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_series_equal(s1, s2, rtol=rtol) | ||||
|  | ||||
|  | ||||
| def test_series_equal_categorical_mismatch(check_categorical, using_infer_string): | ||||
|     if using_infer_string: | ||||
|         dtype = "str" | ||||
|     else: | ||||
|         dtype = "object" | ||||
|     msg = f"""Attributes of Series are different | ||||
|  | ||||
| Attribute "dtype" are different | ||||
| \\[left\\]:  CategoricalDtype\\(categories=\\['a', 'b'\\], ordered=False, \ | ||||
| categories_dtype={dtype}\\) | ||||
| \\[right\\]: CategoricalDtype\\(categories=\\['a', 'b', 'c'\\], \ | ||||
| ordered=False, categories_dtype={dtype}\\)""" | ||||
|  | ||||
|     s1 = Series(Categorical(["a", "b"])) | ||||
|     s2 = Series(Categorical(["a", "b"], categories=list("abc"))) | ||||
|  | ||||
|     if check_categorical: | ||||
|         with pytest.raises(AssertionError, match=msg): | ||||
|             tm.assert_series_equal(s1, s2, check_categorical=check_categorical) | ||||
|     else: | ||||
|         _assert_series_equal_both(s1, s2, check_categorical=check_categorical) | ||||
|  | ||||
|  | ||||
| def test_assert_series_equal_extension_dtype_mismatch(): | ||||
|     # https://github.com/pandas-dev/pandas/issues/32747 | ||||
|     left = Series(pd.array([1, 2, 3], dtype="Int64")) | ||||
|     right = left.astype(int) | ||||
|  | ||||
|     msg = """Attributes of Series are different | ||||
|  | ||||
| Attribute "dtype" are different | ||||
| \\[left\\]:  Int64 | ||||
| \\[right\\]: int[32|64]""" | ||||
|  | ||||
|     tm.assert_series_equal(left, right, check_dtype=False) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_series_equal(left, right, check_dtype=True) | ||||
|  | ||||
|  | ||||
| def test_assert_series_equal_interval_dtype_mismatch(): | ||||
|     # https://github.com/pandas-dev/pandas/issues/32747 | ||||
|     left = Series([pd.Interval(0, 1)], dtype="interval") | ||||
|     right = left.astype(object) | ||||
|  | ||||
|     msg = """Attributes of Series are different | ||||
|  | ||||
| Attribute "dtype" are different | ||||
| \\[left\\]:  interval\\[int64, right\\] | ||||
| \\[right\\]: object""" | ||||
|  | ||||
|     tm.assert_series_equal(left, right, check_dtype=False) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_series_equal(left, right, check_dtype=True) | ||||
|  | ||||
|  | ||||
| def test_series_equal_series_type(): | ||||
|     class MySeries(Series): | ||||
|         pass | ||||
|  | ||||
|     s1 = Series([1, 2]) | ||||
|     s2 = Series([1, 2]) | ||||
|     s3 = MySeries([1, 2]) | ||||
|  | ||||
|     tm.assert_series_equal(s1, s2, check_series_type=False) | ||||
|     tm.assert_series_equal(s1, s2, check_series_type=True) | ||||
|  | ||||
|     tm.assert_series_equal(s1, s3, check_series_type=False) | ||||
|     tm.assert_series_equal(s3, s1, check_series_type=False) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match="Series classes are different"): | ||||
|         tm.assert_series_equal(s1, s3, check_series_type=True) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match="Series classes are different"): | ||||
|         tm.assert_series_equal(s3, s1, check_series_type=True) | ||||
|  | ||||
|  | ||||
| def test_series_equal_exact_for_nonnumeric(): | ||||
|     # https://github.com/pandas-dev/pandas/issues/35446 | ||||
|     s1 = Series(["a", "b"]) | ||||
|     s2 = Series(["a", "b"]) | ||||
|     s3 = Series(["b", "a"]) | ||||
|  | ||||
|     tm.assert_series_equal(s1, s2, check_exact=True) | ||||
|     tm.assert_series_equal(s2, s1, check_exact=True) | ||||
|  | ||||
|     msg = """Series are different | ||||
|  | ||||
| Series values are different \\(100\\.0 %\\) | ||||
| \\[index\\]: \\[0, 1\\] | ||||
| \\[left\\]:  \\[a, b\\] | ||||
| \\[right\\]: \\[b, a\\]""" | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_series_equal(s1, s3, check_exact=True) | ||||
|  | ||||
|     msg = """Series are different | ||||
|  | ||||
| Series values are different \\(100\\.0 %\\) | ||||
| \\[index\\]: \\[0, 1\\] | ||||
| \\[left\\]:  \\[b, a\\] | ||||
| \\[right\\]: \\[a, b\\]""" | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         tm.assert_series_equal(s3, s1, check_exact=True) | ||||
|  | ||||
|  | ||||
| def test_assert_series_equal_ignore_extension_dtype_mismatch(): | ||||
|     # https://github.com/pandas-dev/pandas/issues/35715 | ||||
|     left = Series([1, 2, 3], dtype="Int64") | ||||
|     right = Series([1, 2, 3], dtype="Int32") | ||||
|     tm.assert_series_equal(left, right, check_dtype=False) | ||||
|  | ||||
|  | ||||
| def test_assert_series_equal_ignore_extension_dtype_mismatch_cross_class(): | ||||
|     # https://github.com/pandas-dev/pandas/issues/35715 | ||||
|     left = Series([1, 2, 3], dtype="Int64") | ||||
|     right = Series([1, 2, 3], dtype="int64") | ||||
|     tm.assert_series_equal(left, right, check_dtype=False) | ||||
|  | ||||
|  | ||||
| def test_allows_duplicate_labels(): | ||||
|     left = Series([1]) | ||||
|     right = Series([1]).set_flags(allows_duplicate_labels=False) | ||||
|     tm.assert_series_equal(left, left) | ||||
|     tm.assert_series_equal(right, right) | ||||
|     tm.assert_series_equal(left, right, check_flags=False) | ||||
|     tm.assert_series_equal(right, left, check_flags=False) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match="<Flags"): | ||||
|         tm.assert_series_equal(left, right) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match="<Flags"): | ||||
|         tm.assert_series_equal(left, right) | ||||
|  | ||||
|  | ||||
| def test_assert_series_equal_identical_na(nulls_fixture): | ||||
|     ser = Series([nulls_fixture]) | ||||
|  | ||||
|     tm.assert_series_equal(ser, ser.copy()) | ||||
|  | ||||
|     # while we're here do Index too | ||||
|     idx = pd.Index(ser) | ||||
|     tm.assert_index_equal(idx, idx.copy(deep=True)) | ||||
|  | ||||
|  | ||||
| def test_identical_nested_series_is_equal(): | ||||
|     # GH#22400 | ||||
|     x = Series( | ||||
|         [ | ||||
|             0, | ||||
|             0.0131142231938, | ||||
|             1.77774652865e-05, | ||||
|             np.array([0.4722720840328748, 0.4216929783681722]), | ||||
|         ] | ||||
|     ) | ||||
|     y = Series( | ||||
|         [ | ||||
|             0, | ||||
|             0.0131142231938, | ||||
|             1.77774652865e-05, | ||||
|             np.array([0.4722720840328748, 0.4216929783681722]), | ||||
|         ] | ||||
|     ) | ||||
|     # These two arrays should be equal, nesting could cause issue | ||||
|  | ||||
|     tm.assert_series_equal(x, x) | ||||
|     tm.assert_series_equal(x, x, check_exact=True) | ||||
|     tm.assert_series_equal(x, y) | ||||
|     tm.assert_series_equal(x, y, check_exact=True) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("dtype", ["datetime64", "timedelta64"]) | ||||
| def test_check_dtype_false_different_reso(dtype): | ||||
|     # GH 52449 | ||||
|     ser_s = Series([1000213, 2131232, 21312331]).astype(f"{dtype}[s]") | ||||
|     ser_ms = ser_s.astype(f"{dtype}[ms]") | ||||
|     with pytest.raises(AssertionError, match="Attributes of Series are different"): | ||||
|         tm.assert_series_equal(ser_s, ser_ms) | ||||
|     tm.assert_series_equal(ser_ms, ser_s, check_dtype=False) | ||||
|  | ||||
|     ser_ms -= Series([1, 1, 1]).astype(f"{dtype}[ms]") | ||||
|  | ||||
|     with pytest.raises(AssertionError, match="Series are different"): | ||||
|         tm.assert_series_equal(ser_s, ser_ms) | ||||
|  | ||||
|     with pytest.raises(AssertionError, match="Series are different"): | ||||
|         tm.assert_series_equal(ser_s, ser_ms, check_dtype=False) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("dtype", ["Int64", "int64"]) | ||||
| def test_large_unequal_ints(dtype): | ||||
|     # https://github.com/pandas-dev/pandas/issues/55882 | ||||
|     left = Series([1577840521123000], dtype=dtype) | ||||
|     right = Series([1577840521123543], dtype=dtype) | ||||
|     with pytest.raises(AssertionError, match="Series are different"): | ||||
|         tm.assert_series_equal(left, right) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("dtype", [None, object]) | ||||
| @pytest.mark.parametrize("check_exact", [True, False]) | ||||
| @pytest.mark.parametrize("val", [3, 3.5]) | ||||
| def test_ea_and_numpy_no_dtype_check(val, check_exact, dtype): | ||||
|     # GH#56651 | ||||
|     left = Series([1, 2, val], dtype=dtype) | ||||
|     right = Series(pd.array([1, 2, val])) | ||||
|     tm.assert_series_equal(left, right, check_dtype=False, check_exact=check_exact) | ||||
|  | ||||
|  | ||||
| def test_assert_series_equal_int_tol(): | ||||
|     # GH#56646 | ||||
|     left = Series([81, 18, 121, 38, 74, 72, 81, 81, 146, 81, 81, 170, 74, 74]) | ||||
|     right = Series([72, 9, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72]) | ||||
|     tm.assert_series_equal(left, right, rtol=1.5) | ||||
|  | ||||
|     tm.assert_frame_equal(left.to_frame(), right.to_frame(), rtol=1.5) | ||||
|     tm.assert_extension_array_equal( | ||||
|         left.astype("Int64").values, right.astype("Int64").values, rtol=1.5 | ||||
|     ) | ||||
|  | ||||
|  | ||||
| def test_assert_series_equal_index_exact_default(): | ||||
|     # GH#57067 | ||||
|     ser1 = Series(np.zeros(6, dtype=int), [0, 0.2, 0.4, 0.6, 0.8, 1]) | ||||
|     ser2 = Series(np.zeros(6, dtype=int), np.linspace(0, 1, 6)) | ||||
|     tm.assert_series_equal(ser1, ser2) | ||||
|     tm.assert_frame_equal(ser1.to_frame(), ser2.to_frame()) | ||||
| @ -0,0 +1,63 @@ | ||||
| from textwrap import dedent | ||||
|  | ||||
| import pytest | ||||
|  | ||||
| from pandas.util._decorators import deprecate | ||||
|  | ||||
| import pandas._testing as tm | ||||
|  | ||||
|  | ||||
| def new_func(): | ||||
|     """ | ||||
|     This is the summary. The deprecate directive goes next. | ||||
|  | ||||
|     This is the extended summary. The deprecate directive goes before this. | ||||
|     """ | ||||
|     return "new_func called" | ||||
|  | ||||
|  | ||||
| def new_func_no_docstring(): | ||||
|     return "new_func_no_docstring called" | ||||
|  | ||||
|  | ||||
| def new_func_wrong_docstring(): | ||||
|     """Summary should be in the next line.""" | ||||
|     return "new_func_wrong_docstring called" | ||||
|  | ||||
|  | ||||
| def new_func_with_deprecation(): | ||||
|     """ | ||||
|     This is the summary. The deprecate directive goes next. | ||||
|  | ||||
|     .. deprecated:: 1.0 | ||||
|         Use new_func instead. | ||||
|  | ||||
|     This is the extended summary. The deprecate directive goes before this. | ||||
|     """ | ||||
|  | ||||
|  | ||||
| def test_deprecate_ok(): | ||||
|     depr_func = deprecate("depr_func", new_func, "1.0", msg="Use new_func instead.") | ||||
|  | ||||
|     with tm.assert_produces_warning(FutureWarning): | ||||
|         result = depr_func() | ||||
|  | ||||
|     assert result == "new_func called" | ||||
|     assert depr_func.__doc__ == dedent(new_func_with_deprecation.__doc__) | ||||
|  | ||||
|  | ||||
| def test_deprecate_no_docstring(): | ||||
|     depr_func = deprecate( | ||||
|         "depr_func", new_func_no_docstring, "1.0", msg="Use new_func instead." | ||||
|     ) | ||||
|     with tm.assert_produces_warning(FutureWarning): | ||||
|         result = depr_func() | ||||
|     assert result == "new_func_no_docstring called" | ||||
|  | ||||
|  | ||||
| def test_deprecate_wrong_docstring(): | ||||
|     msg = "deprecate needs a correctly formatted docstring" | ||||
|     with pytest.raises(AssertionError, match=msg): | ||||
|         deprecate( | ||||
|             "depr_func", new_func_wrong_docstring, "1.0", msg="Use new_func instead." | ||||
|         ) | ||||
| @ -0,0 +1,90 @@ | ||||
| import pytest | ||||
|  | ||||
| from pandas.util._decorators import deprecate_kwarg | ||||
|  | ||||
| import pandas._testing as tm | ||||
|  | ||||
|  | ||||
| @deprecate_kwarg("old", "new") | ||||
| def _f1(new=False): | ||||
|     return new | ||||
|  | ||||
|  | ||||
| _f2_mappings = {"yes": True, "no": False} | ||||
|  | ||||
|  | ||||
| @deprecate_kwarg("old", "new", _f2_mappings) | ||||
| def _f2(new=False): | ||||
|     return new | ||||
|  | ||||
|  | ||||
| def _f3_mapping(x): | ||||
|     return x + 1 | ||||
|  | ||||
|  | ||||
| @deprecate_kwarg("old", "new", _f3_mapping) | ||||
| def _f3(new=0): | ||||
|     return new | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("key,klass", [("old", FutureWarning), ("new", None)]) | ||||
| def test_deprecate_kwarg(key, klass): | ||||
|     x = 78 | ||||
|  | ||||
|     with tm.assert_produces_warning(klass): | ||||
|         assert _f1(**{key: x}) == x | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("key", list(_f2_mappings.keys())) | ||||
| def test_dict_deprecate_kwarg(key): | ||||
|     with tm.assert_produces_warning(FutureWarning): | ||||
|         assert _f2(old=key) == _f2_mappings[key] | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("key", ["bogus", 12345, -1.23]) | ||||
| def test_missing_deprecate_kwarg(key): | ||||
|     with tm.assert_produces_warning(FutureWarning): | ||||
|         assert _f2(old=key) == key | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("x", [1, -1.4, 0]) | ||||
| def test_callable_deprecate_kwarg(x): | ||||
|     with tm.assert_produces_warning(FutureWarning): | ||||
|         assert _f3(old=x) == _f3_mapping(x) | ||||
|  | ||||
|  | ||||
| def test_callable_deprecate_kwarg_fail(): | ||||
|     msg = "((can only|cannot) concatenate)|(must be str)|(Can't convert)" | ||||
|  | ||||
|     with pytest.raises(TypeError, match=msg): | ||||
|         _f3(old="hello") | ||||
|  | ||||
|  | ||||
| def test_bad_deprecate_kwarg(): | ||||
|     msg = "mapping from old to new argument values must be dict or callable!" | ||||
|  | ||||
|     with pytest.raises(TypeError, match=msg): | ||||
|  | ||||
|         @deprecate_kwarg("old", "new", 0) | ||||
|         def f4(new=None): | ||||
|             return new | ||||
|  | ||||
|  | ||||
| @deprecate_kwarg("old", None) | ||||
| def _f4(old=True, unchanged=True): | ||||
|     return old, unchanged | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("key", ["old", "unchanged"]) | ||||
| def test_deprecate_keyword(key): | ||||
|     x = 9 | ||||
|  | ||||
|     if key == "old": | ||||
|         klass = FutureWarning | ||||
|         expected = (x, True) | ||||
|     else: | ||||
|         klass = None | ||||
|         expected = (True, x) | ||||
|  | ||||
|     with tm.assert_produces_warning(klass): | ||||
|         assert _f4(**{key: x}) == expected | ||||
| @ -0,0 +1,141 @@ | ||||
| """ | ||||
| Tests for the `deprecate_nonkeyword_arguments` decorator | ||||
| """ | ||||
|  | ||||
| import inspect | ||||
|  | ||||
| from pandas.util._decorators import deprecate_nonkeyword_arguments | ||||
|  | ||||
| import pandas._testing as tm | ||||
|  | ||||
|  | ||||
| @deprecate_nonkeyword_arguments( | ||||
|     version="1.1", allowed_args=["a", "b"], name="f_add_inputs" | ||||
| ) | ||||
| def f(a, b=0, c=0, d=0): | ||||
|     return a + b + c + d | ||||
|  | ||||
|  | ||||
| def test_f_signature(): | ||||
|     assert str(inspect.signature(f)) == "(a, b=0, *, c=0, d=0)" | ||||
|  | ||||
|  | ||||
| def test_one_argument(): | ||||
|     with tm.assert_produces_warning(None): | ||||
|         assert f(19) == 19 | ||||
|  | ||||
|  | ||||
| def test_one_and_one_arguments(): | ||||
|     with tm.assert_produces_warning(None): | ||||
|         assert f(19, d=6) == 25 | ||||
|  | ||||
|  | ||||
| def test_two_arguments(): | ||||
|     with tm.assert_produces_warning(None): | ||||
|         assert f(1, 5) == 6 | ||||
|  | ||||
|  | ||||
| def test_two_and_two_arguments(): | ||||
|     with tm.assert_produces_warning(None): | ||||
|         assert f(1, 3, c=3, d=5) == 12 | ||||
|  | ||||
|  | ||||
| def test_three_arguments(): | ||||
|     with tm.assert_produces_warning(FutureWarning): | ||||
|         assert f(6, 3, 3) == 12 | ||||
|  | ||||
|  | ||||
| def test_four_arguments(): | ||||
|     with tm.assert_produces_warning(FutureWarning): | ||||
|         assert f(1, 2, 3, 4) == 10 | ||||
|  | ||||
|  | ||||
| def test_three_arguments_with_name_in_warning(): | ||||
|     msg = ( | ||||
|         "Starting with pandas version 1.1 all arguments of f_add_inputs " | ||||
|         "except for the arguments 'a' and 'b' will be keyword-only." | ||||
|     ) | ||||
|     with tm.assert_produces_warning(FutureWarning, match=msg): | ||||
|         assert f(6, 3, 3) == 12 | ||||
|  | ||||
|  | ||||
| @deprecate_nonkeyword_arguments(version="1.1") | ||||
| def g(a, b=0, c=0, d=0): | ||||
|     with tm.assert_produces_warning(None): | ||||
|         return a + b + c + d | ||||
|  | ||||
|  | ||||
| def test_g_signature(): | ||||
|     assert str(inspect.signature(g)) == "(a, *, b=0, c=0, d=0)" | ||||
|  | ||||
|  | ||||
| def test_one_and_three_arguments_default_allowed_args(): | ||||
|     with tm.assert_produces_warning(None): | ||||
|         assert g(1, b=3, c=3, d=5) == 12 | ||||
|  | ||||
|  | ||||
| def test_three_arguments_default_allowed_args(): | ||||
|     with tm.assert_produces_warning(FutureWarning): | ||||
|         assert g(6, 3, 3) == 12 | ||||
|  | ||||
|  | ||||
| def test_three_positional_argument_with_warning_message_analysis(): | ||||
|     msg = ( | ||||
|         "Starting with pandas version 1.1 all arguments of g " | ||||
|         "except for the argument 'a' will be keyword-only." | ||||
|     ) | ||||
|     with tm.assert_produces_warning(FutureWarning, match=msg): | ||||
|         assert g(6, 3, 3) == 12 | ||||
|  | ||||
|  | ||||
| @deprecate_nonkeyword_arguments(version="1.1") | ||||
| def h(a=0, b=0, c=0, d=0): | ||||
|     return a + b + c + d | ||||
|  | ||||
|  | ||||
| def test_h_signature(): | ||||
|     assert str(inspect.signature(h)) == "(*, a=0, b=0, c=0, d=0)" | ||||
|  | ||||
|  | ||||
| def test_all_keyword_arguments(): | ||||
|     with tm.assert_produces_warning(None): | ||||
|         assert h(a=1, b=2) == 3 | ||||
|  | ||||
|  | ||||
| def test_one_positional_argument(): | ||||
|     with tm.assert_produces_warning(FutureWarning): | ||||
|         assert h(23) == 23 | ||||
|  | ||||
|  | ||||
| def test_one_positional_argument_with_warning_message_analysis(): | ||||
|     msg = "Starting with pandas version 1.1 all arguments of h will be keyword-only." | ||||
|     with tm.assert_produces_warning(FutureWarning, match=msg): | ||||
|         assert h(19) == 19 | ||||
|  | ||||
|  | ||||
| @deprecate_nonkeyword_arguments(version="1.1") | ||||
| def i(a=0, /, b=0, *, c=0, d=0): | ||||
|     return a + b + c + d | ||||
|  | ||||
|  | ||||
| def test_i_signature(): | ||||
|     assert str(inspect.signature(i)) == "(*, a=0, b=0, c=0, d=0)" | ||||
|  | ||||
|  | ||||
| class Foo: | ||||
|     @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "bar"]) | ||||
|     def baz(self, bar=None, foobar=None):  # pylint: disable=disallowed-name | ||||
|         ... | ||||
|  | ||||
|  | ||||
| def test_foo_signature(): | ||||
|     assert str(inspect.signature(Foo.baz)) == "(self, bar=None, *, foobar=None)" | ||||
|  | ||||
|  | ||||
| def test_class(): | ||||
|     msg = ( | ||||
|         r"In a future version of pandas all arguments of Foo\.baz " | ||||
|         r"except for the argument \'bar\' will be keyword-only" | ||||
|     ) | ||||
|     with tm.assert_produces_warning(FutureWarning, match=msg): | ||||
|         Foo().baz("qux", "quox") | ||||
							
								
								
									
										90
									
								
								lib/python3.11/site-packages/pandas/tests/util/test_doc.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								lib/python3.11/site-packages/pandas/tests/util/test_doc.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,90 @@ | ||||
| from textwrap import dedent | ||||
|  | ||||
| from pandas.util._decorators import doc | ||||
|  | ||||
|  | ||||
| @doc(method="cumsum", operation="sum") | ||||
| def cumsum(whatever): | ||||
|     """ | ||||
|     This is the {method} method. | ||||
|  | ||||
|     It computes the cumulative {operation}. | ||||
|     """ | ||||
|  | ||||
|  | ||||
| @doc( | ||||
|     cumsum, | ||||
|     dedent( | ||||
|         """ | ||||
|         Examples | ||||
|         -------- | ||||
|  | ||||
|         >>> cumavg([1, 2, 3]) | ||||
|         2 | ||||
|         """ | ||||
|     ), | ||||
|     method="cumavg", | ||||
|     operation="average", | ||||
| ) | ||||
| def cumavg(whatever): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| @doc(cumsum, method="cummax", operation="maximum") | ||||
| def cummax(whatever): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| @doc(cummax, method="cummin", operation="minimum") | ||||
| def cummin(whatever): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| def test_docstring_formatting(): | ||||
|     docstr = dedent( | ||||
|         """ | ||||
|         This is the cumsum method. | ||||
|  | ||||
|         It computes the cumulative sum. | ||||
|         """ | ||||
|     ) | ||||
|     assert cumsum.__doc__ == docstr | ||||
|  | ||||
|  | ||||
| def test_docstring_appending(): | ||||
|     docstr = dedent( | ||||
|         """ | ||||
|         This is the cumavg method. | ||||
|  | ||||
|         It computes the cumulative average. | ||||
|  | ||||
|         Examples | ||||
|         -------- | ||||
|  | ||||
|         >>> cumavg([1, 2, 3]) | ||||
|         2 | ||||
|         """ | ||||
|     ) | ||||
|     assert cumavg.__doc__ == docstr | ||||
|  | ||||
|  | ||||
| def test_doc_template_from_func(): | ||||
|     docstr = dedent( | ||||
|         """ | ||||
|         This is the cummax method. | ||||
|  | ||||
|         It computes the cumulative maximum. | ||||
|         """ | ||||
|     ) | ||||
|     assert cummax.__doc__ == docstr | ||||
|  | ||||
|  | ||||
| def test_inherit_doc_template(): | ||||
|     docstr = dedent( | ||||
|         """ | ||||
|         This is the cummin method. | ||||
|  | ||||
|         It computes the cumulative minimum. | ||||
|         """ | ||||
|     ) | ||||
|     assert cummin.__doc__ == docstr | ||||
							
								
								
									
										417
									
								
								lib/python3.11/site-packages/pandas/tests/util/test_hashing.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										417
									
								
								lib/python3.11/site-packages/pandas/tests/util/test_hashing.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,417 @@ | ||||
| import numpy as np | ||||
| import pytest | ||||
|  | ||||
| import pandas as pd | ||||
| from pandas import ( | ||||
|     DataFrame, | ||||
|     Index, | ||||
|     MultiIndex, | ||||
|     Series, | ||||
|     period_range, | ||||
|     timedelta_range, | ||||
| ) | ||||
| import pandas._testing as tm | ||||
| from pandas.core.util.hashing import hash_tuples | ||||
| from pandas.util import ( | ||||
|     hash_array, | ||||
|     hash_pandas_object, | ||||
| ) | ||||
|  | ||||
|  | ||||
| @pytest.fixture( | ||||
|     params=[ | ||||
|         Series([1, 2, 3] * 3, dtype="int32"), | ||||
|         Series([None, 2.5, 3.5] * 3, dtype="float32"), | ||||
|         Series(["a", "b", "c"] * 3, dtype="category"), | ||||
|         Series(["d", "e", "f"] * 3), | ||||
|         Series([True, False, True] * 3), | ||||
|         Series(pd.date_range("20130101", periods=9)), | ||||
|         Series(pd.date_range("20130101", periods=9, tz="US/Eastern")), | ||||
|         Series(timedelta_range("2000", periods=9)), | ||||
|     ] | ||||
| ) | ||||
| def series(request): | ||||
|     return request.param | ||||
|  | ||||
|  | ||||
| @pytest.fixture(params=[True, False]) | ||||
| def index(request): | ||||
|     return request.param | ||||
|  | ||||
|  | ||||
| def test_consistency(): | ||||
|     # Check that our hash doesn't change because of a mistake | ||||
|     # in the actual code; this is the ground truth. | ||||
|     result = hash_pandas_object(Index(["foo", "bar", "baz"])) | ||||
|     expected = Series( | ||||
|         np.array( | ||||
|             [3600424527151052760, 1374399572096150070, 477881037637427054], | ||||
|             dtype="uint64", | ||||
|         ), | ||||
|         index=["foo", "bar", "baz"], | ||||
|     ) | ||||
|     tm.assert_series_equal(result, expected) | ||||
|  | ||||
|  | ||||
| def test_hash_array(series): | ||||
|     arr = series.values | ||||
|     tm.assert_numpy_array_equal(hash_array(arr), hash_array(arr)) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("dtype", ["U", object]) | ||||
| def test_hash_array_mixed(dtype): | ||||
|     result1 = hash_array(np.array(["3", "4", "All"])) | ||||
|     result2 = hash_array(np.array([3, 4, "All"], dtype=dtype)) | ||||
|  | ||||
|     tm.assert_numpy_array_equal(result1, result2) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("val", [5, "foo", pd.Timestamp("20130101")]) | ||||
| def test_hash_array_errors(val): | ||||
|     msg = "must pass a ndarray-like" | ||||
|     with pytest.raises(TypeError, match=msg): | ||||
|         hash_array(val) | ||||
|  | ||||
|  | ||||
| def test_hash_array_index_exception(): | ||||
|     # GH42003 TypeError instead of AttributeError | ||||
|     obj = pd.DatetimeIndex(["2018-10-28 01:20:00"], tz="Europe/Berlin") | ||||
|  | ||||
|     msg = "Use hash_pandas_object instead" | ||||
|     with pytest.raises(TypeError, match=msg): | ||||
|         hash_array(obj) | ||||
|  | ||||
|  | ||||
| def test_hash_tuples(): | ||||
|     tuples = [(1, "one"), (1, "two"), (2, "one")] | ||||
|     result = hash_tuples(tuples) | ||||
|  | ||||
|     expected = hash_pandas_object(MultiIndex.from_tuples(tuples)).values | ||||
|     tm.assert_numpy_array_equal(result, expected) | ||||
|  | ||||
|     # We only need to support MultiIndex and list-of-tuples | ||||
|     msg = "|".join(["object is not iterable", "zip argument #1 must support iteration"]) | ||||
|     with pytest.raises(TypeError, match=msg): | ||||
|         hash_tuples(tuples[0]) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("val", [5, "foo", pd.Timestamp("20130101")]) | ||||
| def test_hash_tuples_err(val): | ||||
|     msg = "must be convertible to a list-of-tuples" | ||||
|     with pytest.raises(TypeError, match=msg): | ||||
|         hash_tuples(val) | ||||
|  | ||||
|  | ||||
| def test_multiindex_unique(): | ||||
|     mi = MultiIndex.from_tuples([(118, 472), (236, 118), (51, 204), (102, 51)]) | ||||
|     assert mi.is_unique is True | ||||
|  | ||||
|     result = hash_pandas_object(mi) | ||||
|     assert result.is_unique is True | ||||
|  | ||||
|  | ||||
| def test_multiindex_objects(): | ||||
|     mi = MultiIndex( | ||||
|         levels=[["b", "d", "a"], [1, 2, 3]], | ||||
|         codes=[[0, 1, 0, 2], [2, 0, 0, 1]], | ||||
|         names=["col1", "col2"], | ||||
|     ) | ||||
|     recons = mi._sort_levels_monotonic() | ||||
|  | ||||
|     # These are equal. | ||||
|     assert mi.equals(recons) | ||||
|     assert Index(mi.values).equals(Index(recons.values)) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "obj", | ||||
|     [ | ||||
|         Series([1, 2, 3]), | ||||
|         Series([1.0, 1.5, 3.2]), | ||||
|         Series([1.0, 1.5, np.nan]), | ||||
|         Series([1.0, 1.5, 3.2], index=[1.5, 1.1, 3.3]), | ||||
|         Series(["a", "b", "c"]), | ||||
|         Series(["a", np.nan, "c"]), | ||||
|         Series(["a", None, "c"]), | ||||
|         Series([True, False, True]), | ||||
|         Series(dtype=object), | ||||
|         DataFrame({"x": ["a", "b", "c"], "y": [1, 2, 3]}), | ||||
|         DataFrame(), | ||||
|         DataFrame(np.full((10, 4), np.nan)), | ||||
|         DataFrame( | ||||
|             { | ||||
|                 "A": [0.0, 1.0, 2.0, 3.0, 4.0], | ||||
|                 "B": [0.0, 1.0, 0.0, 1.0, 0.0], | ||||
|                 "C": Index(["foo1", "foo2", "foo3", "foo4", "foo5"], dtype=object), | ||||
|                 "D": pd.date_range("20130101", periods=5), | ||||
|             } | ||||
|         ), | ||||
|         DataFrame(range(5), index=pd.date_range("2020-01-01", periods=5)), | ||||
|         Series(range(5), index=pd.date_range("2020-01-01", periods=5)), | ||||
|         Series(period_range("2020-01-01", periods=10, freq="D")), | ||||
|         Series(pd.date_range("20130101", periods=3, tz="US/Eastern")), | ||||
|     ], | ||||
| ) | ||||
| def test_hash_pandas_object(obj, index): | ||||
|     a = hash_pandas_object(obj, index=index) | ||||
|     b = hash_pandas_object(obj, index=index) | ||||
|     tm.assert_series_equal(a, b) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "obj", | ||||
|     [ | ||||
|         Series([1, 2, 3]), | ||||
|         Series([1.0, 1.5, 3.2]), | ||||
|         Series([1.0, 1.5, np.nan]), | ||||
|         Series([1.0, 1.5, 3.2], index=[1.5, 1.1, 3.3]), | ||||
|         Series(["a", "b", "c"]), | ||||
|         Series(["a", np.nan, "c"]), | ||||
|         Series(["a", None, "c"]), | ||||
|         Series([True, False, True]), | ||||
|         DataFrame({"x": ["a", "b", "c"], "y": [1, 2, 3]}), | ||||
|         DataFrame(np.full((10, 4), np.nan)), | ||||
|         DataFrame( | ||||
|             { | ||||
|                 "A": [0.0, 1.0, 2.0, 3.0, 4.0], | ||||
|                 "B": [0.0, 1.0, 0.0, 1.0, 0.0], | ||||
|                 "C": Index(["foo1", "foo2", "foo3", "foo4", "foo5"], dtype=object), | ||||
|                 "D": pd.date_range("20130101", periods=5), | ||||
|             } | ||||
|         ), | ||||
|         DataFrame(range(5), index=pd.date_range("2020-01-01", periods=5)), | ||||
|         Series(range(5), index=pd.date_range("2020-01-01", periods=5)), | ||||
|         Series(period_range("2020-01-01", periods=10, freq="D")), | ||||
|         Series(pd.date_range("20130101", periods=3, tz="US/Eastern")), | ||||
|     ], | ||||
| ) | ||||
| def test_hash_pandas_object_diff_index_non_empty(obj): | ||||
|     a = hash_pandas_object(obj, index=True) | ||||
|     b = hash_pandas_object(obj, index=False) | ||||
|     assert not (a == b).all() | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "obj", | ||||
|     [ | ||||
|         Index([1, 2, 3]), | ||||
|         Index([True, False, True]), | ||||
|         timedelta_range("1 day", periods=2), | ||||
|         period_range("2020-01-01", freq="D", periods=2), | ||||
|         MultiIndex.from_product( | ||||
|             [range(5), ["foo", "bar", "baz"], pd.date_range("20130101", periods=2)] | ||||
|         ), | ||||
|         MultiIndex.from_product([pd.CategoricalIndex(list("aabc")), range(3)]), | ||||
|     ], | ||||
| ) | ||||
| def test_hash_pandas_index(obj, index): | ||||
|     a = hash_pandas_object(obj, index=index) | ||||
|     b = hash_pandas_object(obj, index=index) | ||||
|     tm.assert_series_equal(a, b) | ||||
|  | ||||
|  | ||||
| def test_hash_pandas_series(series, index): | ||||
|     a = hash_pandas_object(series, index=index) | ||||
|     b = hash_pandas_object(series, index=index) | ||||
|     tm.assert_series_equal(a, b) | ||||
|  | ||||
|  | ||||
| def test_hash_pandas_series_diff_index(series): | ||||
|     a = hash_pandas_object(series, index=True) | ||||
|     b = hash_pandas_object(series, index=False) | ||||
|     assert not (a == b).all() | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "obj", [Series([], dtype="float64"), Series([], dtype="object"), Index([])] | ||||
| ) | ||||
| def test_hash_pandas_empty_object(obj, index): | ||||
|     # These are by-definition the same with | ||||
|     # or without the index as the data is empty. | ||||
|     a = hash_pandas_object(obj, index=index) | ||||
|     b = hash_pandas_object(obj, index=index) | ||||
|     tm.assert_series_equal(a, b) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "s1", | ||||
|     [ | ||||
|         Series(["a", "b", "c", "d"]), | ||||
|         Series([1000, 2000, 3000, 4000]), | ||||
|         Series(pd.date_range(0, periods=4)), | ||||
|     ], | ||||
| ) | ||||
| @pytest.mark.parametrize("categorize", [True, False]) | ||||
| def test_categorical_consistency(s1, categorize): | ||||
|     # see gh-15143 | ||||
|     # | ||||
|     # Check that categoricals hash consistent with their values, | ||||
|     # not codes. This should work for categoricals of any dtype. | ||||
|     s2 = s1.astype("category").cat.set_categories(s1) | ||||
|     s3 = s2.cat.set_categories(list(reversed(s1))) | ||||
|  | ||||
|     # These should all hash identically. | ||||
|     h1 = hash_pandas_object(s1, categorize=categorize) | ||||
|     h2 = hash_pandas_object(s2, categorize=categorize) | ||||
|     h3 = hash_pandas_object(s3, categorize=categorize) | ||||
|  | ||||
|     tm.assert_series_equal(h1, h2) | ||||
|     tm.assert_series_equal(h1, h3) | ||||
|  | ||||
|  | ||||
| def test_categorical_with_nan_consistency(): | ||||
|     c = pd.Categorical.from_codes( | ||||
|         [-1, 0, 1, 2, 3, 4], categories=pd.date_range("2012-01-01", periods=5, name="B") | ||||
|     ) | ||||
|     expected = hash_array(c, categorize=False) | ||||
|  | ||||
|     c = pd.Categorical.from_codes([-1, 0], categories=[pd.Timestamp("2012-01-01")]) | ||||
|     result = hash_array(c, categorize=False) | ||||
|  | ||||
|     assert result[0] in expected | ||||
|     assert result[1] in expected | ||||
|  | ||||
|  | ||||
| def test_pandas_errors(): | ||||
|     msg = "Unexpected type for hashing" | ||||
|     with pytest.raises(TypeError, match=msg): | ||||
|         hash_pandas_object(pd.Timestamp("20130101")) | ||||
|  | ||||
|  | ||||
| def test_hash_keys(): | ||||
|     # Using different hash keys, should have | ||||
|     # different hashes for the same data. | ||||
|     # | ||||
|     # This only matters for object dtypes. | ||||
|     obj = Series(list("abc")) | ||||
|  | ||||
|     a = hash_pandas_object(obj, hash_key="9876543210123456") | ||||
|     b = hash_pandas_object(obj, hash_key="9876543210123465") | ||||
|  | ||||
|     assert (a != b).all() | ||||
|  | ||||
|  | ||||
| def test_df_hash_keys(): | ||||
|     # DataFrame version of the test_hash_keys. | ||||
|     # https://github.com/pandas-dev/pandas/issues/41404 | ||||
|     obj = DataFrame({"x": np.arange(3), "y": list("abc")}) | ||||
|  | ||||
|     a = hash_pandas_object(obj, hash_key="9876543210123456") | ||||
|     b = hash_pandas_object(obj, hash_key="9876543210123465") | ||||
|  | ||||
|     assert (a != b).all() | ||||
|  | ||||
|  | ||||
| def test_df_encoding(): | ||||
|     # Check that DataFrame recognizes optional encoding. | ||||
|     # https://github.com/pandas-dev/pandas/issues/41404 | ||||
|     # https://github.com/pandas-dev/pandas/pull/42049 | ||||
|     obj = DataFrame({"x": np.arange(3), "y": list("a+c")}) | ||||
|  | ||||
|     a = hash_pandas_object(obj, encoding="utf8") | ||||
|     b = hash_pandas_object(obj, encoding="utf7") | ||||
|  | ||||
|     # Note that the "+" is encoded as "+-" in utf-7. | ||||
|     assert a[0] == b[0] | ||||
|     assert a[1] != b[1] | ||||
|     assert a[2] == b[2] | ||||
|  | ||||
|  | ||||
| def test_invalid_key(): | ||||
|     # This only matters for object dtypes. | ||||
|     msg = "key should be a 16-byte string encoded" | ||||
|  | ||||
|     with pytest.raises(ValueError, match=msg): | ||||
|         hash_pandas_object(Series(list("abc")), hash_key="foo") | ||||
|  | ||||
|  | ||||
| def test_already_encoded(index): | ||||
|     # If already encoded, then ok. | ||||
|     obj = Series(list("abc")).str.encode("utf8") | ||||
|     a = hash_pandas_object(obj, index=index) | ||||
|     b = hash_pandas_object(obj, index=index) | ||||
|     tm.assert_series_equal(a, b) | ||||
|  | ||||
|  | ||||
| def test_alternate_encoding(index): | ||||
|     obj = Series(list("abc")) | ||||
|     a = hash_pandas_object(obj, index=index) | ||||
|     b = hash_pandas_object(obj, index=index) | ||||
|     tm.assert_series_equal(a, b) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("l_exp", range(8)) | ||||
| @pytest.mark.parametrize("l_add", [0, 1]) | ||||
| def test_same_len_hash_collisions(l_exp, l_add): | ||||
|     length = 2 ** (l_exp + 8) + l_add | ||||
|     idx = np.array([str(i) for i in range(length)], dtype=object) | ||||
|  | ||||
|     result = hash_array(idx, "utf8") | ||||
|     assert not result[0] == result[1] | ||||
|  | ||||
|  | ||||
| def test_hash_collisions(): | ||||
|     # Hash collisions are bad. | ||||
|     # | ||||
|     # https://github.com/pandas-dev/pandas/issues/14711#issuecomment-264885726 | ||||
|     hashes = [ | ||||
|         "Ingrid-9Z9fKIZmkO7i7Cn51Li34pJm44fgX6DYGBNj3VPlOH50m7HnBlPxfIwFMrcNJNMP6PSgLmwWnInciMWrCSAlLEvt7JkJl4IxiMrVbXSa8ZQoVaq5xoQPjltuJEfwdNlO6jo8qRRHvD8sBEBMQASrRa6TsdaPTPCBo3nwIBpE7YzzmyH0vMBhjQZLx1aCT7faSEx7PgFxQhHdKFWROcysamgy9iVj8DO2Fmwg1NNl93rIAqC3mdqfrCxrzfvIY8aJdzin2cHVzy3QUJxZgHvtUtOLxoqnUHsYbNTeq0xcLXpTZEZCxD4PGubIuCNf32c33M7HFsnjWSEjE2yVdWKhmSVodyF8hFYVmhYnMCztQnJrt3O8ZvVRXd5IKwlLexiSp4h888w7SzAIcKgc3g5XQJf6MlSMftDXm9lIsE1mJNiJEv6uY6pgvC3fUPhatlR5JPpVAHNSbSEE73MBzJrhCAbOLXQumyOXigZuPoME7QgJcBalliQol7YZ9", | ||||
|         "Tim-b9MddTxOWW2AT1Py6vtVbZwGAmYCjbp89p8mxsiFoVX4FyDOF3wFiAkyQTUgwg9sVqVYOZo09Dh1AzhFHbgij52ylF0SEwgzjzHH8TGY8Lypart4p4onnDoDvVMBa0kdthVGKl6K0BDVGzyOXPXKpmnMF1H6rJzqHJ0HywfwS4XYpVwlAkoeNsiicHkJUFdUAhG229INzvIAiJuAHeJDUoyO4DCBqtoZ5TDend6TK7Y914yHlfH3g1WZu5LksKv68VQHJriWFYusW5e6ZZ6dKaMjTwEGuRgdT66iU5nqWTHRH8WSzpXoCFwGcTOwyuqPSe0fTe21DVtJn1FKj9F9nEnR9xOvJUO7E0piCIF4Ad9yAIDY4DBimpsTfKXCu1vdHpKYerzbndfuFe5AhfMduLYZJi5iAw8qKSwR5h86ttXV0Mc0QmXz8dsRvDgxjXSmupPxBggdlqUlC828hXiTPD7am0yETBV0F3bEtvPiNJfremszcV8NcqAoARMe", | ||||
|     ] | ||||
|  | ||||
|     # These should be different. | ||||
|     result1 = hash_array(np.asarray(hashes[0:1], dtype=object), "utf8") | ||||
|     expected1 = np.array([14963968704024874985], dtype=np.uint64) | ||||
|     tm.assert_numpy_array_equal(result1, expected1) | ||||
|  | ||||
|     result2 = hash_array(np.asarray(hashes[1:2], dtype=object), "utf8") | ||||
|     expected2 = np.array([16428432627716348016], dtype=np.uint64) | ||||
|     tm.assert_numpy_array_equal(result2, expected2) | ||||
|  | ||||
|     result = hash_array(np.asarray(hashes, dtype=object), "utf8") | ||||
|     tm.assert_numpy_array_equal(result, np.concatenate([expected1, expected2], axis=0)) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "data, result_data", | ||||
|     [ | ||||
|         [[tuple("1"), tuple("2")], [10345501319357378243, 8331063931016360761]], | ||||
|         [[(1,), (2,)], [9408946347443669104, 3278256261030523334]], | ||||
|     ], | ||||
| ) | ||||
| def test_hash_with_tuple(data, result_data): | ||||
|     # GH#28969 array containing a tuple raises on call to arr.astype(str) | ||||
|     #  apparently a numpy bug github.com/numpy/numpy/issues/9441 | ||||
|  | ||||
|     df = DataFrame({"data": data}) | ||||
|     result = hash_pandas_object(df) | ||||
|     expected = Series(result_data, dtype=np.uint64) | ||||
|     tm.assert_series_equal(result, expected) | ||||
|  | ||||
|  | ||||
| def test_hashable_tuple_args(): | ||||
|     # require that the elements of such tuples are themselves hashable | ||||
|  | ||||
|     df3 = DataFrame( | ||||
|         { | ||||
|             "data": [ | ||||
|                 ( | ||||
|                     1, | ||||
|                     [], | ||||
|                 ), | ||||
|                 ( | ||||
|                     2, | ||||
|                     {}, | ||||
|                 ), | ||||
|             ] | ||||
|         } | ||||
|     ) | ||||
|     with pytest.raises(TypeError, match="unhashable type: 'list'"): | ||||
|         hash_pandas_object(df3) | ||||
|  | ||||
|  | ||||
| def test_hash_object_none_key(): | ||||
|     # https://github.com/pandas-dev/pandas/issues/30887 | ||||
|     result = pd.util.hash_pandas_object(Series(["a", "b"]), hash_key=None) | ||||
|     expected = Series([4578374827886788867, 17338122309987883691], dtype="uint64") | ||||
|     tm.assert_series_equal(result, expected) | ||||
							
								
								
									
										12
									
								
								lib/python3.11/site-packages/pandas/tests/util/test_numba.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								lib/python3.11/site-packages/pandas/tests/util/test_numba.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| import pytest | ||||
|  | ||||
| import pandas.util._test_decorators as td | ||||
|  | ||||
| from pandas import option_context | ||||
|  | ||||
|  | ||||
| @td.skip_if_installed("numba") | ||||
| def test_numba_not_installed_option_context(): | ||||
|     with pytest.raises(ImportError, match="Missing optional"): | ||||
|         with option_context("compute.use_numba", True): | ||||
|             pass | ||||
| @ -0,0 +1,39 @@ | ||||
| import warnings | ||||
|  | ||||
| import pytest | ||||
|  | ||||
| from pandas.util._exceptions import rewrite_warning | ||||
|  | ||||
| import pandas._testing as tm | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "target_category, target_message, hit", | ||||
|     [ | ||||
|         (FutureWarning, "Target message", True), | ||||
|         (FutureWarning, "Target", True), | ||||
|         (FutureWarning, "get mess", True), | ||||
|         (FutureWarning, "Missed message", False), | ||||
|         (DeprecationWarning, "Target message", False), | ||||
|     ], | ||||
| ) | ||||
| @pytest.mark.parametrize( | ||||
|     "new_category", | ||||
|     [ | ||||
|         None, | ||||
|         DeprecationWarning, | ||||
|     ], | ||||
| ) | ||||
| def test_rewrite_warning(target_category, target_message, hit, new_category): | ||||
|     new_message = "Rewritten message" | ||||
|     if hit: | ||||
|         expected_category = new_category if new_category else target_category | ||||
|         expected_message = new_message | ||||
|     else: | ||||
|         expected_category = FutureWarning | ||||
|         expected_message = "Target message" | ||||
|     with tm.assert_produces_warning(expected_category, match=expected_message): | ||||
|         with rewrite_warning( | ||||
|             target_message, target_category, new_message, new_category | ||||
|         ): | ||||
|             warnings.warn(message="Target message", category=FutureWarning) | ||||
| @ -0,0 +1,32 @@ | ||||
| import numpy as np | ||||
|  | ||||
| import pandas.util._test_decorators as td | ||||
|  | ||||
| import pandas as pd | ||||
| import pandas._testing as tm | ||||
|  | ||||
|  | ||||
| def test_shares_memory_interval(): | ||||
|     obj = pd.interval_range(1, 5) | ||||
|  | ||||
|     assert tm.shares_memory(obj, obj) | ||||
|     assert tm.shares_memory(obj, obj._data) | ||||
|     assert tm.shares_memory(obj, obj[::-1]) | ||||
|     assert tm.shares_memory(obj, obj[:2]) | ||||
|  | ||||
|     assert not tm.shares_memory(obj, obj._data.copy()) | ||||
|  | ||||
|  | ||||
| @td.skip_if_no("pyarrow") | ||||
| def test_shares_memory_string(): | ||||
|     # GH#55823 | ||||
|     import pyarrow as pa | ||||
|  | ||||
|     obj = pd.array(["a", "b"], dtype=pd.StringDtype("pyarrow", na_value=pd.NA)) | ||||
|     assert tm.shares_memory(obj, obj) | ||||
|  | ||||
|     obj = pd.array(["a", "b"], dtype=pd.StringDtype("pyarrow", na_value=np.nan)) | ||||
|     assert tm.shares_memory(obj, obj) | ||||
|  | ||||
|     obj = pd.array(["a", "b"], dtype=pd.ArrowDtype(pa.string())) | ||||
|     assert tm.shares_memory(obj, obj) | ||||
| @ -0,0 +1,81 @@ | ||||
| import json | ||||
| import os | ||||
| import re | ||||
|  | ||||
| from pandas.util._print_versions import ( | ||||
|     _get_dependency_info, | ||||
|     _get_sys_info, | ||||
| ) | ||||
|  | ||||
| import pandas as pd | ||||
|  | ||||
|  | ||||
| def test_show_versions(tmpdir): | ||||
|     # GH39701 | ||||
|     as_json = os.path.join(tmpdir, "test_output.json") | ||||
|  | ||||
|     pd.show_versions(as_json=as_json) | ||||
|  | ||||
|     with open(as_json, encoding="utf-8") as fd: | ||||
|         # check if file output is valid JSON, will raise an exception if not | ||||
|         result = json.load(fd) | ||||
|  | ||||
|     # Basic check that each version element is found in output | ||||
|     expected = { | ||||
|         "system": _get_sys_info(), | ||||
|         "dependencies": _get_dependency_info(), | ||||
|     } | ||||
|  | ||||
|     assert result == expected | ||||
|  | ||||
|  | ||||
| def test_show_versions_console_json(capsys): | ||||
|     # GH39701 | ||||
|     pd.show_versions(as_json=True) | ||||
|     stdout = capsys.readouterr().out | ||||
|  | ||||
|     # check valid json is printed to the console if as_json is True | ||||
|     result = json.loads(stdout) | ||||
|  | ||||
|     # Basic check that each version element is found in output | ||||
|     expected = { | ||||
|         "system": _get_sys_info(), | ||||
|         "dependencies": _get_dependency_info(), | ||||
|     } | ||||
|  | ||||
|     assert result == expected | ||||
|  | ||||
|  | ||||
| def test_show_versions_console(capsys): | ||||
|     # gh-32041 | ||||
|     # gh-32041 | ||||
|     pd.show_versions(as_json=False) | ||||
|     result = capsys.readouterr().out | ||||
|  | ||||
|     # check header | ||||
|     assert "INSTALLED VERSIONS" in result | ||||
|  | ||||
|     # check full commit hash | ||||
|     assert re.search(r"commit\s*:\s[0-9a-f]{40}\n", result) | ||||
|  | ||||
|     # check required dependency | ||||
|     # 2020-12-09 npdev has "dirty" in the tag | ||||
|     # 2022-05-25 npdev released with RC wo/ "dirty". | ||||
|     # Just ensure we match [0-9]+\..* since npdev version is variable | ||||
|     assert re.search(r"numpy\s*:\s[0-9]+\..*\n", result) | ||||
|  | ||||
|     # check optional dependency | ||||
|     assert re.search(r"pyarrow\s*:\s([0-9]+.*|None)\n", result) | ||||
|  | ||||
|  | ||||
| def test_json_output_match(capsys, tmpdir): | ||||
|     # GH39701 | ||||
|     pd.show_versions(as_json=True) | ||||
|     result_console = capsys.readouterr().out | ||||
|  | ||||
|     out_path = os.path.join(tmpdir, "test_json.json") | ||||
|     pd.show_versions(as_json=out_path) | ||||
|     with open(out_path, encoding="utf-8") as out_fd: | ||||
|         result_file = out_fd.read() | ||||
|  | ||||
|     assert result_console == result_file | ||||
							
								
								
									
										58
									
								
								lib/python3.11/site-packages/pandas/tests/util/test_util.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								lib/python3.11/site-packages/pandas/tests/util/test_util.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | ||||
| import os | ||||
|  | ||||
| import pytest | ||||
|  | ||||
| from pandas import ( | ||||
|     array, | ||||
|     compat, | ||||
| ) | ||||
| import pandas._testing as tm | ||||
|  | ||||
|  | ||||
| def test_numpy_err_state_is_default(): | ||||
|     expected = {"over": "warn", "divide": "warn", "invalid": "warn", "under": "ignore"} | ||||
|     import numpy as np | ||||
|  | ||||
|     # The error state should be unchanged after that import. | ||||
|     assert np.geterr() == expected | ||||
|  | ||||
|  | ||||
| def test_convert_rows_list_to_csv_str(): | ||||
|     rows_list = ["aaa", "bbb", "ccc"] | ||||
|     ret = tm.convert_rows_list_to_csv_str(rows_list) | ||||
|  | ||||
|     if compat.is_platform_windows(): | ||||
|         expected = "aaa\r\nbbb\r\nccc\r\n" | ||||
|     else: | ||||
|         expected = "aaa\nbbb\nccc\n" | ||||
|  | ||||
|     assert ret == expected | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("strict_data_files", [True, False]) | ||||
| def test_datapath_missing(datapath): | ||||
|     with pytest.raises(ValueError, match="Could not find file"): | ||||
|         datapath("not_a_file") | ||||
|  | ||||
|  | ||||
| def test_datapath(datapath): | ||||
|     args = ("io", "data", "csv", "iris.csv") | ||||
|  | ||||
|     result = datapath(*args) | ||||
|     expected = os.path.join(os.path.dirname(os.path.dirname(__file__)), *args) | ||||
|  | ||||
|     assert result == expected | ||||
|  | ||||
|  | ||||
| def test_external_error_raised(): | ||||
|     with tm.external_error_raised(TypeError): | ||||
|         raise TypeError("Should not check this error message, so it will pass") | ||||
|  | ||||
|  | ||||
| def test_is_sorted(): | ||||
|     arr = array([1, 2, 3], dtype="Int64") | ||||
|     tm.assert_is_sorted(arr) | ||||
|  | ||||
|     arr = array([4, 2, 3], dtype="Int64") | ||||
|     with pytest.raises(AssertionError, match="ExtensionArray are different"): | ||||
|         tm.assert_is_sorted(arr) | ||||
| @ -0,0 +1,70 @@ | ||||
| import pytest | ||||
|  | ||||
| from pandas.util._validators import validate_args | ||||
|  | ||||
|  | ||||
| @pytest.fixture | ||||
| def _fname(): | ||||
|     return "func" | ||||
|  | ||||
|  | ||||
| def test_bad_min_fname_arg_count(_fname): | ||||
|     msg = "'max_fname_arg_count' must be non-negative" | ||||
|  | ||||
|     with pytest.raises(ValueError, match=msg): | ||||
|         validate_args(_fname, (None,), -1, "foo") | ||||
|  | ||||
|  | ||||
| def test_bad_arg_length_max_value_single(_fname): | ||||
|     args = (None, None) | ||||
|     compat_args = ("foo",) | ||||
|  | ||||
|     min_fname_arg_count = 0 | ||||
|     max_length = len(compat_args) + min_fname_arg_count | ||||
|     actual_length = len(args) + min_fname_arg_count | ||||
|     msg = ( | ||||
|         rf"{_fname}\(\) takes at most {max_length} " | ||||
|         rf"argument \({actual_length} given\)" | ||||
|     ) | ||||
|  | ||||
|     with pytest.raises(TypeError, match=msg): | ||||
|         validate_args(_fname, args, min_fname_arg_count, compat_args) | ||||
|  | ||||
|  | ||||
| def test_bad_arg_length_max_value_multiple(_fname): | ||||
|     args = (None, None) | ||||
|     compat_args = {"foo": None} | ||||
|  | ||||
|     min_fname_arg_count = 2 | ||||
|     max_length = len(compat_args) + min_fname_arg_count | ||||
|     actual_length = len(args) + min_fname_arg_count | ||||
|     msg = ( | ||||
|         rf"{_fname}\(\) takes at most {max_length} " | ||||
|         rf"arguments \({actual_length} given\)" | ||||
|     ) | ||||
|  | ||||
|     with pytest.raises(TypeError, match=msg): | ||||
|         validate_args(_fname, args, min_fname_arg_count, compat_args) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("i", range(1, 3)) | ||||
| def test_not_all_defaults(i, _fname): | ||||
|     bad_arg = "foo" | ||||
|     msg = ( | ||||
|         f"the '{bad_arg}' parameter is not supported " | ||||
|         rf"in the pandas implementation of {_fname}\(\)" | ||||
|     ) | ||||
|  | ||||
|     compat_args = {"foo": 2, "bar": -1, "baz": 3} | ||||
|     arg_vals = (1, -1, 3) | ||||
|  | ||||
|     with pytest.raises(ValueError, match=msg): | ||||
|         validate_args(_fname, arg_vals[:i], 2, compat_args) | ||||
|  | ||||
|  | ||||
| def test_validation(_fname): | ||||
|     # No exceptions should be raised. | ||||
|     validate_args(_fname, (None,), 2, {"out": None}) | ||||
|  | ||||
|     compat_args = {"axis": 1, "out": None} | ||||
|     validate_args(_fname, (1, None), 2, compat_args) | ||||
| @ -0,0 +1,84 @@ | ||||
| import pytest | ||||
|  | ||||
| from pandas.util._validators import validate_args_and_kwargs | ||||
|  | ||||
|  | ||||
| @pytest.fixture | ||||
| def _fname(): | ||||
|     return "func" | ||||
|  | ||||
|  | ||||
| def test_invalid_total_length_max_length_one(_fname): | ||||
|     compat_args = ("foo",) | ||||
|     kwargs = {"foo": "FOO"} | ||||
|     args = ("FoO", "BaZ") | ||||
|  | ||||
|     min_fname_arg_count = 0 | ||||
|     max_length = len(compat_args) + min_fname_arg_count | ||||
|     actual_length = len(kwargs) + len(args) + min_fname_arg_count | ||||
|  | ||||
|     msg = ( | ||||
|         rf"{_fname}\(\) takes at most {max_length} " | ||||
|         rf"argument \({actual_length} given\)" | ||||
|     ) | ||||
|  | ||||
|     with pytest.raises(TypeError, match=msg): | ||||
|         validate_args_and_kwargs(_fname, args, kwargs, min_fname_arg_count, compat_args) | ||||
|  | ||||
|  | ||||
| def test_invalid_total_length_max_length_multiple(_fname): | ||||
|     compat_args = ("foo", "bar", "baz") | ||||
|     kwargs = {"foo": "FOO", "bar": "BAR"} | ||||
|     args = ("FoO", "BaZ") | ||||
|  | ||||
|     min_fname_arg_count = 2 | ||||
|     max_length = len(compat_args) + min_fname_arg_count | ||||
|     actual_length = len(kwargs) + len(args) + min_fname_arg_count | ||||
|  | ||||
|     msg = ( | ||||
|         rf"{_fname}\(\) takes at most {max_length} " | ||||
|         rf"arguments \({actual_length} given\)" | ||||
|     ) | ||||
|  | ||||
|     with pytest.raises(TypeError, match=msg): | ||||
|         validate_args_and_kwargs(_fname, args, kwargs, min_fname_arg_count, compat_args) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("args,kwargs", [((), {"foo": -5, "bar": 2}), ((-5, 2), {})]) | ||||
| def test_missing_args_or_kwargs(args, kwargs, _fname): | ||||
|     bad_arg = "bar" | ||||
|     min_fname_arg_count = 2 | ||||
|  | ||||
|     compat_args = {"foo": -5, bad_arg: 1} | ||||
|  | ||||
|     msg = ( | ||||
|         rf"the '{bad_arg}' parameter is not supported " | ||||
|         rf"in the pandas implementation of {_fname}\(\)" | ||||
|     ) | ||||
|  | ||||
|     with pytest.raises(ValueError, match=msg): | ||||
|         validate_args_and_kwargs(_fname, args, kwargs, min_fname_arg_count, compat_args) | ||||
|  | ||||
|  | ||||
| def test_duplicate_argument(_fname): | ||||
|     min_fname_arg_count = 2 | ||||
|  | ||||
|     compat_args = {"foo": None, "bar": None, "baz": None} | ||||
|     kwargs = {"foo": None, "bar": None} | ||||
|     args = (None,)  # duplicate value for "foo" | ||||
|  | ||||
|     msg = rf"{_fname}\(\) got multiple values for keyword argument 'foo'" | ||||
|  | ||||
|     with pytest.raises(TypeError, match=msg): | ||||
|         validate_args_and_kwargs(_fname, args, kwargs, min_fname_arg_count, compat_args) | ||||
|  | ||||
|  | ||||
| def test_validation(_fname): | ||||
|     # No exceptions should be raised. | ||||
|     compat_args = {"foo": 1, "bar": None, "baz": -2} | ||||
|     kwargs = {"baz": -2} | ||||
|  | ||||
|     args = (1, None) | ||||
|     min_fname_arg_count = 2 | ||||
|  | ||||
|     validate_args_and_kwargs(_fname, args, kwargs, min_fname_arg_count, compat_args) | ||||
| @ -0,0 +1,40 @@ | ||||
| import numpy as np | ||||
| import pytest | ||||
|  | ||||
| from pandas.util._validators import validate_inclusive | ||||
|  | ||||
| import pandas as pd | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "invalid_inclusive", | ||||
|     ( | ||||
|         "ccc", | ||||
|         2, | ||||
|         object(), | ||||
|         None, | ||||
|         np.nan, | ||||
|         pd.NA, | ||||
|         pd.DataFrame(), | ||||
|     ), | ||||
| ) | ||||
| def test_invalid_inclusive(invalid_inclusive): | ||||
|     with pytest.raises( | ||||
|         ValueError, | ||||
|         match="Inclusive has to be either 'both', 'neither', 'left' or 'right'", | ||||
|     ): | ||||
|         validate_inclusive(invalid_inclusive) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     "valid_inclusive, expected_tuple", | ||||
|     ( | ||||
|         ("left", (True, False)), | ||||
|         ("right", (False, True)), | ||||
|         ("both", (True, True)), | ||||
|         ("neither", (False, False)), | ||||
|     ), | ||||
| ) | ||||
| def test_valid_inclusive(valid_inclusive, expected_tuple): | ||||
|     resultant_tuple = validate_inclusive(valid_inclusive) | ||||
|     assert expected_tuple == resultant_tuple | ||||
| @ -0,0 +1,69 @@ | ||||
| import pytest | ||||
|  | ||||
| from pandas.util._validators import ( | ||||
|     validate_bool_kwarg, | ||||
|     validate_kwargs, | ||||
| ) | ||||
|  | ||||
|  | ||||
| @pytest.fixture | ||||
| def _fname(): | ||||
|     return "func" | ||||
|  | ||||
|  | ||||
| def test_bad_kwarg(_fname): | ||||
|     good_arg = "f" | ||||
|     bad_arg = good_arg + "o" | ||||
|  | ||||
|     compat_args = {good_arg: "foo", bad_arg + "o": "bar"} | ||||
|     kwargs = {good_arg: "foo", bad_arg: "bar"} | ||||
|  | ||||
|     msg = rf"{_fname}\(\) got an unexpected keyword argument '{bad_arg}'" | ||||
|  | ||||
|     with pytest.raises(TypeError, match=msg): | ||||
|         validate_kwargs(_fname, kwargs, compat_args) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("i", range(1, 3)) | ||||
| def test_not_all_none(i, _fname): | ||||
|     bad_arg = "foo" | ||||
|     msg = ( | ||||
|         rf"the '{bad_arg}' parameter is not supported " | ||||
|         rf"in the pandas implementation of {_fname}\(\)" | ||||
|     ) | ||||
|  | ||||
|     compat_args = {"foo": 1, "bar": "s", "baz": None} | ||||
|  | ||||
|     kwarg_keys = ("foo", "bar", "baz") | ||||
|     kwarg_vals = (2, "s", None) | ||||
|  | ||||
|     kwargs = dict(zip(kwarg_keys[:i], kwarg_vals[:i])) | ||||
|  | ||||
|     with pytest.raises(ValueError, match=msg): | ||||
|         validate_kwargs(_fname, kwargs, compat_args) | ||||
|  | ||||
|  | ||||
| def test_validation(_fname): | ||||
|     # No exceptions should be raised. | ||||
|     compat_args = {"f": None, "b": 1, "ba": "s"} | ||||
|  | ||||
|     kwargs = {"f": None, "b": 1} | ||||
|     validate_kwargs(_fname, kwargs, compat_args) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("name", ["inplace", "copy"]) | ||||
| @pytest.mark.parametrize("value", [1, "True", [1, 2, 3], 5.0]) | ||||
| def test_validate_bool_kwarg_fail(name, value): | ||||
|     msg = ( | ||||
|         f'For argument "{name}" expected type bool, ' | ||||
|         f"received type {type(value).__name__}" | ||||
|     ) | ||||
|  | ||||
|     with pytest.raises(ValueError, match=msg): | ||||
|         validate_bool_kwarg(value, name) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("name", ["inplace", "copy"]) | ||||
| @pytest.mark.parametrize("value", [True, False, None]) | ||||
| def test_validate_bool_kwarg(name, value): | ||||
|     assert validate_bool_kwarg(value, name) == value | ||||
		Reference in New Issue
	
	Block a user