Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/pandas/_testing/asserters.py: 12%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

444 statements  

1from __future__ import annotations 

2 

3import operator 

4from typing import ( 

5 TYPE_CHECKING, 

6 Literal, 

7 NoReturn, 

8 cast, 

9) 

10import warnings 

11 

12import numpy as np 

13 

14from pandas._libs import lib 

15from pandas._libs.missing import is_matching_na 

16from pandas._libs.sparse import SparseIndex 

17import pandas._libs.testing as _testing 

18from pandas._libs.tslibs.np_datetime import compare_mismatched_resolutions 

19from pandas.errors import Pandas4Warning 

20from pandas.util._decorators import ( 

21 deprecate_kwarg, 

22 set_module, 

23) 

24 

25from pandas.core.dtypes.common import ( 

26 is_bool, 

27 is_float_dtype, 

28 is_integer_dtype, 

29 is_number, 

30 is_numeric_dtype, 

31 needs_i8_conversion, 

32) 

33from pandas.core.dtypes.dtypes import ( 

34 CategoricalDtype, 

35 DatetimeTZDtype, 

36 ExtensionDtype, 

37 NumpyEADtype, 

38) 

39from pandas.core.dtypes.missing import array_equivalent 

40 

41import pandas as pd 

42from pandas import ( 

43 Categorical, 

44 DataFrame, 

45 DatetimeIndex, 

46 Index, 

47 IntervalDtype, 

48 IntervalIndex, 

49 MultiIndex, 

50 PeriodIndex, 

51 RangeIndex, 

52 Series, 

53 TimedeltaIndex, 

54) 

55from pandas.core.arrays import ( 

56 DatetimeArray, 

57 ExtensionArray, 

58 IntervalArray, 

59 PeriodArray, 

60 TimedeltaArray, 

61) 

62from pandas.core.arrays.datetimelike import DatetimeLikeArrayMixin 

63from pandas.core.arrays.string_ import StringDtype 

64from pandas.core.indexes.api import safe_sort_index 

65 

66from pandas.io.formats.printing import pprint_thing 

67 

68if TYPE_CHECKING: 

69 from pandas._typing import DtypeObj 

70 

71 

72def assert_almost_equal( 

73 left, 

74 right, 

75 check_dtype: bool | Literal["equiv"] = "equiv", 

76 rtol: float = 1.0e-5, 

77 atol: float = 1.0e-8, 

78 **kwargs, 

79) -> None: 

80 """ 

81 Check that the left and right objects are approximately equal. 

82 

83 By approximately equal, we refer to objects that are numbers or that 

84 contain numbers which may be equivalent to specific levels of precision. 

85 

86 Parameters 

87 ---------- 

88 left : object 

89 right : object 

90 check_dtype : bool or {'equiv'}, default 'equiv' 

91 Check dtype if both a and b are the same type. If 'equiv' is passed in, 

92 then `RangeIndex` and `Index` with int64 dtype are also considered 

93 equivalent when doing type checking. 

94 rtol : float, default 1e-5 

95 Relative tolerance. 

96 atol : float, default 1e-8 

97 Absolute tolerance. 

98 """ 

99 if isinstance(left, Index): 

100 assert_index_equal( 

101 left, 

102 right, 

103 check_exact=False, 

104 exact=check_dtype, 

105 rtol=rtol, 

106 atol=atol, 

107 **kwargs, 

108 ) 

109 

110 elif isinstance(left, Series): 

111 assert_series_equal( 

112 left, 

113 right, 

114 check_exact=False, 

115 check_dtype=check_dtype, 

116 rtol=rtol, 

117 atol=atol, 

118 **kwargs, 

119 ) 

120 

121 elif isinstance(left, DataFrame): 

122 assert_frame_equal( 

123 left, 

124 right, 

125 check_exact=False, 

126 check_dtype=check_dtype, 

127 rtol=rtol, 

128 atol=atol, 

129 **kwargs, 

130 ) 

131 

132 else: 

133 # Other sequences. 

134 if check_dtype: 

135 if is_number(left) and is_number(right): 

136 # Do not compare numeric classes, like np.float64 and float. 

137 pass 

138 elif is_bool(left) and is_bool(right): 

139 # Do not compare bool classes, like np.bool_ and bool. 

140 pass 

141 else: 

142 if isinstance(left, np.ndarray) or isinstance(right, np.ndarray): 

143 obj = "numpy array" 

144 else: 

145 obj = "Input" 

146 assert_class_equal(left, right, obj=obj) 

147 

148 # if we have "equiv", this becomes True 

149 _testing.assert_almost_equal( 

150 left, right, check_dtype=bool(check_dtype), rtol=rtol, atol=atol, **kwargs 

151 ) 

152 

153 

154def _check_isinstance(left, right, cls) -> None: 

155 """ 

156 Helper method for our assert_* methods that ensures that 

157 the two objects being compared have the right type before 

158 proceeding with the comparison. 

159 

160 Parameters 

161 ---------- 

162 left : The first object being compared. 

163 right : The second object being compared. 

164 cls : The class type to check against. 

165 

166 Raises 

167 ------ 

168 AssertionError : Either `left` or `right` is not an instance of `cls`. 

169 """ 

170 cls_name = cls.__name__ 

171 

172 if not isinstance(left, cls): 

173 raise AssertionError( 

174 f"{cls_name} Expected type {cls}, found {type(left)} instead" 

175 ) 

176 if not isinstance(right, cls): 

177 raise AssertionError( 

178 f"{cls_name} Expected type {cls}, found {type(right)} instead" 

179 ) 

180 

181 

182def assert_dict_equal(left, right, compare_keys: bool = True) -> None: 

183 _check_isinstance(left, right, dict) 

184 _testing.assert_dict_equal(left, right, compare_keys=compare_keys) 

185 

186 

187@set_module("pandas.testing") 

188def assert_index_equal( 

189 left: Index, 

190 right: Index, 

191 exact: bool | str = "equiv", 

192 check_names: bool = True, 

193 check_exact: bool = True, 

194 check_categorical: bool = True, 

195 check_order: bool = True, 

196 rtol: float = 1.0e-5, 

197 atol: float = 1.0e-8, 

198 obj: str | None = None, 

199) -> None: 

