asserters.py 47 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432
  1. from __future__ import annotations
  2. from typing import cast
  3. import warnings
  4. import numpy as np
  5. from pandas._libs.lib import (
  6. NoDefault,
  7. no_default,
  8. )
  9. from pandas._libs.missing import is_matching_na
  10. import pandas._libs.testing as _testing
  11. from pandas.core.dtypes.common import (
  12. is_bool,
  13. is_categorical_dtype,
  14. is_extension_array_dtype,
  15. is_interval_dtype,
  16. is_number,
  17. is_numeric_dtype,
  18. needs_i8_conversion,
  19. )
  20. from pandas.core.dtypes.dtypes import PandasDtype
  21. from pandas.core.dtypes.missing import array_equivalent
  22. import pandas as pd
  23. from pandas import (
  24. Categorical,
  25. DataFrame,
  26. DatetimeIndex,
  27. Index,
  28. IntervalIndex,
  29. MultiIndex,
  30. PeriodIndex,
  31. Series,
  32. TimedeltaIndex,
  33. )
  34. from pandas.core.algorithms import (
  35. safe_sort,
  36. take_nd,
  37. )
  38. from pandas.core.arrays import (
  39. DatetimeArray,
  40. ExtensionArray,
  41. IntervalArray,
  42. PeriodArray,
  43. TimedeltaArray,
  44. )
  45. from pandas.core.arrays.datetimelike import DatetimeLikeArrayMixin
  46. from pandas.core.arrays.string_ import StringDtype
  47. from pandas.io.formats.printing import pprint_thing
  48. def assert_almost_equal(
  49. left,
  50. right,
  51. check_dtype: bool | str = "equiv",
  52. check_less_precise: bool | int | NoDefault = no_default,
  53. rtol: float = 1.0e-5,
  54. atol: float = 1.0e-8,
  55. **kwargs,
  56. ):
  57. """
  58. Check that the left and right objects are approximately equal.
  59. By approximately equal, we refer to objects that are numbers or that
  60. contain numbers which may be equivalent to specific levels of precision.
  61. Parameters
  62. ----------
  63. left : object
  64. right : object
  65. check_dtype : bool or {'equiv'}, default 'equiv'
  66. Check dtype if both a and b are the same type. If 'equiv' is passed in,
  67. then `RangeIndex` and `Int64Index` are also considered equivalent
  68. when doing type checking.
  69. check_less_precise : bool or int, default False
  70. Specify comparison precision. 5 digits (False) or 3 digits (True)
  71. after decimal points are compared. If int, then specify the number
  72. of digits to compare.
  73. When comparing two numbers, if the first number has magnitude less
  74. than 1e-5, we compare the two numbers directly and check whether
  75. they are equivalent within the specified precision. Otherwise, we
  76. compare the **ratio** of the second number to the first number and
  77. check whether it is equivalent to 1 within the specified precision.
  78. .. deprecated:: 1.1.0
  79. Use `rtol` and `atol` instead to define relative/absolute
  80. tolerance, respectively. Similar to :func:`math.isclose`.
  81. rtol : float, default 1e-5
  82. Relative tolerance.
  83. .. versionadded:: 1.1.0
  84. atol : float, default 1e-8
  85. Absolute tolerance.
  86. .. versionadded:: 1.1.0
  87. """
  88. if check_less_precise is not no_default:
  89. warnings.warn(
  90. "The 'check_less_precise' keyword in testing.assert_*_equal "
  91. "is deprecated and will be removed in a future version. "
  92. "You can stop passing 'check_less_precise' to silence this warning.",
  93. FutureWarning,
  94. stacklevel=2,
  95. )
  96. # error: Argument 1 to "_get_tol_from_less_precise" has incompatible
  97. # type "Union[bool, int, NoDefault]"; expected "Union[bool, int]"
  98. rtol = atol = _get_tol_from_less_precise(
  99. check_less_precise # type: ignore[arg-type]
  100. )
  101. if isinstance(left, Index):
  102. assert_index_equal(
  103. left,
  104. right,
  105. check_exact=False,
  106. exact=check_dtype,
  107. rtol=rtol,
  108. atol=atol,
  109. **kwargs,
  110. )
  111. elif isinstance(left, Series):
  112. assert_series_equal(
  113. left,
  114. right,
  115. check_exact=False,
  116. check_dtype=check_dtype,
  117. rtol=rtol,
  118. atol=atol,
  119. **kwargs,
  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. else:
  132. # Other sequences.
  133. if check_dtype:
  134. if is_number(left) and is_number(right):
  135. # Do not compare numeric classes, like np.float64 and float.
  136. pass
  137. elif is_bool(left) and is_bool(right):
  138. # Do not compare bool classes, like np.bool_ and bool.
  139. pass
  140. else:
  141. if isinstance(left, np.ndarray) or isinstance(right, np.ndarray):
  142. obj = "numpy array"
  143. else:
  144. obj = "Input"
  145. assert_class_equal(left, right, obj=obj)
  146. # if we have "equiv", this becomes True
  147. check_dtype = bool(check_dtype)
  148. _testing.assert_almost_equal(
  149. left, right, check_dtype=check_dtype, rtol=rtol, atol=atol, **kwargs
  150. )
  151. def _get_tol_from_less_precise(check_less_precise: bool | int) -> float:
  152. """
  153. Return the tolerance equivalent to the deprecated `check_less_precise`
  154. parameter.
  155. Parameters
  156. ----------
  157. check_less_precise : bool or int
  158. Returns
  159. -------
  160. float
  161. Tolerance to be used as relative/absolute tolerance.
  162. Examples
  163. --------
  164. >>> # Using check_less_precise as a bool:
  165. >>> _get_tol_from_less_precise(False)
  166. 0.5e-5
  167. >>> _get_tol_from_less_precise(True)
  168. 0.5e-3
  169. >>> # Using check_less_precise as an int representing the decimal
  170. >>> # tolerance intended:
  171. >>> _get_tol_from_less_precise(2)
  172. 0.5e-2
  173. >>> _get_tol_from_less_precise(8)
  174. 0.5e-8
  175. """
  176. if isinstance(check_less_precise, bool):
  177. if check_less_precise:
  178. # 3-digit tolerance
  179. return 0.5e-3
  180. else:
  181. # 5-digit tolerance
  182. return 0.5e-5
  183. else:
  184. # Equivalent to setting checking_less_precise=<decimals>
  185. return 0.5 * 10 ** -check_less_precise
  186. def _check_isinstance(left, right, cls):
  187. """
  188. Helper method for our assert_* methods that ensures that
  189. the two objects being compared have the right type before
  190. proceeding with the comparison.
  191. Parameters
  192. ----------
  193. left : The first object being compared.
  194. right : The second object being compared.
  195. cls : The class type to check against.
  196. Raises
  197. ------
  198. AssertionError : Either `left` or `right` is not an instance of `cls`.
  199. """
  200. cls_name = cls.__name__
  201. if not isinstance(left, cls):
  202. raise AssertionError(
  203. f"{cls_name} Expected type {cls}, found {type(left)} instead"
  204. )
  205. if not isinstance(right, cls):
  206. raise AssertionError(
  207. f"{cls_name} Expected type {cls}, found {type(right)} instead"
  208. )
  209. def assert_dict_equal(left, right, compare_keys: bool = True):
  210. _check_isinstance(left, right, dict)
  211. _testing.assert_dict_equal(left, right, compare_keys=compare_keys)
  212. def assert_index_equal(
  213. left: Index,
  214. right: Index,
  215. exact: bool | str = "equiv",
  216. check_names: bool = True,
  217. check_less_precise: bool | int | NoDefault = no_default,
  218. check_exact: bool = True,
  219. check_categorical: bool = True,
  220. check_order: bool = True,
  221. rtol: float = 1.0e-5,
  222. atol: float = 1.0e-8,
  223. obj: str = "Index",
  224. ) -> None:
  225. """
  226. Check that left and right Index are equal.
  227. Parameters
  228. ----------
  229. left : Index
  230. right : Index
  231. exact : bool or {'equiv'}, default 'equiv'
  232. Whether to check the Index class, dtype and inferred_type
  233. are identical. If 'equiv', then RangeIndex can be substituted for
  234. Int64Index as well.
  235. check_names : bool, default True
  236. Whether to check the names attribute.
  237. check_less_precise : bool or int, default False
  238. Specify comparison precision. Only used when check_exact is False.
  239. 5 digits (False) or 3 digits (True) after decimal points are compared.
  240. If int, then specify the digits to compare.
  241. .. deprecated:: 1.1.0
  242. Use `rtol` and `atol` instead to define relative/absolute
  243. tolerance, respectively. Similar to :func:`math.isclose`.
  244. check_exact : bool, default True
  245. Whether to compare number exactly.
  246. check_categorical : bool, default True
  247. Whether to compare internal Categorical exactly.
  248. check_order : bool, default True
  249. Whether to compare the order of index entries as well as their values.
  250. If True, both indexes must contain the same elements, in the same order.
  251. If False, both indexes must contain the same elements, but in any order.
  252. .. versionadded:: 1.2.0
  253. rtol : float, default 1e-5
  254. Relative tolerance. Only used when check_exact is False.
  255. .. versionadded:: 1.1.0
  256. atol : float, default 1e-8
  257. Absolute tolerance. Only used when check_exact is False.
  258. .. versionadded:: 1.1.0
  259. obj : str, default 'Index'
  260. Specify object name being compared, internally used to show appropriate
  261. assertion message.
  262. Examples
  263. --------
  264. >>> from pandas.testing import assert_index_equal
  265. >>> a = pd.Index([1, 2, 3])
  266. >>> b = pd.Index([1, 2, 3])
  267. >>> assert_index_equal(a, b)
  268. """
  269. __tracebackhide__ = True
  270. def _check_types(left, right, obj="Index") -> None:
  271. if not exact:
  272. return
  273. assert_class_equal(left, right, exact=exact, obj=obj)
  274. # Skip exact dtype checking when `check_categorical` is False
  275. if check_categorical:
  276. assert_attr_equal("dtype", left, right, obj=obj)
  277. if is_categorical_dtype(left.dtype) and is_categorical_dtype(right.dtype):
  278. assert_index_equal(left.categories, right.categories, exact=exact)
  279. # allow string-like to have different inferred_types
  280. if left.inferred_type in ("string"):
  281. assert right.inferred_type in ("string")
  282. else:
  283. assert_attr_equal("inferred_type", left, right, obj=obj)
  284. def _get_ilevel_values(index, level):
  285. # accept level number only
  286. unique = index.levels[level]
  287. level_codes = index.codes[level]
  288. filled = take_nd(unique._values, level_codes, fill_value=unique._na_value)
  289. return unique._shallow_copy(filled, name=index.names[level])
  290. if check_less_precise is not no_default:
  291. warnings.warn(
  292. "The 'check_less_precise' keyword in testing.assert_*_equal "
  293. "is deprecated and will be removed in a future version. "
  294. "You can stop passing 'check_less_precise' to silence this warning.",
  295. FutureWarning,
  296. stacklevel=2,
  297. )
  298. # error: Argument 1 to "_get_tol_from_less_precise" has incompatible
  299. # type "Union[bool, int, NoDefault]"; expected "Union[bool, int]"
  300. rtol = atol = _get_tol_from_less_precise(
  301. check_less_precise # type: ignore[arg-type]
  302. )
  303. # instance validation
  304. _check_isinstance(left, right, Index)
  305. # class / dtype comparison
  306. _check_types(left, right, obj=obj)
  307. # level comparison
  308. if left.nlevels != right.nlevels:
  309. msg1 = f"{obj} levels are different"
  310. msg2 = f"{left.nlevels}, {left}"
  311. msg3 = f"{right.nlevels}, {right}"
  312. raise_assert_detail(obj, msg1, msg2, msg3)
  313. # length comparison
  314. if len(left) != len(right):
  315. msg1 = f"{obj} length are different"
  316. msg2 = f"{len(left)}, {left}"
  317. msg3 = f"{len(right)}, {right}"
  318. raise_assert_detail(obj, msg1, msg2, msg3)
  319. # If order doesn't matter then sort the index entries
  320. if not check_order:
  321. left = Index(safe_sort(left))
  322. right = Index(safe_sort(right))
  323. # MultiIndex special comparison for little-friendly error messages
  324. if left.nlevels > 1:
  325. left = cast(MultiIndex, left)
  326. right = cast(MultiIndex, right)
  327. for level in range(left.nlevels):
  328. # cannot use get_level_values here because it can change dtype
  329. llevel = _get_ilevel_values(left, level)
  330. rlevel = _get_ilevel_values(right, level)
  331. lobj = f"MultiIndex level [{level}]"
  332. assert_index_equal(
  333. llevel,
  334. rlevel,
  335. exact=exact,
  336. check_names=check_names,
  337. check_exact=check_exact,
  338. rtol=rtol,
  339. atol=atol,
  340. obj=lobj,
  341. )
  342. # get_level_values may change dtype
  343. _check_types(left.levels[level], right.levels[level], obj=obj)
  344. # skip exact index checking when `check_categorical` is False
  345. if check_exact and check_categorical:
  346. if not left.equals(right):
  347. diff = (
  348. np.sum((left._values != right._values).astype(int)) * 100.0 / len(left)
  349. )
  350. msg = f"{obj} values are different ({np.round(diff, 5)} %)"
  351. raise_assert_detail(obj, msg, left, right)
  352. else:
  353. # if we have "equiv", this becomes True
  354. exact_bool = bool(exact)
  355. _testing.assert_almost_equal(
  356. left.values,
  357. right.values,
  358. rtol=rtol,
  359. atol=atol,
  360. check_dtype=exact_bool,
  361. obj=obj,
  362. lobj=left,
  363. robj=right,
  364. )
  365. # metadata comparison
  366. if check_names:
  367. assert_attr_equal("names", left, right, obj=obj)
  368. if isinstance(left, PeriodIndex) or isinstance(right, PeriodIndex):
  369. assert_attr_equal("freq", left, right, obj=obj)
  370. if isinstance(left, IntervalIndex) or isinstance(right, IntervalIndex):
  371. assert_interval_array_equal(left._values, right._values)
  372. if check_categorical:
  373. if is_categorical_dtype(left.dtype) or is_categorical_dtype(right.dtype):
  374. assert_categorical_equal(left._values, right._values, obj=f"{obj} category")
  375. def assert_class_equal(left, right, exact: bool | str = True, obj="Input"):
  376. """
  377. Checks classes are equal.
  378. """
  379. __tracebackhide__ = True
  380. def repr_class(x):
  381. if isinstance(x, Index):
  382. # return Index as it is to include values in the error message
  383. return x
  384. return type(x).__name__
  385. if exact == "equiv":
  386. if type(left) != type(right):
  387. # allow equivalence of Int64Index/RangeIndex
  388. types = {type(left).__name__, type(right).__name__}
  389. if len(types - {"Int64Index", "RangeIndex"}):
  390. msg = f"{obj} classes are not equivalent"
  391. raise_assert_detail(obj, msg, repr_class(left), repr_class(right))
  392. elif exact:
  393. if type(left) != type(right):
  394. msg = f"{obj} classes are different"
  395. raise_assert_detail(obj, msg, repr_class(left), repr_class(right))
  396. def assert_attr_equal(attr: str, left, right, obj: str = "Attributes"):
  397. """
  398. Check attributes are equal. Both objects must have attribute.
  399. Parameters
  400. ----------
  401. attr : str
  402. Attribute name being compared.
  403. left : object
  404. right : object
  405. obj : str, default 'Attributes'
  406. Specify object name being compared, internally used to show appropriate
  407. assertion message
  408. """
  409. __tracebackhide__ = True
  410. left_attr = getattr(left, attr)
  411. right_attr = getattr(right, attr)
  412. if left_attr is right_attr:
  413. return True
  414. elif is_matching_na(left_attr, right_attr):
  415. # e.g. both np.nan, both NaT, both pd.NA, ...
  416. return True
  417. try:
  418. result = left_attr == right_attr
  419. except TypeError:
  420. # datetimetz on rhs may raise TypeError
  421. result = False
  422. if (left_attr is pd.NA) ^ (right_attr is pd.NA):
  423. result = False
  424. elif not isinstance(result, bool):
  425. result = result.all()
  426. if result:
  427. return True
  428. else:
  429. msg = f'Attribute "{attr}" are different'
  430. raise_assert_detail(obj, msg, left_attr, right_attr)
  431. def assert_is_valid_plot_return_object(objs):
  432. import matplotlib.pyplot as plt
  433. if isinstance(objs, (Series, np.ndarray)):
  434. for el in objs.ravel():
  435. msg = (
  436. "one of 'objs' is not a matplotlib Axes instance, "
  437. f"type encountered {repr(type(el).__name__)}"
  438. )
  439. assert isinstance(el, (plt.Axes, dict)), msg
  440. else:
  441. msg = (
  442. "objs is neither an ndarray of Artist instances nor a single "
  443. "ArtistArtist instance, tuple, or dict, 'objs' is a "
  444. f"{repr(type(objs).__name__)}"
  445. )
  446. assert isinstance(objs, (plt.Artist, tuple, dict)), msg
  447. def assert_is_sorted(seq):
  448. """Assert that the sequence is sorted."""
  449. if isinstance(seq, (Index, Series)):
  450. seq = seq.values
  451. # sorting does not change precisions
  452. assert_numpy_array_equal(seq, np.sort(np.array(seq)))
  453. def assert_categorical_equal(
  454. left, right, check_dtype=True, check_category_order=True, obj="Categorical"
  455. ):
  456. """
  457. Test that Categoricals are equivalent.
  458. Parameters
  459. ----------
  460. left : Categorical
  461. right : Categorical
  462. check_dtype : bool, default True
  463. Check that integer dtype of the codes are the same
  464. check_category_order : bool, default True
  465. Whether the order of the categories should be compared, which
  466. implies identical integer codes. If False, only the resulting
  467. values are compared. The ordered attribute is
  468. checked regardless.
  469. obj : str, default 'Categorical'
  470. Specify object name being compared, internally used to show appropriate
  471. assertion message
  472. """
  473. _check_isinstance(left, right, Categorical)
  474. if check_category_order:
  475. assert_index_equal(left.categories, right.categories, obj=f"{obj}.categories")
  476. assert_numpy_array_equal(
  477. left.codes, right.codes, check_dtype=check_dtype, obj=f"{obj}.codes"
  478. )
  479. else:
  480. try:
  481. lc = left.categories.sort_values()
  482. rc = right.categories.sort_values()
  483. except TypeError:
  484. # e.g. '<' not supported between instances of 'int' and 'str'
  485. lc, rc = left.categories, right.categories
  486. assert_index_equal(lc, rc, obj=f"{obj}.categories")
  487. assert_index_equal(
  488. left.categories.take(left.codes),
  489. right.categories.take(right.codes),
  490. obj=f"{obj}.values",
  491. )
  492. assert_attr_equal("ordered", left, right, obj=obj)
  493. def assert_interval_array_equal(left, right, exact="equiv", obj="IntervalArray"):
  494. """
  495. Test that two IntervalArrays are equivalent.
  496. Parameters
  497. ----------
  498. left, right : IntervalArray
  499. The IntervalArrays to compare.
  500. exact : bool or {'equiv'}, default 'equiv'
  501. Whether to check the Index class, dtype and inferred_type
  502. are identical. If 'equiv', then RangeIndex can be substituted for
  503. Int64Index as well.
  504. obj : str, default 'IntervalArray'
  505. Specify object name being compared, internally used to show appropriate
  506. assertion message
  507. """
  508. _check_isinstance(left, right, IntervalArray)
  509. kwargs = {}
  510. if left._left.dtype.kind in ["m", "M"]:
  511. # We have a DatetimeArray or TimedeltaArray
  512. kwargs["check_freq"] = False
  513. assert_equal(left._left, right._left, obj=f"{obj}.left", **kwargs)
  514. assert_equal(left._right, right._right, obj=f"{obj}.left", **kwargs)
  515. assert_attr_equal("closed", left, right, obj=obj)
  516. def assert_period_array_equal(left, right, obj="PeriodArray"):
  517. _check_isinstance(left, right, PeriodArray)
  518. assert_numpy_array_equal(left._data, right._data, obj=f"{obj}._data")
  519. assert_attr_equal("freq", left, right, obj=obj)
  520. def assert_datetime_array_equal(left, right, obj="DatetimeArray", check_freq=True):
  521. __tracebackhide__ = True
  522. _check_isinstance(left, right, DatetimeArray)
  523. assert_numpy_array_equal(left._data, right._data, obj=f"{obj}._data")
  524. if check_freq:
  525. assert_attr_equal("freq", left, right, obj=obj)
  526. assert_attr_equal("tz", left, right, obj=obj)
  527. def assert_timedelta_array_equal(left, right, obj="TimedeltaArray", check_freq=True):
  528. __tracebackhide__ = True
  529. _check_isinstance(left, right, TimedeltaArray)
  530. assert_numpy_array_equal(left._data, right._data, obj=f"{obj}._data")
  531. if check_freq:
  532. assert_attr_equal("freq", left, right, obj=obj)
  533. def raise_assert_detail(obj, message, left, right, diff=None, index_values=None):
  534. __tracebackhide__ = True
  535. msg = f"""{obj} are different
  536. {message}"""
  537. if isinstance(index_values, np.ndarray):
  538. msg += f"\n[index]: {pprint_thing(index_values)}"
  539. if isinstance(left, np.ndarray):
  540. left = pprint_thing(left)
  541. elif (
  542. is_categorical_dtype(left)
  543. or isinstance(left, PandasDtype)
  544. or isinstance(left, StringDtype)
  545. ):
  546. left = repr(left)
  547. if isinstance(right, np.ndarray):
  548. right = pprint_thing(right)
  549. elif (
  550. is_categorical_dtype(right)
  551. or isinstance(right, PandasDtype)
  552. or isinstance(right, StringDtype)
  553. ):
  554. right = repr(right)
  555. msg += f"""
  556. [left]: {left}
  557. [right]: {right}"""
  558. if diff is not None:
  559. msg += f"\n[diff]: {diff}"
  560. raise AssertionError(msg)
  561. def assert_numpy_array_equal(
  562. left,
  563. right,
  564. strict_nan=False,
  565. check_dtype=True,
  566. err_msg=None,
  567. check_same=None,
  568. obj="numpy array",
  569. index_values=None,
  570. ):
  571. """
  572. Check that 'np.ndarray' is equivalent.
  573. Parameters
  574. ----------
  575. left, right : numpy.ndarray or iterable
  576. The two arrays to be compared.
  577. strict_nan : bool, default False
  578. If True, consider NaN and None to be different.
  579. check_dtype : bool, default True
  580. Check dtype if both a and b are np.ndarray.
  581. err_msg : str, default None
  582. If provided, used as assertion message.
  583. check_same : None|'copy'|'same', default None
  584. Ensure left and right refer/do not refer to the same memory area.
  585. obj : str, default 'numpy array'
  586. Specify object name being compared, internally used to show appropriate
  587. assertion message.
  588. index_values : numpy.ndarray, default None
  589. optional index (shared by both left and right), used in output.
  590. """
  591. __tracebackhide__ = True
  592. # instance validation
  593. # Show a detailed error message when classes are different
  594. assert_class_equal(left, right, obj=obj)
  595. # both classes must be an np.ndarray
  596. _check_isinstance(left, right, np.ndarray)
  597. def _get_base(obj):
  598. return obj.base if getattr(obj, "base", None) is not None else obj
  599. left_base = _get_base(left)
  600. right_base = _get_base(right)
  601. if check_same == "same":
  602. if left_base is not right_base:
  603. raise AssertionError(f"{repr(left_base)} is not {repr(right_base)}")
  604. elif check_same == "copy":
  605. if left_base is right_base:
  606. raise AssertionError(f"{repr(left_base)} is {repr(right_base)}")
  607. def _raise(left, right, err_msg):
  608. if err_msg is None:
  609. if left.shape != right.shape:
  610. raise_assert_detail(
  611. obj, f"{obj} shapes are different", left.shape, right.shape
  612. )
  613. diff = 0
  614. for left_arr, right_arr in zip(left, right):
  615. # count up differences
  616. if not array_equivalent(left_arr, right_arr, strict_nan=strict_nan):
  617. diff += 1
  618. diff = diff * 100.0 / left.size
  619. msg = f"{obj} values are different ({np.round(diff, 5)} %)"
  620. raise_assert_detail(obj, msg, left, right, index_values=index_values)
  621. raise AssertionError(err_msg)
  622. # compare shape and values
  623. if not array_equivalent(left, right, strict_nan=strict_nan):
  624. _raise(left, right, err_msg)
  625. if check_dtype:
  626. if isinstance(left, np.ndarray) and isinstance(right, np.ndarray):
  627. assert_attr_equal("dtype", left, right, obj=obj)
  628. def assert_extension_array_equal(
  629. left,
  630. right,
  631. check_dtype=True,
  632. index_values=None,
  633. check_less_precise=no_default,
  634. check_exact=False,
  635. rtol: float = 1.0e-5,
  636. atol: float = 1.0e-8,
  637. ):
  638. """
  639. Check that left and right ExtensionArrays are equal.
  640. Parameters
  641. ----------
  642. left, right : ExtensionArray
  643. The two arrays to compare.
  644. check_dtype : bool, default True
  645. Whether to check if the ExtensionArray dtypes are identical.
  646. index_values : numpy.ndarray, default None
  647. Optional index (shared by both left and right), used in output.
  648. check_less_precise : bool or int, default False
  649. Specify comparison precision. Only used when check_exact is False.
  650. 5 digits (False) or 3 digits (True) after decimal points are compared.
  651. If int, then specify the digits to compare.
  652. .. deprecated:: 1.1.0
  653. Use `rtol` and `atol` instead to define relative/absolute
  654. tolerance, respectively. Similar to :func:`math.isclose`.
  655. check_exact : bool, default False
  656. Whether to compare number exactly.
  657. rtol : float, default 1e-5
  658. Relative tolerance. Only used when check_exact is False.
  659. .. versionadded:: 1.1.0
  660. atol : float, default 1e-8
  661. Absolute tolerance. Only used when check_exact is False.
  662. .. versionadded:: 1.1.0
  663. Notes
  664. -----
  665. Missing values are checked separately from valid values.
  666. A mask of missing values is computed for each and checked to match.
  667. The remaining all-valid values are cast to object dtype and checked.
  668. Examples
  669. --------
  670. >>> from pandas.testing import assert_extension_array_equal
  671. >>> a = pd.Series([1, 2, 3, 4])
  672. >>> b, c = a.array, a.array
  673. >>> assert_extension_array_equal(b, c)
  674. """
  675. if check_less_precise is not no_default:
  676. warnings.warn(
  677. "The 'check_less_precise' keyword in testing.assert_*_equal "
  678. "is deprecated and will be removed in a future version. "
  679. "You can stop passing 'check_less_precise' to silence this warning.",
  680. FutureWarning,
  681. stacklevel=2,
  682. )
  683. rtol = atol = _get_tol_from_less_precise(check_less_precise)
  684. assert isinstance(left, ExtensionArray), "left is not an ExtensionArray"
  685. assert isinstance(right, ExtensionArray), "right is not an ExtensionArray"
  686. if check_dtype:
  687. assert_attr_equal("dtype", left, right, obj="ExtensionArray")
  688. if (
  689. isinstance(left, DatetimeLikeArrayMixin)
  690. and isinstance(right, DatetimeLikeArrayMixin)
  691. and type(right) == type(left)
  692. ):
  693. # Avoid slow object-dtype comparisons
  694. # np.asarray for case where we have a np.MaskedArray
  695. assert_numpy_array_equal(
  696. np.asarray(left.asi8), np.asarray(right.asi8), index_values=index_values
  697. )
  698. return
  699. left_na = np.asarray(left.isna())
  700. right_na = np.asarray(right.isna())
  701. assert_numpy_array_equal(
  702. left_na, right_na, obj="ExtensionArray NA mask", index_values=index_values
  703. )
  704. left_valid = np.asarray(left[~left_na].astype(object))
  705. right_valid = np.asarray(right[~right_na].astype(object))
  706. if check_exact:
  707. assert_numpy_array_equal(
  708. left_valid, right_valid, obj="ExtensionArray", index_values=index_values
  709. )
  710. else:
  711. _testing.assert_almost_equal(
  712. left_valid,
  713. right_valid,
  714. check_dtype=check_dtype,
  715. rtol=rtol,
  716. atol=atol,
  717. obj="ExtensionArray",
  718. index_values=index_values,
  719. )
  720. # This could be refactored to use the NDFrame.equals method
  721. def assert_series_equal(
  722. left,
  723. right,
  724. check_dtype=True,
  725. check_index_type="equiv",
  726. check_series_type=True,
  727. check_less_precise=no_default,
  728. check_names=True,
  729. check_exact=False,
  730. check_datetimelike_compat=False,
  731. check_categorical=True,
  732. check_category_order=True,
  733. check_freq=True,
  734. check_flags=True,
  735. rtol=1.0e-5,
  736. atol=1.0e-8,
  737. obj="Series",
  738. *,
  739. check_index=True,
  740. ):
  741. """
  742. Check that left and right Series are equal.
  743. Parameters
  744. ----------
  745. left : Series
  746. right : Series
  747. check_dtype : bool, default True
  748. Whether to check the Series dtype is identical.
  749. check_index_type : bool or {'equiv'}, default 'equiv'
  750. Whether to check the Index class, dtype and inferred_type
  751. are identical.
  752. check_series_type : bool, default True
  753. Whether to check the Series class is identical.
  754. check_less_precise : bool or int, default False
  755. Specify comparison precision. Only used when check_exact is False.
  756. 5 digits (False) or 3 digits (True) after decimal points are compared.
  757. If int, then specify the digits to compare.
  758. When comparing two numbers, if the first number has magnitude less
  759. than 1e-5, we compare the two numbers directly and check whether
  760. they are equivalent within the specified precision. Otherwise, we
  761. compare the **ratio** of the second number to the first number and
  762. check whether it is equivalent to 1 within the specified precision.
  763. .. deprecated:: 1.1.0
  764. Use `rtol` and `atol` instead to define relative/absolute
  765. tolerance, respectively. Similar to :func:`math.isclose`.
  766. check_names : bool, default True
  767. Whether to check the Series and Index names attribute.
  768. check_exact : bool, default False
  769. Whether to compare number exactly.
  770. check_datetimelike_compat : bool, default False
  771. Compare datetime-like which is comparable ignoring dtype.
  772. check_categorical : bool, default True
  773. Whether to compare internal Categorical exactly.
  774. check_category_order : bool, default True
  775. Whether to compare category order of internal Categoricals.
  776. .. versionadded:: 1.0.2
  777. check_freq : bool, default True
  778. Whether to check the `freq` attribute on a DatetimeIndex or TimedeltaIndex.
  779. .. versionadded:: 1.1.0
  780. check_flags : bool, default True
  781. Whether to check the `flags` attribute.
  782. .. versionadded:: 1.2.0
  783. rtol : float, default 1e-5
  784. Relative tolerance. Only used when check_exact is False.
  785. .. versionadded:: 1.1.0
  786. atol : float, default 1e-8
  787. Absolute tolerance. Only used when check_exact is False.
  788. .. versionadded:: 1.1.0
  789. obj : str, default 'Series'
  790. Specify object name being compared, internally used to show appropriate
  791. assertion message.
  792. check_index : bool, default True
  793. Whether to check index equivalence. If False, then compare only values.
  794. .. versionadded:: 1.3.0
  795. Examples
  796. --------
  797. >>> from pandas.testing import assert_series_equal
  798. >>> a = pd.Series([1, 2, 3, 4])
  799. >>> b = pd.Series([1, 2, 3, 4])
  800. >>> assert_series_equal(a, b)
  801. """
  802. __tracebackhide__ = True
  803. if check_less_precise is not no_default:
  804. warnings.warn(
  805. "The 'check_less_precise' keyword in testing.assert_*_equal "
  806. "is deprecated and will be removed in a future version. "
  807. "You can stop passing 'check_less_precise' to silence this warning.",
  808. FutureWarning,
  809. stacklevel=2,
  810. )
  811. rtol = atol = _get_tol_from_less_precise(check_less_precise)
  812. # instance validation
  813. _check_isinstance(left, right, Series)
  814. if check_series_type:
  815. assert_class_equal(left, right, obj=obj)
  816. # length comparison
  817. if len(left) != len(right):
  818. msg1 = f"{len(left)}, {left.index}"
  819. msg2 = f"{len(right)}, {right.index}"
  820. raise_assert_detail(obj, "Series length are different", msg1, msg2)
  821. if check_flags:
  822. assert left.flags == right.flags, f"{repr(left.flags)} != {repr(right.flags)}"
  823. if check_index:
  824. # GH #38183
  825. assert_index_equal(
  826. left.index,
  827. right.index,
  828. exact=check_index_type,
  829. check_names=check_names,
  830. check_exact=check_exact,
  831. check_categorical=check_categorical,
  832. rtol=rtol,
  833. atol=atol,
  834. obj=f"{obj}.index",
  835. )
  836. if check_freq and isinstance(left.index, (DatetimeIndex, TimedeltaIndex)):
  837. lidx = left.index
  838. ridx = right.index
  839. assert lidx.freq == ridx.freq, (lidx.freq, ridx.freq)
  840. if check_dtype:
  841. # We want to skip exact dtype checking when `check_categorical`
  842. # is False. We'll still raise if only one is a `Categorical`,
  843. # regardless of `check_categorical`
  844. if (
  845. is_categorical_dtype(left.dtype)
  846. and is_categorical_dtype(right.dtype)
  847. and not check_categorical
  848. ):
  849. pass
  850. else:
  851. assert_attr_equal("dtype", left, right, obj=f"Attributes of {obj}")
  852. if check_exact and is_numeric_dtype(left.dtype) and is_numeric_dtype(right.dtype):
  853. left_values = left._values
  854. right_values = right._values
  855. # Only check exact if dtype is numeric
  856. if isinstance(left_values, ExtensionArray) and isinstance(
  857. right_values, ExtensionArray
  858. ):
  859. assert_extension_array_equal(
  860. left_values,
  861. right_values,
  862. check_dtype=check_dtype,
  863. index_values=np.asarray(left.index),
  864. )
  865. else:
  866. assert_numpy_array_equal(
  867. left_values,
  868. right_values,
  869. check_dtype=check_dtype,
  870. obj=str(obj),
  871. index_values=np.asarray(left.index),
  872. )
  873. elif check_datetimelike_compat and (
  874. needs_i8_conversion(left.dtype) or needs_i8_conversion(right.dtype)
  875. ):
  876. # we want to check only if we have compat dtypes
  877. # e.g. integer and M|m are NOT compat, but we can simply check
  878. # the values in that case
  879. # datetimelike may have different objects (e.g. datetime.datetime
  880. # vs Timestamp) but will compare equal
  881. if not Index(left._values).equals(Index(right._values)):
  882. msg = (
  883. f"[datetimelike_compat=True] {left._values} "
  884. f"is not equal to {right._values}."
  885. )
  886. raise AssertionError(msg)
  887. elif is_interval_dtype(left.dtype) and is_interval_dtype(right.dtype):
  888. assert_interval_array_equal(left.array, right.array)
  889. elif is_categorical_dtype(left.dtype) or is_categorical_dtype(right.dtype):
  890. _testing.assert_almost_equal(
  891. left._values,
  892. right._values,
  893. rtol=rtol,
  894. atol=atol,
  895. check_dtype=check_dtype,
  896. obj=str(obj),
  897. index_values=np.asarray(left.index),
  898. )
  899. elif is_extension_array_dtype(left.dtype) and is_extension_array_dtype(right.dtype):
  900. assert_extension_array_equal(
  901. left._values,
  902. right._values,
  903. check_dtype=check_dtype,
  904. index_values=np.asarray(left.index),
  905. )
  906. elif is_extension_array_dtype_and_needs_i8_conversion(
  907. left.dtype, right.dtype
  908. ) or is_extension_array_dtype_and_needs_i8_conversion(right.dtype, left.dtype):
  909. assert_extension_array_equal(
  910. left._values,
  911. right._values,
  912. check_dtype=check_dtype,
  913. index_values=np.asarray(left.index),
  914. )
  915. elif needs_i8_conversion(left.dtype) and needs_i8_conversion(right.dtype):
  916. # DatetimeArray or TimedeltaArray
  917. assert_extension_array_equal(
  918. left._values,
  919. right._values,
  920. check_dtype=check_dtype,
  921. index_values=np.asarray(left.index),
  922. )
  923. else:
  924. _testing.assert_almost_equal(
  925. left._values,
  926. right._values,
  927. rtol=rtol,
  928. atol=atol,
  929. check_dtype=check_dtype,
  930. obj=str(obj),
  931. index_values=np.asarray(left.index),
  932. )
  933. # metadata comparison
  934. if check_names:
  935. assert_attr_equal("name", left, right, obj=obj)
  936. if check_categorical:
  937. if is_categorical_dtype(left.dtype) or is_categorical_dtype(right.dtype):
  938. assert_categorical_equal(
  939. left._values,
  940. right._values,
  941. obj=f"{obj} category",
  942. check_category_order=check_category_order,
  943. )
  944. # This could be refactored to use the NDFrame.equals method
  945. def assert_frame_equal(
  946. left,
  947. right,
  948. check_dtype=True,
  949. check_index_type="equiv",
  950. check_column_type="equiv",
  951. check_frame_type=True,
  952. check_less_precise=no_default,
  953. check_names=True,
  954. by_blocks=False,
  955. check_exact=False,
  956. check_datetimelike_compat=False,
  957. check_categorical=True,
  958. check_like=False,
  959. check_freq=True,
  960. check_flags=True,
  961. rtol=1.0e-5,
  962. atol=1.0e-8,
  963. obj="DataFrame",
  964. ):
  965. """
  966. Check that left and right DataFrame are equal.
  967. This function is intended to compare two DataFrames and output any
  968. differences. Is is mostly intended for use in unit tests.
  969. Additional parameters allow varying the strictness of the
  970. equality checks performed.
  971. Parameters
  972. ----------
  973. left : DataFrame
  974. First DataFrame to compare.
  975. right : DataFrame
  976. Second DataFrame to compare.
  977. check_dtype : bool, default True
  978. Whether to check the DataFrame dtype is identical.
  979. check_index_type : bool or {'equiv'}, default 'equiv'
  980. Whether to check the Index class, dtype and inferred_type
  981. are identical.
  982. check_column_type : bool or {'equiv'}, default 'equiv'
  983. Whether to check the columns class, dtype and inferred_type
  984. are identical. Is passed as the ``exact`` argument of
  985. :func:`assert_index_equal`.
  986. check_frame_type : bool, default True
  987. Whether to check the DataFrame class is identical.
  988. check_less_precise : bool or int, default False
  989. Specify comparison precision. Only used when check_exact is False.
  990. 5 digits (False) or 3 digits (True) after decimal points are compared.
  991. If int, then specify the digits to compare.
  992. When comparing two numbers, if the first number has magnitude less
  993. than 1e-5, we compare the two numbers directly and check whether
  994. they are equivalent within the specified precision. Otherwise, we
  995. compare the **ratio** of the second number to the first number and
  996. check whether it is equivalent to 1 within the specified precision.
  997. .. deprecated:: 1.1.0
  998. Use `rtol` and `atol` instead to define relative/absolute
  999. tolerance, respectively. Similar to :func:`math.isclose`.
  1000. check_names : bool, default True
  1001. Whether to check that the `names` attribute for both the `index`
  1002. and `column` attributes of the DataFrame is identical.
  1003. by_blocks : bool, default False
  1004. Specify how to compare internal data. If False, compare by columns.
  1005. If True, compare by blocks.
  1006. check_exact : bool, default False
  1007. Whether to compare number exactly.
  1008. check_datetimelike_compat : bool, default False
  1009. Compare datetime-like which is comparable ignoring dtype.
  1010. check_categorical : bool, default True
  1011. Whether to compare internal Categorical exactly.
  1012. check_like : bool, default False
  1013. If True, ignore the order of index & columns.
  1014. Note: index labels must match their respective rows
  1015. (same as in columns) - same labels must be with the same data.
  1016. check_freq : bool, default True
  1017. Whether to check the `freq` attribute on a DatetimeIndex or TimedeltaIndex.
  1018. .. versionadded:: 1.1.0
  1019. check_flags : bool, default True
  1020. Whether to check the `flags` attribute.
  1021. rtol : float, default 1e-5
  1022. Relative tolerance. Only used when check_exact is False.
  1023. .. versionadded:: 1.1.0
  1024. atol : float, default 1e-8
  1025. Absolute tolerance. Only used when check_exact is False.
  1026. .. versionadded:: 1.1.0
  1027. obj : str, default 'DataFrame'
  1028. Specify object name being compared, internally used to show appropriate
  1029. assertion message.
  1030. See Also
  1031. --------
  1032. assert_series_equal : Equivalent method for asserting Series equality.
  1033. DataFrame.equals : Check DataFrame equality.
  1034. Examples
  1035. --------
  1036. This example shows comparing two DataFrames that are equal
  1037. but with columns of differing dtypes.
  1038. >>> from pandas._testing import assert_frame_equal
  1039. >>> df1 = pd.DataFrame({'a': [1, 2], 'b': [3, 4]})
  1040. >>> df2 = pd.DataFrame({'a': [1, 2], 'b': [3.0, 4.0]})
  1041. df1 equals itself.
  1042. >>> assert_frame_equal(df1, df1)
  1043. df1 differs from df2 as column 'b' is of a different type.
  1044. >>> assert_frame_equal(df1, df2)
  1045. Traceback (most recent call last):
  1046. ...
  1047. AssertionError: Attributes of DataFrame.iloc[:, 1] (column name="b") are different
  1048. Attribute "dtype" are different
  1049. [left]: int64
  1050. [right]: float64
  1051. Ignore differing dtypes in columns with check_dtype.
  1052. >>> assert_frame_equal(df1, df2, check_dtype=False)
  1053. """
  1054. __tracebackhide__ = True
  1055. if check_less_precise is not no_default:
  1056. warnings.warn(
  1057. "The 'check_less_precise' keyword in testing.assert_*_equal "
  1058. "is deprecated and will be removed in a future version. "
  1059. "You can stop passing 'check_less_precise' to silence this warning.",
  1060. FutureWarning,
  1061. stacklevel=2,
  1062. )
  1063. rtol = atol = _get_tol_from_less_precise(check_less_precise)
  1064. # instance validation
  1065. _check_isinstance(left, right, DataFrame)
  1066. if check_frame_type:
  1067. assert isinstance(left, type(right))
  1068. # assert_class_equal(left, right, obj=obj)
  1069. # shape comparison
  1070. if left.shape != right.shape:
  1071. raise_assert_detail(
  1072. obj, f"{obj} shape mismatch", f"{repr(left.shape)}", f"{repr(right.shape)}"
  1073. )
  1074. if check_flags:
  1075. assert left.flags == right.flags, f"{repr(left.flags)} != {repr(right.flags)}"
  1076. # index comparison
  1077. assert_index_equal(
  1078. left.index,
  1079. right.index,
  1080. exact=check_index_type,
  1081. check_names=check_names,
  1082. check_exact=check_exact,
  1083. check_categorical=check_categorical,
  1084. check_order=not check_like,
  1085. rtol=rtol,
  1086. atol=atol,
  1087. obj=f"{obj}.index",
  1088. )
  1089. # column comparison
  1090. assert_index_equal(
  1091. left.columns,
  1092. right.columns,
  1093. exact=check_column_type,
  1094. check_names=check_names,
  1095. check_exact=check_exact,
  1096. check_categorical=check_categorical,
  1097. check_order=not check_like,
  1098. rtol=rtol,
  1099. atol=atol,
  1100. obj=f"{obj}.columns",
  1101. )
  1102. if check_like:
  1103. left, right = left.reindex_like(right), right
  1104. # compare by blocks
  1105. if by_blocks:
  1106. rblocks = right._to_dict_of_blocks()
  1107. lblocks = left._to_dict_of_blocks()
  1108. for dtype in list(set(list(lblocks.keys()) + list(rblocks.keys()))):
  1109. assert dtype in lblocks
  1110. assert dtype in rblocks
  1111. assert_frame_equal(
  1112. lblocks[dtype], rblocks[dtype], check_dtype=check_dtype, obj=obj
  1113. )
  1114. # compare by columns
  1115. else:
  1116. for i, col in enumerate(left.columns):
  1117. assert col in right
  1118. lcol = left.iloc[:, i]
  1119. rcol = right.iloc[:, i]
  1120. # GH #38183
  1121. # use check_index=False, because we do not want to run
  1122. # assert_index_equal for each column,
  1123. # as we already checked it for the whole dataframe before.
  1124. assert_series_equal(
  1125. lcol,
  1126. rcol,
  1127. check_dtype=check_dtype,
  1128. check_index_type=check_index_type,
  1129. check_exact=check_exact,
  1130. check_names=check_names,
  1131. check_datetimelike_compat=check_datetimelike_compat,
  1132. check_categorical=check_categorical,
  1133. check_freq=check_freq,
  1134. obj=f'{obj}.iloc[:, {i}] (column name="{col}")',
  1135. rtol=rtol,
  1136. atol=atol,
  1137. check_index=False,
  1138. )
  1139. def assert_equal(left, right, **kwargs):
  1140. """
  1141. Wrapper for tm.assert_*_equal to dispatch to the appropriate test function.
  1142. Parameters
  1143. ----------
  1144. left, right : Index, Series, DataFrame, ExtensionArray, or np.ndarray
  1145. The two items to be compared.
  1146. **kwargs
  1147. All keyword arguments are passed through to the underlying assert method.
  1148. """
  1149. __tracebackhide__ = True
  1150. if isinstance(left, Index):
  1151. assert_index_equal(left, right, **kwargs)
  1152. if isinstance(left, (DatetimeIndex, TimedeltaIndex)):
  1153. assert left.freq == right.freq, (left.freq, right.freq)
  1154. elif isinstance(left, Series):
  1155. assert_series_equal(left, right, **kwargs)
  1156. elif isinstance(left, DataFrame):
  1157. assert_frame_equal(left, right, **kwargs)
  1158. elif isinstance(left, IntervalArray):
  1159. assert_interval_array_equal(left, right, **kwargs)
  1160. elif isinstance(left, PeriodArray):
  1161. assert_period_array_equal(left, right, **kwargs)
  1162. elif isinstance(left, DatetimeArray):
  1163. assert_datetime_array_equal(left, right, **kwargs)
  1164. elif isinstance(left, TimedeltaArray):
  1165. assert_timedelta_array_equal(left, right, **kwargs)
  1166. elif isinstance(left, ExtensionArray):
  1167. assert_extension_array_equal(left, right, **kwargs)
  1168. elif isinstance(left, np.ndarray):
  1169. assert_numpy_array_equal(left, right, **kwargs)
  1170. elif isinstance(left, str):
  1171. assert kwargs == {}
  1172. assert left == right
  1173. else:
  1174. raise NotImplementedError(type(left))
  1175. def assert_sp_array_equal(left, right):
  1176. """
  1177. Check that the left and right SparseArray are equal.
  1178. Parameters
  1179. ----------
  1180. left : SparseArray
  1181. right : SparseArray
  1182. """
  1183. _check_isinstance(left, right, pd.arrays.SparseArray)
  1184. assert_numpy_array_equal(left.sp_values, right.sp_values)
  1185. # SparseIndex comparison
  1186. assert isinstance(left.sp_index, pd._libs.sparse.SparseIndex)
  1187. assert isinstance(right.sp_index, pd._libs.sparse.SparseIndex)
  1188. left_index = left.sp_index
  1189. right_index = right.sp_index
  1190. if not left_index.equals(right_index):
  1191. raise_assert_detail(
  1192. "SparseArray.index", "index are not equal", left_index, right_index
  1193. )
  1194. else:
  1195. # Just ensure a
  1196. pass
  1197. assert_attr_equal("fill_value", left, right)
  1198. assert_attr_equal("dtype", left, right)
  1199. assert_numpy_array_equal(left.to_dense(), right.to_dense())
  1200. def assert_contains_all(iterable, dic):
  1201. for k in iterable:
  1202. assert k in dic, f"Did not contain item: {repr(k)}"
  1203. def assert_copy(iter1, iter2, **eql_kwargs):
  1204. """
  1205. iter1, iter2: iterables that produce elements
  1206. comparable with assert_almost_equal
  1207. Checks that the elements are equal, but not
  1208. the same object. (Does not check that items
  1209. in sequences are also not the same object)
  1210. """
  1211. for elem1, elem2 in zip(iter1, iter2):
  1212. assert_almost_equal(elem1, elem2, **eql_kwargs)
  1213. msg = (
  1214. f"Expected object {repr(type(elem1))} and object {repr(type(elem2))} to be "
  1215. "different objects, but they were the same object."
  1216. )
  1217. assert elem1 is not elem2, msg
  1218. def is_extension_array_dtype_and_needs_i8_conversion(left_dtype, right_dtype) -> bool:
  1219. """
  1220. Checks that we have the combination of an ExtensionArraydtype and
  1221. a dtype that should be converted to int64
  1222. Returns
  1223. -------
  1224. bool
  1225. Related to issue #37609
  1226. """
  1227. return is_extension_array_dtype(left_dtype) and needs_i8_conversion(right_dtype)