200 """ 

201 Check that left and right Index are equal. 

202 

203 Parameters 

204 ---------- 

205 left : Index 

206 The first index to compare. 

207 right : Index 

208 The second index to compare. 

209 exact : bool or {'equiv'}, default 'equiv' 

210 Whether to check the Index class, dtype and inferred_type 

211 are identical. If 'equiv', then RangeIndex can be substituted for 

212 Index with an int64 dtype as well. 

213 check_names : bool, default True 

214 Whether to check the names attribute. 

215 check_exact : bool, default True 

216 Whether to compare number exactly. 

217 check_categorical : bool, default True 

218 Whether to compare internal Categorical exactly. 

219 check_order : bool, default True 

220 Whether to compare the order of index entries as well as their values. 

221 If True, both indexes must contain the same elements, in the same order. 

222 If False, both indexes must contain the same elements, but in any order. 

223 rtol : float, default 1e-5 

224 Relative tolerance. Only used when check_exact is False. 

225 atol : float, default 1e-8 

226 Absolute tolerance. Only used when check_exact is False. 

227 obj : str, default 'Index' or 'MultiIndex' 

228 Specify object name being compared, internally used to show appropriate 

229 assertion message. 

230 

231 See Also 

232 -------- 

233 testing.assert_series_equal : Check that two Series are equal. 

234 testing.assert_frame_equal : Check that two DataFrames are equal. 

235 

236 Examples 

237 -------- 

238 >>> from pandas import testing as tm 

239 >>> a = pd.Index([1, 2, 3]) 

240 >>> b = pd.Index([1, 2, 3]) 

241 >>> tm.assert_index_equal(a, b) 

242 """ 

243 __tracebackhide__ = True 

244 

245 if obj is None: 

246 obj = "MultiIndex" if isinstance(left, MultiIndex) else "Index" 

247 

248 def _check_types(left, right, obj: str = "Index") -> None: 

249 if not exact: 

250 return 

251 

252 assert_class_equal(left, right, exact=exact, obj=obj) 

253 assert_attr_equal("inferred_type", left, right, obj=obj) 

254 

255 # Skip exact dtype checking when `check_categorical` is False 

256 if isinstance(left.dtype, CategoricalDtype) and isinstance( 

257 right.dtype, CategoricalDtype 

258 ): 

259 if check_categorical: 

260 assert_attr_equal("dtype", left, right, obj=obj) 

261 assert_index_equal(left.categories, right.categories, exact=exact) 

262 return 

263 

264 assert_attr_equal("dtype", left, right, obj=obj) 

265 

266 # instance validation 

267 _check_isinstance(left, right, Index) 

268 

269 # class / dtype comparison 

270 _check_types(left, right, obj=obj) 

271 

272 # level comparison 

273 if left.nlevels != right.nlevels: 

274 msg1 = f"{obj} levels are different" 

275 msg2 = f"{left.nlevels}, {left}" 

276 msg3 = f"{right.nlevels}, {right}" 

277 raise_assert_detail(obj, msg1, msg2, msg3) 

278 

279 # length comparison 

280 if len(left) != len(right): 

281 msg1 = f"{obj} length are different" 

282 msg2 = f"{len(left)}, {left}" 

283 msg3 = f"{len(right)}, {right}" 

284 raise_assert_detail(obj, msg1, msg2, msg3) 

285 

286 # If order doesn't matter then sort the index entries 

287 if not check_order: 

288 left = safe_sort_index(left) 

289 right = safe_sort_index(right) 

290 

291 # MultiIndex special comparison for little-friendly error messages 

292 if isinstance(left, MultiIndex): 

293 right = cast(MultiIndex, right) 

294 

295 for level in range(left.nlevels): 

296 lobj = f"{obj} level [{level}]" 

297 try: 

298 # try comparison on levels/codes to avoid densifying MultiIndex 

299 assert_index_equal( 

300 left.levels[level], 

301 right.levels[level], 

302 exact=exact, 

303 check_names=check_names, 

304 check_exact=check_exact, 

305 check_categorical=check_categorical, 

306 rtol=rtol, 

307 atol=atol, 

308 obj=lobj, 

309 ) 

310 assert_numpy_array_equal(left.codes[level], right.codes[level]) 

311 except AssertionError: 

312 llevel = left.get_level_values(level) 

313 rlevel = right.get_level_values(level) 

314 

315 assert_index_equal( 

316 llevel, 

317 rlevel, 

318 exact=exact, 

319 check_names=check_names, 

320 check_exact=check_exact, 

321 check_categorical=check_categorical, 

322 rtol=rtol, 

323 atol=atol, 

324 obj=lobj, 

325 ) 

326 # get_level_values may change dtype 

327 _check_types(left.levels[level], right.levels[level], obj=lobj) 

328 

329 # skip exact index checking when `check_categorical` is False 

330 elif check_exact and check_categorical: 

331 if not left.equals(right): 

332 # _values compare can raise TypeError (non-comparable 

333 # categoricals (GH#61935) 

334 try: 

335 mismatch = left._values != right._values 

336 except TypeError: 

337 raise_assert_detail( 

338 obj, 

339 "types are not comparable (non-matching categorical categories)", 

340 left, 

341 right, 

342 ) 

343 

344 if not isinstance(mismatch, np.ndarray): 

345 mismatch = cast("ExtensionArray", mismatch).fillna(True) 

346 

347 diff = np.sum(mismatch.astype(int)) * 100.0 / len(left) 

348 msg = f"{obj} values are different ({np.round(diff, 5)} %)" 

349 raise_assert_detail(obj, msg, left, right) 

350 else: 

351 # if we have "equiv", this becomes True 

352 exact_bool = bool(exact) 

353 _testing.assert_almost_equal( 

354 left.values, 

355 right.values, 

356 rtol=rtol, 

357 atol=atol, 

358 check_dtype=exact_bool, 

359 obj=obj, 

360 lobj=left, 

361 robj=right, 

362 ) 

363 

364 # metadata comparison 

365 if check_names: 

366 assert_attr_equal("names", left, right, obj=obj) 

367 if isinstance(left, PeriodIndex) or isinstance(right, PeriodIndex): 

368 assert_attr_equal("dtype", left, right, obj=obj) 

369 if isinstance(left, IntervalIndex) or isinstance(right, IntervalIndex): 

370 assert_interval_array_equal(left._values, right._values) 

371 

372 if check_categorical: 

373 if isinstance(left.dtype, CategoricalDtype) or isinstance( 

374 right.dtype, CategoricalDtype 

375 ): 

376 assert_categorical_equal(left._values, right._values, obj=f"{obj} category") 

377 

378 

379def assert_class_equal( 

380 left, right, exact: bool | str = True, obj: str = "Input" 

381) -> None: 

382 """ 

383 Checks classes are equal. 

384 """ 

385 __tracebackhide__ = True 

386 

387 def repr_class(x): 

388 if isinstance(x, Index): 

389 # return Index as it is to include values in the error message 

390 return x 

391 

392 return type(x).__name__ 

393 

394 def is_class_equiv(idx: Index) -> bool: 

395 """Classes that are a RangeIndex (sub-)instance or exactly an `Index` . 

396 

397 This only checks class equivalence. There is a separate check that the 

398 dtype is int64. 

399 """ 

400 return type(idx) is Index or isinstance(idx, RangeIndex) 

401 

402 if type(left) == type(right): 

403 return 

404 

405 if exact == "equiv": 

406 if is_class_equiv(left) and is_class_equiv(right): 

407 return 

408 

409 msg = f"{obj} classes are different" 

410 raise_assert_detail(obj, msg, repr_class(left), repr_class(right)) 

411 

412 

413def assert_attr_equal(attr: str, left, right, obj: str = "Attributes") -> None: 

414 """ 

415 Check attributes are equal. Both objects must have attribute. 

416 

417 Parameters 

418 ---------- 

419 attr : str 

420 Attribute name being compared. 

421 left : object 

422 right : object 

423 obj : str, default 'Attributes' 

424 Specify object name being compared, internally used to show appropriate 

425 assertion message 

426 """ 

427 __tracebackhide__ = True 

428 

429 left_attr = getattr(left, attr) 

430 right_attr = getattr(right, attr) 

431 

432 if left_attr is right_attr or is_matching_na(left_attr, right_attr): 

433 # e.g. both np.nan, both NaT, both pd.NA, ... 

434 return None 

435 

436 try: 

437 result = left_attr == right_attr 

438 except TypeError: 

439 # datetimetz on rhs may raise TypeError 

440 result = False 

441 if (left_attr is pd.NA) ^ (right_attr is pd.NA): 

442 result = False 

443 elif not isinstance(result, bool): 

444 result = result.all() 

445 

446 if not result: 

447 msg = f'Attribute "{attr}" are different' 

448 raise_assert_detail(obj, msg, left_attr, right_attr) 

449 return None 

450 

451 

452def assert_is_sorted(seq) -> None: 

453 """Assert that the sequence is sorted.""" 

454 if isinstance(seq, (Index, Series)): 

455 seq = seq.values 

456 # sorting does not change precisions 

457 if isinstance(seq, np.ndarray): 

458 assert_numpy_array_equal(seq, np.sort(np.array(seq))) 

459 else: 

460 assert_extension_array_equal(seq, seq[seq.argsort()]) 

461 

462 

463def assert_categorical_equal( 

464 left, 

465 right, 

466 check_dtype: bool = True, 

467 check_category_order: bool = True, 

468 obj: str = "Categorical", 

469) -> None: 

470 """ 

471 Test that Categoricals are equivalent. 

472 

473 Parameters 

474 ---------- 

475 left : Categorical 

476 right : Categorical 

477 check_dtype : bool, default True 

478 Check that integer dtype of the codes are the same. 

479 check_category_order : bool, default True 

480 Whether the order of the categories should be compared, which 

481 implies identical integer codes. If False, only the resulting 

482 values are compared. The ordered attribute is 

483 checked regardless. 

484 obj : str, default 'Categorical' 

485 Specify object name being compared, internally used to show appropriate 

486 assertion message. 

487 """ 

488 _check_isinstance(left, right, Categorical) 

489 

490 exact: bool | str 

491 if isinstance(left.categories, RangeIndex) or isinstance( 

492 right.categories, RangeIndex 

493 ): 

494 exact = "equiv" 

495 else: 

496 # We still want to require exact matches for Index 

497 exact = True 

498 

499 if check_category_order: 

500 assert_index_equal( 

501 left.categories, right.categories, obj=f"{obj}.categories", exact=exact 

502 ) 

503 assert_numpy_array_equal( 

504 left.codes, right.codes, check_dtype=check_dtype, obj=f"{obj}.codes" 

505 ) 

506 else: 

507 try: 

508 lc = left.categories.sort_values() 

509 rc = right.categories.sort_values() 

510 except TypeError: 

511 # e.g. '<' not supported between instances of 'int' and 'str' 

512 lc, rc = left.categories, right.categories 

513 assert_index_equal(lc, rc, obj=f"{obj}.categories", exact=exact) 

514 assert_index_equal( 

515 left.categories.take(left.codes), 

516 right.categories.take(right.codes), 

517 obj=f"{obj}.values", 

518 exact=exact, 

519 ) 

520 

521 assert_attr_equal("ordered", left, right, obj=obj) 

522 

523 

524def assert_interval_array_equal( 

525 left, right, exact: bool | Literal["equiv"] = "equiv", obj: str = "IntervalArray" 

526) -> None: 

527 """ 

528 Test that two IntervalArrays are equivalent. 

529 

530 Parameters 

531 ---------- 

532 left, right : IntervalArray 

533 The IntervalArrays to compare. 

534 exact : bool or {'equiv'}, default 'equiv' 

535 Whether to check the Index class, dtype and inferred_type 

536 are identical. If 'equiv', then RangeIndex can be substituted for 

537 Index with an int64 dtype as well. 

538 obj : str, default 'IntervalArray' 

539 Specify object name being compared, internally used to show appropriate 

540 assertion message 

541 """ 

542 _check_isinstance(left, right, IntervalArray) 

543 

544 kwargs = {} 

545 if left._left.dtype.kind in "mM": 

546 # We have a DatetimeArray or TimedeltaArray 

547 kwargs["check_freq"] = False 

548 

549 assert_equal(left._left, right._left, obj=f"{obj}.left", **kwargs) 

550 assert_equal(left._right, right._right, obj=f"{obj}.right", **kwargs) 

551 

552 assert_attr_equal("closed", left, right, obj=obj) 

553 

554 

555def assert_period_array_equal(left, right, obj: str = "PeriodArray") -> None: 

556 _check_isinstance(left, right, PeriodArray) 

557 

558 assert_numpy_array_equal(left._ndarray, right._ndarray, obj=f"{obj}._ndarray") 

559 assert_attr_equal("dtype", left, right, obj=obj) 

560 

561 

562def assert_datetime_array_equal( 

563 left, right, obj: str = "DatetimeArray", check_freq: bool = True 

564) -> None: 

565 __tracebackhide__ = True 

566 _check_isinstance(left, right, DatetimeArray) 

567 

568 assert_numpy_array_equal(left._ndarray, right._ndarray, obj=f"{obj}._ndarray") 

569 if check_freq: 

570 assert_attr_equal("freq", left, right, obj=obj) 

571 assert_attr_equal("tz", left, right, obj=obj) 

572 

573 

574def assert_timedelta_array_equal( 

575 left, right, obj: str = "TimedeltaArray", check_freq: bool = True 

576) -> None: 

577 __tracebackhide__ = True 

578 _check_isinstance(left, right, TimedeltaArray) 

579 assert_numpy_array_equal(left._ndarray, right._ndarray, obj=f"{obj}._ndarray") 

580 if check_freq: 

581 assert_attr_equal("freq", left, right, obj=obj) 

582 

583 

584def raise_assert_detail( 

585 obj, message, left, right, diff=None, first_diff=None, index_values=None 

586) -> NoReturn: 

587 __tracebackhide__ = True 

588 

589 msg = f"""{obj} are different 

590 

591{message}""" 

592 

593 if isinstance(index_values, Index): 

594 index_values = np.asarray(index_values) 

595 

596 if isinstance(index_values, np.ndarray): 

597 msg += f"\n[index]: {pprint_thing(index_values)}" 

598 

599 if isinstance(left, np.ndarray): 

600 left = pprint_thing(left) 

601 elif isinstance(left, (CategoricalDtype, StringDtype, NumpyEADtype)): 

602 left = repr(left) 

603 

604 if isinstance(right, np.ndarray): 

605 right = pprint_thing(right) 

606 elif isinstance(right, (CategoricalDtype, StringDtype, NumpyEADtype)): 

607 right = repr(right) 

608 

609 msg += f""" 

610[left]: {left} 

611[right]: {right}""" 

612 

613 if diff is not None: 

614 msg += f"\n[diff]: {diff}" 

615 

616 if first_diff is not None: 

617 msg += f"\n{first_diff}" 

618 

619 raise AssertionError(msg) 

620 

621 

622def assert_numpy_array_equal( 

623 left, 

624 right, 

625 strict_nan: bool = False, 

626 check_dtype: bool | Literal["equiv"] = True, 

627 err_msg=None, 

628 check_same=None, 

629 obj: str = "numpy array", 

630 index_values=None, 

631) -> None: 

632 """ 

633 Check that 'np.ndarray' is equivalent. 

634 

635 Parameters 

636 ---------- 

637 left, right : numpy.ndarray or iterable 

638 The two arrays to be compared. 

639 strict_nan : bool, default False 

640 If True, consider NaN and None to be different. 

641 check_dtype : bool, default True 

642 Check dtype if both a and b are np.ndarray. 

643 err_msg : str, default None 

644 If provided, used as assertion message. 

645 check_same : None|'copy'|'same', default None 

646 Ensure left and right refer/do not refer to the same memory area. 

647 obj : str, default 'numpy array' 

648 Specify object name being compared, internally used to show appropriate 

649 assertion message. 

650 index_values : Index | numpy.ndarray, default None 

651 optional index (shared by both left and right), used in output. 

652 """ 

653 __tracebackhide__ = True 

654 

655 # instance validation 

656 # Show a detailed error message when classes are different 

657 assert_class_equal(left, right, obj=obj) 

658 # both classes must be an np.ndarray 

659 _check_isinstance(left, right, np.ndarray) 

660 

661 def _get_base(obj): 

662 return obj.base if getattr(obj, "base", None) is not None else obj 

663 

664 left_base = _get_base(left) 

665 right_base = _get_base(right) 

666 

667 if check_same == "same": 

668 if left_base is not right_base: 

669 raise AssertionError(f"{left_base!r} is not {right_base!r}") 

670 elif check_same == "copy": 

671 if left_base is right_base: 

672 raise AssertionError(f"{left_base!r} is {right_base!r}") 

673 

674 def _raise(left, right, err_msg) -> NoReturn: 

675 if err_msg is None: 

676 if left.shape != right.shape: 

677 raise_assert_detail( 

678 obj, f"{obj} shapes are different", left.shape, right.shape 

679 ) 

680 

681 diff = 0 

682 for left_arr, right_arr in zip(left, right, strict=True): 

683 # count up differences 

684 if not array_equivalent(left_arr, right_arr, strict_nan=strict_nan): 

685 diff += 1 

686 

687 diff = diff * 100.0 / left.size 

688 msg = f"{obj} values are different ({np.round(diff, 5)} %)" 

689 raise_assert_detail(obj, msg, left, right, index_values=index_values) 

690 

691 raise AssertionError(err_msg) 

692 

693 # compare shape and values 

694 if not array_equivalent(left, right, strict_nan=strict_nan): 

695 _raise(left, right, err_msg) 

696 

697 if check_dtype: 

698 if isinstance(left, np.ndarray) and isinstance(right, np.ndarray): 

699 assert_attr_equal("dtype", left, right, obj=obj) 

700 

701 

702@set_module("pandas.testing") 

703def assert_extension_array_equal( 

704 left, 

705 right, 

706 check_dtype: bool | Literal["equiv"] = True, 

707 index_values=None, 

708 check_exact: bool | lib.NoDefault = lib.no_default, 

709 rtol: float | lib.NoDefault = lib.no_default, 

710 atol: float | lib.NoDefault = lib.no_default, 

711 obj: str = "ExtensionArray", 

712) -> None: 

713 """ 

714 Check that left and right ExtensionArrays are equal. 

715 

716 This method compares two ``ExtensionArray`` instances for equality, 

717 including checks for missing values, the dtype of the arrays, and 

718 the exactness of the comparison (or tolerance when comparing floats). 

719 

720 Parameters 

721 ---------- 

722 left, right : ExtensionArray 

723 The two arrays to compare. 

724 check_dtype : bool, default True 

725 Whether to check if the ExtensionArray dtypes are identical. 

726 index_values : Index | numpy.ndarray, default None 

727 Optional index (shared by both left and right), used in output. 

728 check_exact : bool, default False 

729 Whether to compare number exactly. 

730 

731 .. versionchanged:: 2.2.0 

732 

733 Defaults to True for integer dtypes if none of 

734 ``check_exact``, ``rtol`` and ``atol`` are specified. 

735 rtol : float, default 1e-5 

736 Relative tolerance. Only used when check_exact is False. 

737 atol : float, default 1e-8 

738 Absolute tolerance. Only used when check_exact is False. 

739 obj : str, default 'ExtensionArray' 

740 Specify object name being compared, internally used to show appropriate 

741 assertion message. 

742 

743 .. versionadded:: 2.0.0 

744 

745 See Also 

746 -------- 

747 testing.assert_series_equal : Check that left and right ``Series`` are equal. 

748 testing.assert_frame_equal : Check that left and right ``DataFrame`` are equal. 

749 testing.assert_index_equal : Check that left and right ``Index`` are equal. 

750 

751 Notes 

752 ----- 

753 Missing values are checked separately from valid values. 

754 A mask of missing values is computed for each and checked to match. 

755 The remaining all-valid values are cast to object dtype and checked. 

756 

757 Examples 

758 -------- 

759 >>> from pandas import testing as tm 

760 >>> a = pd.Series([1, 2, 3, 4]) 

761 >>> b, c = a.array, a.array 

762 >>> tm.assert_extension_array_equal(b, c) 

763 """ 

764 if ( 

765 check_exact is lib.no_default 

766 and rtol is lib.no_default 

767 and atol is lib.no_default 

768 ): 

769 check_exact = ( 

770 is_numeric_dtype(left.dtype) and not is_float_dtype(left.dtype) 

771 ) or (is_numeric_dtype(right.dtype) and not is_float_dtype(right.dtype)) 

772 elif check_exact is lib.no_default: 

773 check_exact = False 

774 

775 rtol = rtol if rtol is not lib.no_default else 1.0e-5 

776 atol = atol if atol is not lib.no_default else 1.0e-8 

777 

778 assert isinstance(left, ExtensionArray), "left is not an ExtensionArray" 

779 assert isinstance(right, ExtensionArray), "right is not an ExtensionArray" 

780 if check_dtype: 

781 assert_attr_equal("dtype", left, right, obj=f"Attributes of {obj}") 

782 

783 if ( 

784 isinstance(left, DatetimeLikeArrayMixin) 

785 and isinstance(right, DatetimeLikeArrayMixin) 

786 and type(right) == type(left) 

787 ): 

788 # GH 52449 

789 if not check_dtype and left.dtype.kind in "mM": 

790 if not isinstance(left.dtype, np.dtype): 

791 l_unit = cast(DatetimeTZDtype, left.dtype).unit 

792 else: 

793 l_unit = np.datetime_data(left.dtype)[0] 

794 if not isinstance(right.dtype, np.dtype): 

795 r_unit = cast(DatetimeTZDtype, right.dtype).unit 

796 else: 

797 r_unit = np.datetime_data(right.dtype)[0] 

798 if ( 

799 l_unit != r_unit 

800 and compare_mismatched_resolutions( 

801 left._ndarray, right._ndarray, operator.eq 

802 ).all() 

803 ): 

804 return 

805 # Avoid slow object-dtype comparisons 

806 # np.asarray for case where we have an np.MaskedArray 

807 assert_numpy_array_equal( 

808 np.asarray(left.asi8), 

809 np.asarray(right.asi8), 

810 index_values=index_values, 

811 obj=obj, 

812 ) 

813 return 

814 

815 left_na = np.asarray(left.isna()) 

816 right_na = np.asarray(right.isna()) 

817 assert_numpy_array_equal( 

818 left_na, right_na, obj=f"{obj} NA mask", index_values=index_values 

819 ) 

820 

821 # Specifically for StringArrayNumpySemantics, validate here we have a valid array 

822 if ( 

823 isinstance(left.dtype, StringDtype) 

824 and left.dtype.storage == "python" 

825 and left.dtype.na_value is np.nan 

826 ): 

827 assert np.all( 

828 [np.isnan(val) for val in left._ndarray[left_na]] # type: ignore[attr-defined] 

829 ), "wrong missing value sentinels" 

830 if ( 

831 isinstance(right.dtype, StringDtype) 

832 and right.dtype.storage == "python" 

833 and right.dtype.na_value is np.nan 

834 ): 

835 assert np.all( 

836 [np.isnan(val) for val in right._ndarray[right_na]] # type: ignore[attr-defined] 

837 ), "wrong missing value sentinels" 

838 

839 left_valid = left[~left_na].to_numpy(dtype=object) 

840 right_valid = right[~right_na].to_numpy(dtype=object) 

841 if check_exact: 

842 assert_numpy_array_equal( 

843 left_valid, right_valid, obj=obj, index_values=index_values 

844 ) 

845 else: 

846 _testing.assert_almost_equal( 

847 left_valid, 

848 right_valid, 

849 check_dtype=bool(check_dtype), 

850 rtol=rtol, 

851 atol=atol, 

852 obj=obj, 

853 index_values=index_values, 

854 ) 

855 

856 

857# This could be refactored to use the NDFrame.equals method 

858@set_module("pandas.testing") 

859@deprecate_kwarg(Pandas4Warning, "check_datetimelike_compat", new_arg_name=None) 

860def assert_series_equal( 

861 left, 

862 right, 

863 check_dtype: bool | Literal["equiv"] = True, 

864 check_index_type: bool | Literal["equiv"] = "equiv", 

865 check_series_type: bool = True, 

866 check_names: bool = True, 

867 check_exact: bool | lib.NoDefault = lib.no_default, 

868 check_datetimelike_compat: bool = False, 

869 check_categorical: bool = True, 

870 check_category_order: bool = True, 

871 check_freq: bool = True, 

872 check_flags: bool = True, 

873 rtol: float | lib.NoDefault = lib.no_default, 

874 atol: float | lib.NoDefault = lib.no_default, 

875 obj: str = "Series", 

876 *, 

877 check_index: bool = True, 

878 check_like: bool = False, 

879) -> None: 

880 """ 

881 Check that left and right Series are equal. 

882 

883 Parameters 

884 ---------- 

885 left : Series 

886 First Series to compare. 

887 right : Series 

888 Second Series to compare. 

889 check_dtype : bool, default True 

890 Whether to check the Series dtype is identical. 

891 check_index_type : bool or {'equiv'}, default 'equiv' 

892 Whether to check the Index class, dtype and inferred_type 

893 are identical. 

894 check_series_type : bool, default True 

895 Whether to check the Series class is identical. 

896 check_names : bool, default True 

897 Whether to check the Series and Index names attribute. 

898 check_exact : bool, default False 

899 Whether to compare number exactly. This also applies when checking 

900 Index equivalence. 

901 

902 .. versionchanged:: 2.2.0 

903 

904 Defaults to True for integer dtypes if none of 

905 ``check_exact``, ``rtol`` and ``atol`` are specified. 

906 

907 .. versionchanged:: 3.0.0 

908 

909 check_exact for comparing the Indexes defaults to True by 

910 checking if an Index is of integer dtypes. 

911 

912 check_datetimelike_compat : bool, default False 

913 Compare datetime-like which is comparable ignoring dtype. 

914 

915 .. deprecated:: 3.0 

916 

917 check_categorical : bool, default True 

918 Whether to compare internal Categorical exactly. 

919 check_category_order : bool, default True 

920 Whether to compare category order of internal Categoricals. 

921 check_freq : bool, default True 

922 Whether to check the `freq` attribute on a DatetimeIndex or TimedeltaIndex. 

923 check_flags : bool, default True 

924 Whether to check the `flags` attribute. 

925 rtol : float, default 1e-5 

926 Relative tolerance. Only used when check_exact is False. 

927 atol : float, default 1e-8 

928 Absolute tolerance. Only used when check_exact is False. 

929 obj : str, default 'Series' 

930 Specify object name being compared, internally used to show appropriate 

931 assertion message. 

932 check_index : bool, default True 

933 Whether to check index equivalence. If False, then compare only values. 

934 check_like : bool, default False 

935 If True, ignore the order of the index. Must be False if check_index is False. 

936 Note: same labels must be with the same data. 

937 

938 See Also 

939 -------- 

940 testing.assert_index_equal : Check that two Indexes are equal. 

941 testing.assert_frame_equal : Check that two DataFrames are equal. 

942 

943 Examples 

944 -------- 

945 >>> from pandas import testing as tm 

946 >>> a = pd.Series([1, 2, 3, 4]) 

947 >>> b = pd.Series([1, 2, 3, 4]) 

948 >>> tm.assert_series_equal(a, b) 

949 """ 

950 __tracebackhide__ = True 

951 if ( 

952 check_exact is lib.no_default 

953 and rtol is lib.no_default 

954 and atol is lib.no_default 

955 ): 

956 check_exact = ( 

957 is_numeric_dtype(left.dtype) and not is_float_dtype(left.dtype) 

958 ) or (is_numeric_dtype(right.dtype) and not is_float_dtype(right.dtype)) 

959 left_index_dtypes = ( 

960 [left.index.dtype] if left.index.nlevels == 1 else left.index.dtypes 

961 ) 

962 right_index_dtypes = ( 

963 [right.index.dtype] if right.index.nlevels == 1 else right.index.dtypes 

964 ) 

965 check_exact_index = all( 

966 dtype.kind in "iu" for dtype in left_index_dtypes 

967 ) or all(dtype.kind in "iu" for dtype in right_index_dtypes) 

968 elif check_exact is lib.no_default: 

969 check_exact = False 

970 check_exact_index = False 

971 else: 

972 check_exact_index = check_exact 

973 

974 rtol = rtol if rtol is not lib.no_default else 1.0e-5 

975 atol = atol if atol is not lib.no_default else 1.0e-8 

976 

977 if not check_index and check_like: 

978 raise ValueError("check_like must be False if check_index is False") 

979 

980 # instance validation 

981 _check_isinstance(left, right, Series) 

982 

983 if check_series_type: 

984 assert_class_equal(left, right, obj=obj) 

985 

986 # length comparison 

987 if len(left) != len(right): 

988 msg1 = f"{len(left)}, {left.index}" 

989 msg2 = f"{len(right)}, {right.index}" 

990 raise_assert_detail(obj, "Series length are different", msg1, msg2) 

991 

992 if check_flags: 

993 assert left.flags == right.flags, f"{left.flags!r} != {right.flags!r}" 

994 

995 if check_index: 

996 # GH #38183 

997 assert_index_equal( 

998 left.index, 

999 right.index, 

1000 exact=check_index_type, 

1001 check_names=check_names, 

1002 check_exact=check_exact_index, 

1003 check_categorical=check_categorical, 

1004 check_order=not check_like, 

1005 rtol=rtol, 

1006 atol=atol, 

1007 obj=f"{obj}.index", 

1008 ) 

1009 

1010 if check_like: 

1011 left = left.reindex_like(right) 

1012 

1013 if check_freq and isinstance(left.index, (DatetimeIndex, TimedeltaIndex)): 

1014 lidx = left.index 

1015 ridx = right.index 

1016 assert lidx.freq == ridx.freq, (lidx.freq, ridx.freq) 

1017 

1018 if check_dtype: 

1019 # We want to skip exact dtype checking when `check_categorical` 

1020 # is False. We'll still raise if only one is a `Categorical`, 

1021 # regardless of `check_categorical` 

1022 if ( 

1023 isinstance(left.dtype, CategoricalDtype) 

1024 and isinstance(right.dtype, CategoricalDtype) 

1025 and not check_categorical 

1026 ): 

1027 pass 

1028 else: 

1029 assert_attr_equal("dtype", left, right, obj=f"Attributes of {obj}") 

1030 if check_exact: 

1031 left_values = left._values 

1032 right_values = right._values 

1033 # Only check exact if dtype is numeric 

1034 if isinstance(left_values, ExtensionArray) and isinstance( 

1035 right_values, ExtensionArray 

1036 ): 

1037 assert_extension_array_equal( 

1038 left_values, 

1039 right_values, 

1040 check_dtype=check_dtype, 

1041 index_values=left.index, 

1042 obj=str(obj), 

1043 ) 

1044 else: 

1045 # convert both to NumPy if not, check_dtype would raise earlier 

1046 lv, rv = left_values, right_values 

1047 if isinstance(left_values, ExtensionArray): 

1048 lv = left_values.to_numpy() 

1049 if isinstance(right_values, ExtensionArray): 

1050 rv = right_values.to_numpy() 

1051 assert_numpy_array_equal( 

1052 lv, 

1053 rv, 

1054 check_dtype=check_dtype, 

1055 obj=str(obj), 

1056 index_values=left.index, 

1057 ) 

1058 elif check_datetimelike_compat and ( 

1059 needs_i8_conversion(left.dtype) or needs_i8_conversion(right.dtype) 

1060 ): 

1061 # we want to check only if we have compat dtypes 

1062 # e.g. integer and M|m are NOT compat, but we can simply check 

1063 # the values in that case 

1064 

1065 # datetimelike may have different objects (e.g. datetime.datetime 

1066 # vs Timestamp) but will compare equal 

1067 if not Index(left._values).equals(Index(right._values)): 

1068 msg = ( 

1069 f"[datetimelike_compat=True] {left._values} " 

1070 f"is not equal to {right._values}." 

1071 ) 

1072 raise AssertionError(msg) 

1073 elif isinstance(left.dtype, IntervalDtype) and isinstance( 

1074 right.dtype, IntervalDtype 

1075 ): 

1076 assert_interval_array_equal(left.array, right.array) 

1077 elif isinstance(left.dtype, CategoricalDtype) or isinstance( 

1078 right.dtype, CategoricalDtype 

1079 ): 

1080 _testing.assert_almost_equal( 

1081 left._values, 

1082 right._values, 

1083 rtol=rtol, 

1084 atol=atol, 

1085 check_dtype=bool(check_dtype), 

1086 obj=str(obj), 

1087 index_values=left.index, 

1088 ) 

1089 elif isinstance(left.dtype, ExtensionDtype) and isinstance( 

1090 right.dtype, ExtensionDtype 

1091 ): 

1092 assert_extension_array_equal( 

1093 left._values, 

1094 right._values, 

1095 rtol=rtol, 

1096 atol=atol, 

1097 check_dtype=check_dtype, 

1098 index_values=left.index, 

1099 obj=str(obj), 

1100 ) 

1101 elif is_extension_array_dtype_and_needs_i8_conversion( 

1102 left.dtype, right.dtype 

1103 ) or is_extension_array_dtype_and_needs_i8_conversion(right.dtype, left.dtype): 

1104 assert_extension_array_equal( 

1105 left._values, 

1106 right._values, 

1107 check_dtype=check_dtype, 

1108 index_values=left.index, 

1109 obj=str(obj), 

1110 ) 

1111 elif needs_i8_conversion(left.dtype) and needs_i8_conversion(right.dtype): 

1112 # DatetimeArray or TimedeltaArray 

1113 assert_extension_array_equal( 

1114 left._values, 

1115 right._values, 

1116 check_dtype=check_dtype, 

1117 index_values=left.index, 

1118 obj=str(obj), 

1119 ) 

1120 else: 

1121 _testing.assert_almost_equal( 

1122 left._values, 

1123 right._values, 

1124 rtol=rtol, 

1125 atol=atol, 

1126 check_dtype=bool(check_dtype), 

1127 obj=str(obj), 

1128 index_values=left.index, 

1129 ) 

1130 

1131 # metadata comparison 

1132 if check_names: 

1133 assert_attr_equal("name", left, right, obj=obj) 

1134 

1135 if check_categorical: 

1136 if isinstance(left.dtype, CategoricalDtype) or isinstance( 

1137 right.dtype, CategoricalDtype 

1138 ): 

1139 assert_categorical_equal( 

1140 left._values, 

1141 right._values, 

1142 obj=f"{obj} category", 

1143 check_category_order=check_category_order, 

1144 ) 

1145 

1146 

1147# This could be refactored to use the NDFrame.equals method 

1148@set_module("pandas.testing") 

1149@deprecate_kwarg(Pandas4Warning, "check_datetimelike_compat", new_arg_name=None) 

1150def assert_frame_equal( 

1151 left, 

1152 right, 

1153 check_dtype: bool | Literal["equiv"] = True, 

1154 check_index_type: bool | Literal["equiv"] = "equiv", 

1155 check_column_type: bool | Literal["equiv"] = "equiv", 

1156 check_frame_type: bool = True, 

1157 check_names: bool = True, 

1158 by_blocks: bool = False, 

1159 check_exact: bool | lib.NoDefault = lib.no_default, 

1160 check_datetimelike_compat: bool = False, 

1161 check_categorical: bool = True, 

1162 check_like: bool = False, 

1163 check_freq: bool = True, 

1164 check_flags: bool = True, 

1165 rtol: float | lib.NoDefault = lib.no_default, 

1166 atol: float | lib.NoDefault = lib.no_default, 

1167 obj: str = "DataFrame", 

1168) -> None: 

1169 """ 

1170 Check that left and right DataFrame are equal. 

1171 

1172 This function is intended to compare two DataFrames and output any 

1173 differences. It is mostly intended for use in unit tests. 

1174 Additional parameters allow varying the strictness of the 

1175 equality checks performed. 

1176 

1177 Parameters 

1178 ---------- 

1179 left : DataFrame 

1180 First DataFrame to compare. 

1181 right : DataFrame 

1182 Second DataFrame to compare. 

1183 check_dtype : bool, default True 

1184 Whether to check the DataFrame dtype is identical. 

1185 check_index_type : bool or {'equiv'}, default 'equiv' 

1186 Whether to check the Index class, dtype and inferred_type 

1187 are identical. 

1188 check_column_type : bool or {'equiv'}, default 'equiv' 

1189 Whether to check the columns class, dtype and inferred_type 

1190 are identical. Is passed as the ``exact`` argument of 

1191 :func:`assert_index_equal`. 

1192 check_frame_type : bool, default True 

1193 Whether to check the DataFrame class is identical. 

1194 check_names : bool, default True 

1195 Whether to check that the `names` attribute for both the `index` 

1196 and `column` attributes of the DataFrame is identical. 

1197 by_blocks : bool, default False 

1198 Specify how to compare internal data. If False, compare by columns. 

1199 If True, compare by blocks. 

1200 check_exact : bool, default False 

1201 Whether to compare number exactly. If False, the comparison uses the 

1202 relative tolerance (``rtol``) and absolute tolerance (``atol``) 

1203 parameters to determine if two values are considered close, 

1204 according to the formula: ``|a - b| <= (atol + rtol * |b|)``. 

1205 

1206 .. versionchanged:: 2.2.0 

1207 

1208 Defaults to True for integer dtypes if none of 

1209 ``check_exact``, ``rtol`` and ``atol`` are specified. 

1210 check_datetimelike_compat : bool, default False 

1211 Compare datetime-like which is comparable ignoring dtype. 

1212 

1213 .. deprecated:: 3.0 

1214 

1215 check_categorical : bool, default True 

1216 Whether to compare internal Categorical exactly. 

1217 check_like : bool, default False 

1218 If True, ignore the order of index & columns. 

1219 Note: index labels must match their respective rows 

1220 (same as in columns) - same labels must be with the same data. 

1221 check_freq : bool, default True 

1222 Whether to check the `freq` attribute on a DatetimeIndex or TimedeltaIndex. 

1223 check_flags : bool, default True 

1224 Whether to check the `flags` attribute. 

1225 rtol : float, default 1e-5 

1226 Relative tolerance. Only used when check_exact is False. 

1227 atol : float, default 1e-8 

1228 Absolute tolerance. Only used when check_exact is False. 

1229 obj : str, default 'DataFrame' 

1230 Specify object name being compared, internally used to show appropriate 

1231 assertion message. 

1232 

1233 See Also 

1234 -------- 

1235 assert_series_equal : Equivalent method for asserting Series equality. 

1236 DataFrame.equals : Check DataFrame equality. 

1237 

1238 Examples 

1239 -------- 

1240 This example shows comparing two DataFrames that are equal 

1241 but with columns of differing dtypes. 

1242 

1243 >>> from pandas.testing import assert_frame_equal 

1244 >>> df1 = pd.DataFrame({"a": [1, 2], "b": [3, 4]}) 

1245 >>> df2 = pd.DataFrame({"a": [1, 2], "b": [3.0, 4.0]}) 

1246 

1247 df1 equals itself. 

1248 

1249 >>> assert_frame_equal(df1, df1) 

1250 

1251 df1 differs from df2 as column 'b' is of a different type. 

1252 

1253 >>> assert_frame_equal(df1, df2) 

1254 Traceback (most recent call last): 

1255 ... 

1256 AssertionError: Attributes of DataFrame.iloc[:, 1] (column name="b") are different 

1257 

1258 Attribute "dtype" are different 

1259 [left]: int64 

1260 [right]: float64 

1261 

1262 Ignore differing dtypes in columns with check_dtype. 

1263 

1264 >>> assert_frame_equal(df1, df2, check_dtype=False) 

1265 """ 

1266 __tracebackhide__ = True 

1267 _rtol = rtol if rtol is not lib.no_default else 1.0e-5 

1268 _atol = atol if atol is not lib.no_default else 1.0e-8 

1269 _check_exact = check_exact if check_exact is not lib.no_default else False 

1270 

1271 # instance validation 

1272 _check_isinstance(left, right, DataFrame) 

1273 

1274 if check_frame_type: 

1275 assert isinstance(left, type(right)) 

1276 # assert_class_equal(left, right, obj=obj) 

1277 

1278 # shape comparison 

1279 if left.shape != right.shape: 

1280 raise_assert_detail( 

1281 obj, f"{obj} shape mismatch", f"{left.shape!r}", f"{right.shape!r}" 

1282 ) 

1283 

1284 if check_flags: 

1285 assert left.flags == right.flags, f"{left.flags!r} != {right.flags!r}" 

1286 

1287 # index comparison 

1288 assert_index_equal( 

1289 left.index, 

1290 right.index, 

1291 exact=check_index_type, 

1292 check_names=check_names, 

1293 check_exact=_check_exact, 

1294 check_categorical=check_categorical, 

1295 check_order=not check_like, 

1296 rtol=_rtol, 

1297 atol=_atol, 

1298 obj=f"{obj}.index", 

1299 ) 

1300 

1301 # column comparison 

1302 assert_index_equal( 

1303 left.columns, 

1304 right.columns, 

1305 exact=check_column_type, 

1306 check_names=check_names, 

1307 check_exact=_check_exact, 

1308 check_categorical=check_categorical, 

1309 check_order=not check_like, 

1310 rtol=_rtol, 

1311 atol=_atol, 

1312 obj=f"{obj}.columns", 

1313 ) 

1314 

1315 if check_like: 

1316 left = left.reindex_like(right) 

1317 

1318 # compare by blocks 

1319 if by_blocks: 

1320 rblocks = right._to_dict_of_blocks() 

1321 lblocks = left._to_dict_of_blocks() 

1322 for dtype in list(set(list(lblocks.keys()) + list(rblocks.keys()))): 

1323 assert dtype in lblocks 

1324 assert dtype in rblocks 

1325 assert_frame_equal( 

1326 lblocks[dtype], rblocks[dtype], check_dtype=check_dtype, obj=obj 

1327 ) 

1328 

1329 # compare by columns 

1330 else: 

1331 for i, col in enumerate(left.columns): 

1332 # We have already checked that columns match, so we can do 

1333 # fast location-based lookups 

1334 lcol = left._ixs(i, axis=1) 

1335 rcol = right._ixs(i, axis=1) 

1336 

1337 # GH #38183 

1338 # use check_index=False, because we do not want to run 

1339 # assert_index_equal for each column, 

1340 # as we already checked it for the whole dataframe before. 

1341 with warnings.catch_warnings(): 

1342 warnings.filterwarnings( 

1343 "ignore", 

1344 message="the 'check_datetimelike_compat' keyword", 

1345 category=Pandas4Warning, 

1346 ) 

1347 assert_series_equal( 

1348 lcol, 

1349 rcol, 

1350 check_dtype=check_dtype, 

1351 check_index_type=check_index_type, 

1352 check_exact=check_exact, 

1353 check_names=check_names, 

1354 check_datetimelike_compat=check_datetimelike_compat, 

1355 check_categorical=check_categorical, 

1356 check_freq=check_freq, 

1357 obj=f'{obj}.iloc[:, {i}] (column name="{col}")', 

1358 rtol=rtol, 

1359 atol=atol, 

1360 check_index=False, 

1361 check_flags=False, 

1362 ) 

1363 

1364 

1365def assert_equal(left, right, **kwargs) -> None: 

1366 """ 

1367 Wrapper for tm.assert_*_equal to dispatch to the appropriate test function. 

1368 

1369 Parameters 

1370 ---------- 

1371 left, right : Index, Series, DataFrame, ExtensionArray, or np.ndarray 

1372 The two items to be compared. 

1373 **kwargs 

1374 All keyword arguments are passed through to the underlying assert method. 

1375 """ 

1376 __tracebackhide__ = True 

1377 

1378 if isinstance(left, Index): 

1379 assert_index_equal(left, right, **kwargs) 

1380 if isinstance(left, (DatetimeIndex, TimedeltaIndex)): 

1381 assert left.freq == right.freq, (left.freq, right.freq) 

1382 elif isinstance(left, Series): 

1383 assert_series_equal(left, right, **kwargs) 

1384 elif isinstance(left, DataFrame): 

1385 assert_frame_equal(left, right, **kwargs) 

1386 elif isinstance(left, IntervalArray): 

1387 assert_interval_array_equal(left, right, **kwargs) 

1388 elif isinstance(left, PeriodArray): 

1389 assert_period_array_equal(left, right, **kwargs) 

1390 elif isinstance(left, DatetimeArray): 

1391 assert_datetime_array_equal(left, right, **kwargs) 

1392 elif isinstance(left, TimedeltaArray): 

1393 assert_timedelta_array_equal(left, right, **kwargs) 

1394 elif isinstance(left, ExtensionArray): 

1395 assert_extension_array_equal(left, right, **kwargs) 

1396 elif isinstance(left, np.ndarray): 

1397 assert_numpy_array_equal(left, right, **kwargs) 

1398 elif isinstance(left, str): 

1399 assert kwargs == {} 

1400 assert left == right 

1401 else: 

1402 assert kwargs == {} 

1403 assert_almost_equal(left, right) 

1404 

1405 

1406def assert_sp_array_equal(left, right) -> None: 

1407 """ 

1408 Check that the left and right SparseArray are equal. 

1409 

1410 Parameters 

1411 ---------- 

1412 left : SparseArray 

1413 right : SparseArray 

1414 """ 

1415 _check_isinstance(left, right, pd.arrays.SparseArray) 

1416 

1417 assert_numpy_array_equal(left.sp_values, right.sp_values) 

1418 

1419 # SparseIndex comparison 

1420 assert isinstance(left.sp_index, SparseIndex) 

1421 assert isinstance(right.sp_index, SparseIndex) 

1422 

1423 left_index = left.sp_index 

1424 right_index = right.sp_index 

1425 

1426 if not left_index.equals(right_index): 

1427 raise_assert_detail( 

1428 "SparseArray.index", "index are not equal", left_index, right_index 

1429 ) 

1430 else: 

1431 # Just ensure a 

1432 pass 

1433 

1434 assert_attr_equal("fill_value", left, right) 

1435 assert_attr_equal("dtype", left, right) 

1436 assert_numpy_array_equal(left.to_dense(), right.to_dense()) 

1437 

1438 

1439def assert_contains_all(iterable, dic) -> None: 

1440 for k in iterable: 

1441 assert k in dic, f"Did not contain item: {k!r}" 

1442 

1443 

1444def assert_copy(iter1, iter2, **eql_kwargs) -> None: 

1445 """ 

1446 iter1, iter2: iterables that produce elements 

1447 comparable with assert_almost_equal 

1448 

1449 Checks that the elements are equal, but not 

1450 the same object. (Does not check that items 

1451 in sequences are also not the same object) 

1452 """ 

1453 for elem1, elem2 in zip(iter1, iter2, strict=True): 

1454 assert_almost_equal(elem1, elem2, **eql_kwargs) 

1455 msg = ( 

1456 f"Expected object {type(elem1)!r} and object {type(elem2)!r} to be " 

1457 "different objects, but they were the same object." 

1458 ) 

1459 assert elem1 is not elem2, msg 

1460 

1461 

1462def is_extension_array_dtype_and_needs_i8_conversion( 

1463 left_dtype: DtypeObj, right_dtype: DtypeObj 

1464) -> bool: 

1465 """ 

1466 Checks that we have the combination of an ExtensionArraydtype and 

1467 a dtype that should be converted to int64 

1468 

1469 Returns 

1470 ------- 

1471 bool 

1472 

1473 Related to issue #37609 

1474 """ 

1475 return isinstance(left_dtype, ExtensionDtype) and needs_i8_conversion(right_dtype) 

1476 

1477 

1478def assert_indexing_slices_equivalent(ser: Series, l_slc: slice, i_slc: slice) -> None: 

1479 """ 

1480 Check that ser.iloc[i_slc] matches ser.loc[l_slc] and, if applicable, 

1481 ser[l_slc]. 

1482 """ 

1483 expected = ser.iloc[i_slc] 

1484 

1485 assert_series_equal(ser.loc[l_slc], expected) 

1486 

1487 if not is_integer_dtype(ser.index): 

1488 # For integer indices, .loc and plain getitem are position-based. 

1489 assert_series_equal(ser[l_slc], expected) 

1490 

1491 

1492def assert_metadata_equivalent( 

1493 left: DataFrame | Series, right: DataFrame | Series | None = None 

1494) -> None: 

1495 """ 

1496 Check that ._metadata attributes are equivalent. 

1497 """ 

1498 for attr in left._metadata: 

1499 val = getattr(left, attr, None) 

1500 if right is None: 

1501 assert val is None 

1502 else: 

1503 assert val == getattr(right, attr, None)