conftest.py 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968
  1. """
  2. This file is very long and growing, but it was decided to not split it yet, as
  3. it's still manageable (2020-03-17, ~1.1k LoC). See gh-31989
  4. Instead of splitting it was decided to define sections here:
  5. - Configuration / Settings
  6. - Autouse fixtures
  7. - Common arguments
  8. - Missing values & co.
  9. - Classes
  10. - Indices
  11. - Series'
  12. - DataFrames
  13. - Operators & Operations
  14. - Data sets/files
  15. - Time zones
  16. - Dtypes
  17. - Misc
  18. """
  19. from __future__ import annotations
  20. from collections import abc
  21. from datetime import (
  22. date,
  23. datetime,
  24. time,
  25. timedelta,
  26. timezone,
  27. )
  28. from decimal import Decimal
  29. import operator
  30. import os
  31. from typing import (
  32. Callable,
  33. Hashable,
  34. Iterator,
  35. )
  36. from dateutil.tz import (
  37. tzlocal,
  38. tzutc,
  39. )
  40. import hypothesis
  41. from hypothesis import strategies as st
  42. import numpy as np
  43. import pytest
  44. from pytz import (
  45. FixedOffset,
  46. utc,
  47. )
  48. import pandas.util._test_decorators as td
  49. from pandas.core.dtypes.dtypes import (
  50. DatetimeTZDtype,
  51. IntervalDtype,
  52. )
  53. import pandas as pd
  54. from pandas import (
  55. DataFrame,
  56. Interval,
  57. Period,
  58. Series,
  59. Timedelta,
  60. Timestamp,
  61. compat,
  62. )
  63. import pandas._testing as tm
  64. from pandas.core import ops
  65. from pandas.core.indexes.api import (
  66. Index,
  67. MultiIndex,
  68. )
  69. try:
  70. import pyarrow as pa
  71. except ImportError:
  72. has_pyarrow = False
  73. else:
  74. del pa
  75. has_pyarrow = True
  76. zoneinfo = None
  77. if compat.PY39:
  78. # Import "zoneinfo" could not be resolved (reportMissingImports)
  79. import zoneinfo # type: ignore[no-redef]
  80. # Although zoneinfo can be imported in Py39, it is effectively
  81. # "not available" without tzdata/IANA tz data.
  82. # We will set zoneinfo to not found in this case
  83. try:
  84. zoneinfo.ZoneInfo("UTC") # type: ignore[attr-defined]
  85. except zoneinfo.ZoneInfoNotFoundError: # type: ignore[attr-defined]
  86. zoneinfo = None
  87. # ----------------------------------------------------------------
  88. # Configuration / Settings
  89. # ----------------------------------------------------------------
  90. # pytest
  91. def pytest_addoption(parser) -> None:
  92. parser.addoption("--skip-slow", action="store_true", help="skip slow tests")
  93. parser.addoption("--skip-network", action="store_true", help="skip network tests")
  94. parser.addoption("--skip-db", action="store_true", help="skip db tests")
  95. parser.addoption(
  96. "--run-high-memory", action="store_true", help="run high memory tests"
  97. )
  98. parser.addoption("--only-slow", action="store_true", help="run only slow tests")
  99. parser.addoption(
  100. "--strict-data-files",
  101. action="store_true",
  102. help="Fail if a test is skipped for missing data file.",
  103. )
  104. def ignore_doctest_warning(item: pytest.Item, path: str, message: str) -> None:
  105. """Ignore doctest warning.
  106. Parameters
  107. ----------
  108. item : pytest.Item
  109. pytest test item.
  110. path : str
  111. Module path to Python object, e.g. "pandas.core.frame.DataFrame.append". A
  112. warning will be filtered when item.name ends with in given path. So it is
  113. sufficient to specify e.g. "DataFrame.append".
  114. message : str
  115. Message to be filtered.
  116. """
  117. if item.name.endswith(path):
  118. item.add_marker(pytest.mark.filterwarnings(f"ignore:{message}"))
  119. def pytest_collection_modifyitems(items, config) -> None:
  120. skip_slow = config.getoption("--skip-slow")
  121. only_slow = config.getoption("--only-slow")
  122. skip_network = config.getoption("--skip-network")
  123. skip_db = config.getoption("--skip-db")
  124. marks = [
  125. (pytest.mark.slow, "slow", skip_slow, "--skip-slow"),
  126. (pytest.mark.network, "network", skip_network, "--network"),
  127. (pytest.mark.db, "db", skip_db, "--skip-db"),
  128. ]
  129. # Warnings from doctests that can be ignored; place reason in comment above.
  130. # Each entry specifies (path, message) - see the ignore_doctest_warning function
  131. ignored_doctest_warnings = [
  132. # Docstring divides by zero to show behavior difference
  133. ("missing.mask_zero_div_zero", "divide by zero encountered"),
  134. ]
  135. for item in items:
  136. if config.getoption("--doctest-modules") or config.getoption(
  137. "--doctest-cython", default=False
  138. ):
  139. # autouse=True for the add_doctest_imports can lead to expensive teardowns
  140. # since doctest_namespace is a session fixture
  141. item.add_marker(pytest.mark.usefixtures("add_doctest_imports"))
  142. for path, message in ignored_doctest_warnings:
  143. ignore_doctest_warning(item, path, message)
  144. # mark all tests in the pandas/tests/frame directory with "arraymanager"
  145. if "/frame/" in item.nodeid:
  146. item.add_marker(pytest.mark.arraymanager)
  147. for mark, kwd, skip_if_found, arg_name in marks:
  148. if kwd in item.keywords:
  149. # If we're skipping, no need to actually add the marker or look for
  150. # other markers
  151. if skip_if_found:
  152. item.add_marker(pytest.mark.skip(f"skipping due to {arg_name}"))
  153. break
  154. item.add_marker(mark)
  155. if only_slow and "slow" not in item.keywords:
  156. item.add_marker(pytest.mark.skip("skipping due to --only-slow"))
  157. # Hypothesis
  158. hypothesis.settings.register_profile(
  159. "ci",
  160. # Hypothesis timing checks are tuned for scalars by default, so we bump
  161. # them from 200ms to 500ms per test case as the global default. If this
  162. # is too short for a specific test, (a) try to make it faster, and (b)
  163. # if it really is slow add `@settings(deadline=...)` with a working value,
  164. # or `deadline=None` to entirely disable timeouts for that test.
  165. # 2022-02-09: Changed deadline from 500 -> None. Deadline leads to
  166. # non-actionable, flaky CI failures (# GH 24641, 44969, 45118, 44969)
  167. deadline=None,
  168. suppress_health_check=(hypothesis.HealthCheck.too_slow,),
  169. )
  170. hypothesis.settings.load_profile("ci")
  171. # Registering these strategies makes them globally available via st.from_type,
  172. # which is use for offsets in tests/tseries/offsets/test_offsets_properties.py
  173. for name in "MonthBegin MonthEnd BMonthBegin BMonthEnd".split():
  174. cls = getattr(pd.tseries.offsets, name)
  175. st.register_type_strategy(
  176. cls, st.builds(cls, n=st.integers(-99, 99), normalize=st.booleans())
  177. )
  178. for name in "YearBegin YearEnd BYearBegin BYearEnd".split():
  179. cls = getattr(pd.tseries.offsets, name)
  180. st.register_type_strategy(
  181. cls,
  182. st.builds(
  183. cls,
  184. n=st.integers(-5, 5),
  185. normalize=st.booleans(),
  186. month=st.integers(min_value=1, max_value=12),
  187. ),
  188. )
  189. for name in "QuarterBegin QuarterEnd BQuarterBegin BQuarterEnd".split():
  190. cls = getattr(pd.tseries.offsets, name)
  191. st.register_type_strategy(
  192. cls,
  193. st.builds(
  194. cls,
  195. n=st.integers(-24, 24),
  196. normalize=st.booleans(),
  197. startingMonth=st.integers(min_value=1, max_value=12),
  198. ),
  199. )
  200. @pytest.fixture
  201. def add_doctest_imports(doctest_namespace) -> None:
  202. """
  203. Make `np` and `pd` names available for doctests.
  204. """
  205. doctest_namespace["np"] = np
  206. doctest_namespace["pd"] = pd
  207. # ----------------------------------------------------------------
  208. # Autouse fixtures
  209. # ----------------------------------------------------------------
  210. @pytest.fixture(autouse=True)
  211. def configure_tests() -> None:
  212. """
  213. Configure settings for all tests and test modules.
  214. """
  215. pd.set_option("chained_assignment", "raise")
  216. # ----------------------------------------------------------------
  217. # Common arguments
  218. # ----------------------------------------------------------------
  219. @pytest.fixture(params=[0, 1, "index", "columns"], ids=lambda x: f"axis={repr(x)}")
  220. def axis(request):
  221. """
  222. Fixture for returning the axis numbers of a DataFrame.
  223. """
  224. return request.param
  225. axis_frame = axis
  226. @pytest.fixture(params=[1, "columns"], ids=lambda x: f"axis={repr(x)}")
  227. def axis_1(request):
  228. """
  229. Fixture for returning aliases of axis 1 of a DataFrame.
  230. """
  231. return request.param
  232. @pytest.fixture(params=[True, False, None])
  233. def observed(request):
  234. """
  235. Pass in the observed keyword to groupby for [True, False]
  236. This indicates whether categoricals should return values for
  237. values which are not in the grouper [False / None], or only values which
  238. appear in the grouper [True]. [None] is supported for future compatibility
  239. if we decide to change the default (and would need to warn if this
  240. parameter is not passed).
  241. """
  242. return request.param
  243. @pytest.fixture(params=[True, False, None])
  244. def ordered(request):
  245. """
  246. Boolean 'ordered' parameter for Categorical.
  247. """
  248. return request.param
  249. @pytest.fixture(params=[True, False])
  250. def skipna(request):
  251. """
  252. Boolean 'skipna' parameter.
  253. """
  254. return request.param
  255. @pytest.fixture(params=["first", "last", False])
  256. def keep(request):
  257. """
  258. Valid values for the 'keep' parameter used in
  259. .duplicated or .drop_duplicates
  260. """
  261. return request.param
  262. @pytest.fixture(params=["both", "neither", "left", "right"])
  263. def inclusive_endpoints_fixture(request):
  264. """
  265. Fixture for trying all interval 'inclusive' parameters.
  266. """
  267. return request.param
  268. @pytest.fixture(params=["left", "right", "both", "neither"])
  269. def closed(request):
  270. """
  271. Fixture for trying all interval closed parameters.
  272. """
  273. return request.param
  274. @pytest.fixture(params=["left", "right", "both", "neither"])
  275. def other_closed(request):
  276. """
  277. Secondary closed fixture to allow parametrizing over all pairs of closed.
  278. """
  279. return request.param
  280. @pytest.fixture(
  281. params=[
  282. None,
  283. "gzip",
  284. "bz2",
  285. "zip",
  286. "xz",
  287. "tar",
  288. pytest.param("zstd", marks=td.skip_if_no("zstandard")),
  289. ]
  290. )
  291. def compression(request):
  292. """
  293. Fixture for trying common compression types in compression tests.
  294. """
  295. return request.param
  296. @pytest.fixture(
  297. params=[
  298. "gzip",
  299. "bz2",
  300. "zip",
  301. "xz",
  302. "tar",
  303. pytest.param("zstd", marks=td.skip_if_no("zstandard")),
  304. ]
  305. )
  306. def compression_only(request):
  307. """
  308. Fixture for trying common compression types in compression tests excluding
  309. uncompressed case.
  310. """
  311. return request.param
  312. @pytest.fixture(params=[True, False])
  313. def writable(request):
  314. """
  315. Fixture that an array is writable.
  316. """
  317. return request.param
  318. @pytest.fixture(params=["inner", "outer", "left", "right"])
  319. def join_type(request):
  320. """
  321. Fixture for trying all types of join operations.
  322. """
  323. return request.param
  324. @pytest.fixture(params=["nlargest", "nsmallest"])
  325. def nselect_method(request):
  326. """
  327. Fixture for trying all nselect methods.
  328. """
  329. return request.param
  330. # ----------------------------------------------------------------
  331. # Missing values & co.
  332. # ----------------------------------------------------------------
  333. @pytest.fixture(params=tm.NULL_OBJECTS, ids=lambda x: type(x).__name__)
  334. def nulls_fixture(request):
  335. """
  336. Fixture for each null type in pandas.
  337. """
  338. return request.param
  339. nulls_fixture2 = nulls_fixture # Generate cartesian product of nulls_fixture
  340. @pytest.fixture(params=[None, np.nan, pd.NaT])
  341. def unique_nulls_fixture(request):
  342. """
  343. Fixture for each null type in pandas, each null type exactly once.
  344. """
  345. return request.param
  346. # Generate cartesian product of unique_nulls_fixture:
  347. unique_nulls_fixture2 = unique_nulls_fixture
  348. @pytest.fixture(params=tm.NP_NAT_OBJECTS, ids=lambda x: type(x).__name__)
  349. def np_nat_fixture(request):
  350. """
  351. Fixture for each NaT type in numpy.
  352. """
  353. return request.param
  354. # Generate cartesian product of np_nat_fixture:
  355. np_nat_fixture2 = np_nat_fixture
  356. # ----------------------------------------------------------------
  357. # Classes
  358. # ----------------------------------------------------------------
  359. @pytest.fixture(params=[DataFrame, Series])
  360. def frame_or_series(request):
  361. """
  362. Fixture to parametrize over DataFrame and Series.
  363. """
  364. return request.param
  365. @pytest.fixture(params=[Index, Series], ids=["index", "series"])
  366. def index_or_series(request):
  367. """
  368. Fixture to parametrize over Index and Series, made necessary by a mypy
  369. bug, giving an error:
  370. List item 0 has incompatible type "Type[Series]"; expected "Type[PandasObject]"
  371. See GH#29725
  372. """
  373. return request.param
  374. # Generate cartesian product of index_or_series fixture:
  375. index_or_series2 = index_or_series
  376. @pytest.fixture(params=[Index, Series, pd.array], ids=["index", "series", "array"])
  377. def index_or_series_or_array(request):
  378. """
  379. Fixture to parametrize over Index, Series, and ExtensionArray
  380. """
  381. return request.param
  382. @pytest.fixture(params=[Index, Series, DataFrame, pd.array], ids=lambda x: x.__name__)
  383. def box_with_array(request):
  384. """
  385. Fixture to test behavior for Index, Series, DataFrame, and pandas Array
  386. classes
  387. """
  388. return request.param
  389. box_with_array2 = box_with_array
  390. @pytest.fixture
  391. def dict_subclass():
  392. """
  393. Fixture for a dictionary subclass.
  394. """
  395. class TestSubDict(dict):
  396. def __init__(self, *args, **kwargs) -> None:
  397. dict.__init__(self, *args, **kwargs)
  398. return TestSubDict
  399. @pytest.fixture
  400. def non_dict_mapping_subclass():
  401. """
  402. Fixture for a non-mapping dictionary subclass.
  403. """
  404. class TestNonDictMapping(abc.Mapping):
  405. def __init__(self, underlying_dict) -> None:
  406. self._data = underlying_dict
  407. def __getitem__(self, key):
  408. return self._data.__getitem__(key)
  409. def __iter__(self) -> Iterator:
  410. return self._data.__iter__()
  411. def __len__(self) -> int:
  412. return self._data.__len__()
  413. return TestNonDictMapping
  414. # ----------------------------------------------------------------
  415. # Indices
  416. # ----------------------------------------------------------------
  417. @pytest.fixture
  418. def multiindex_year_month_day_dataframe_random_data():
  419. """
  420. DataFrame with 3 level MultiIndex (year, month, day) covering
  421. first 100 business days from 2000-01-01 with random data
  422. """
  423. tdf = tm.makeTimeDataFrame(100)
  424. ymd = tdf.groupby([lambda x: x.year, lambda x: x.month, lambda x: x.day]).sum()
  425. # use int64 Index, to make sure things work
  426. ymd.index = ymd.index.set_levels([lev.astype("i8") for lev in ymd.index.levels])
  427. ymd.index.set_names(["year", "month", "day"], inplace=True)
  428. return ymd
  429. @pytest.fixture
  430. def lexsorted_two_level_string_multiindex() -> MultiIndex:
  431. """
  432. 2-level MultiIndex, lexsorted, with string names.
  433. """
  434. return MultiIndex(
  435. levels=[["foo", "bar", "baz", "qux"], ["one", "two", "three"]],
  436. codes=[[0, 0, 0, 1, 1, 2, 2, 3, 3, 3], [0, 1, 2, 0, 1, 1, 2, 0, 1, 2]],
  437. names=["first", "second"],
  438. )
  439. @pytest.fixture
  440. def multiindex_dataframe_random_data(
  441. lexsorted_two_level_string_multiindex,
  442. ) -> DataFrame:
  443. """DataFrame with 2 level MultiIndex with random data"""
  444. index = lexsorted_two_level_string_multiindex
  445. return DataFrame(
  446. np.random.randn(10, 3), index=index, columns=Index(["A", "B", "C"], name="exp")
  447. )
  448. def _create_multiindex():
  449. """
  450. MultiIndex used to test the general functionality of this object
  451. """
  452. # See Also: tests.multi.conftest.idx
  453. major_axis = Index(["foo", "bar", "baz", "qux"])
  454. minor_axis = Index(["one", "two"])
  455. major_codes = np.array([0, 0, 1, 2, 3, 3])
  456. minor_codes = np.array([0, 1, 0, 1, 0, 1])
  457. index_names = ["first", "second"]
  458. return MultiIndex(
  459. levels=[major_axis, minor_axis],
  460. codes=[major_codes, minor_codes],
  461. names=index_names,
  462. verify_integrity=False,
  463. )
  464. def _create_mi_with_dt64tz_level():
  465. """
  466. MultiIndex with a level that is a tzaware DatetimeIndex.
  467. """
  468. # GH#8367 round trip with pickle
  469. return MultiIndex.from_product(
  470. [[1, 2], ["a", "b"], pd.date_range("20130101", periods=3, tz="US/Eastern")],
  471. names=["one", "two", "three"],
  472. )
  473. indices_dict = {
  474. "string": tm.makeStringIndex(100),
  475. "datetime": tm.makeDateIndex(100),
  476. "datetime-tz": tm.makeDateIndex(100, tz="US/Pacific"),
  477. "period": tm.makePeriodIndex(100),
  478. "timedelta": tm.makeTimedeltaIndex(100),
  479. "range": tm.makeRangeIndex(100),
  480. "int8": tm.makeIntIndex(100, dtype="int8"),
  481. "int16": tm.makeIntIndex(100, dtype="int16"),
  482. "int32": tm.makeIntIndex(100, dtype="int32"),
  483. "int64": tm.makeIntIndex(100, dtype="int64"),
  484. "uint8": tm.makeUIntIndex(100, dtype="uint8"),
  485. "uint16": tm.makeUIntIndex(100, dtype="uint16"),
  486. "uint32": tm.makeUIntIndex(100, dtype="uint32"),
  487. "uint64": tm.makeUIntIndex(100, dtype="uint64"),
  488. "float32": tm.makeFloatIndex(100, dtype="float32"),
  489. "float64": tm.makeFloatIndex(100, dtype="float64"),
  490. "bool-object": tm.makeBoolIndex(10).astype(object),
  491. "bool-dtype": Index(np.random.randn(10) < 0),
  492. "complex64": tm.makeNumericIndex(100, dtype="float64").astype("complex64"),
  493. "complex128": tm.makeNumericIndex(100, dtype="float64").astype("complex128"),
  494. "categorical": tm.makeCategoricalIndex(100),
  495. "interval": tm.makeIntervalIndex(100),
  496. "empty": Index([]),
  497. "tuples": MultiIndex.from_tuples(zip(["foo", "bar", "baz"], [1, 2, 3])),
  498. "mi-with-dt64tz-level": _create_mi_with_dt64tz_level(),
  499. "multi": _create_multiindex(),
  500. "repeats": Index([0, 0, 1, 1, 2, 2]),
  501. "nullable_int": Index(np.arange(100), dtype="Int64"),
  502. "nullable_uint": Index(np.arange(100), dtype="UInt16"),
  503. "nullable_float": Index(np.arange(100), dtype="Float32"),
  504. "nullable_bool": Index(np.arange(100).astype(bool), dtype="boolean"),
  505. "string-python": Index(pd.array(tm.makeStringIndex(100), dtype="string[python]")),
  506. }
  507. if has_pyarrow:
  508. idx = Index(pd.array(tm.makeStringIndex(100), dtype="string[pyarrow]"))
  509. indices_dict["string-pyarrow"] = idx
  510. @pytest.fixture(params=indices_dict.keys())
  511. def index(request):
  512. """
  513. Fixture for many "simple" kinds of indices.
  514. These indices are unlikely to cover corner cases, e.g.
  515. - no names
  516. - no NaTs/NaNs
  517. - no values near implementation bounds
  518. - ...
  519. """
  520. # copy to avoid mutation, e.g. setting .name
  521. return indices_dict[request.param].copy()
  522. # Needed to generate cartesian product of indices
  523. index_fixture2 = index
  524. @pytest.fixture(
  525. params=[
  526. key for key, value in indices_dict.items() if not isinstance(value, MultiIndex)
  527. ]
  528. )
  529. def index_flat(request):
  530. """
  531. index fixture, but excluding MultiIndex cases.
  532. """
  533. key = request.param
  534. return indices_dict[key].copy()
  535. # Alias so we can test with cartesian product of index_flat
  536. index_flat2 = index_flat
  537. @pytest.fixture(
  538. params=[
  539. key
  540. for key, value in indices_dict.items()
  541. if not (
  542. key.startswith("int")
  543. or key.startswith("uint")
  544. or key.startswith("float")
  545. or key in ["range", "empty", "repeats", "bool-dtype"]
  546. )
  547. and not isinstance(value, MultiIndex)
  548. ]
  549. )
  550. def index_with_missing(request):
  551. """
  552. Fixture for indices with missing values.
  553. Integer-dtype and empty cases are excluded because they cannot hold missing
  554. values.
  555. MultiIndex is excluded because isna() is not defined for MultiIndex.
  556. """
  557. # GH 35538. Use deep copy to avoid illusive bug on np-dev
  558. # GHA pipeline that writes into indices_dict despite copy
  559. ind = indices_dict[request.param].copy(deep=True)
  560. vals = ind.values
  561. if request.param in ["tuples", "mi-with-dt64tz-level", "multi"]:
  562. # For setting missing values in the top level of MultiIndex
  563. vals = ind.tolist()
  564. vals[0] = (None,) + vals[0][1:]
  565. vals[-1] = (None,) + vals[-1][1:]
  566. return MultiIndex.from_tuples(vals)
  567. else:
  568. vals[0] = None
  569. vals[-1] = None
  570. return type(ind)(vals)
  571. # ----------------------------------------------------------------
  572. # Series'
  573. # ----------------------------------------------------------------
  574. @pytest.fixture
  575. def string_series() -> Series:
  576. """
  577. Fixture for Series of floats with Index of unique strings
  578. """
  579. s = tm.makeStringSeries()
  580. s.name = "series"
  581. return s
  582. @pytest.fixture
  583. def object_series() -> Series:
  584. """
  585. Fixture for Series of dtype object with Index of unique strings
  586. """
  587. s = tm.makeObjectSeries()
  588. s.name = "objects"
  589. return s
  590. @pytest.fixture
  591. def datetime_series() -> Series:
  592. """
  593. Fixture for Series of floats with DatetimeIndex
  594. """
  595. s = tm.makeTimeSeries()
  596. s.name = "ts"
  597. return s
  598. def _create_series(index):
  599. """Helper for the _series dict"""
  600. size = len(index)
  601. data = np.random.randn(size)
  602. return Series(data, index=index, name="a", copy=False)
  603. _series = {
  604. f"series-with-{index_id}-index": _create_series(index)
  605. for index_id, index in indices_dict.items()
  606. }
  607. @pytest.fixture
  608. def series_with_simple_index(index) -> Series:
  609. """
  610. Fixture for tests on series with changing types of indices.
  611. """
  612. return _create_series(index)
  613. @pytest.fixture
  614. def series_with_multilevel_index() -> Series:
  615. """
  616. Fixture with a Series with a 2-level MultiIndex.
  617. """
  618. arrays = [
  619. ["bar", "bar", "baz", "baz", "qux", "qux", "foo", "foo"],
  620. ["one", "two", "one", "two", "one", "two", "one", "two"],
  621. ]
  622. tuples = zip(*arrays)
  623. index = MultiIndex.from_tuples(tuples)
  624. data = np.random.randn(8)
  625. ser = Series(data, index=index)
  626. ser[3] = np.NaN
  627. return ser
  628. _narrow_series = {
  629. f"{dtype.__name__}-series": tm.make_rand_series(name="a", dtype=dtype)
  630. for dtype in tm.NARROW_NP_DTYPES
  631. }
  632. _index_or_series_objs = {**indices_dict, **_series, **_narrow_series}
  633. @pytest.fixture(params=_index_or_series_objs.keys())
  634. def index_or_series_obj(request):
  635. """
  636. Fixture for tests on indexes, series and series with a narrow dtype
  637. copy to avoid mutation, e.g. setting .name
  638. """
  639. return _index_or_series_objs[request.param].copy(deep=True)
  640. # ----------------------------------------------------------------
  641. # DataFrames
  642. # ----------------------------------------------------------------
  643. @pytest.fixture
  644. def int_frame() -> DataFrame:
  645. """
  646. Fixture for DataFrame of ints with index of unique strings
  647. Columns are ['A', 'B', 'C', 'D']
  648. A B C D
  649. vpBeWjM651 1 0 1 0
  650. 5JyxmrP1En -1 0 0 0
  651. qEDaoD49U2 -1 1 0 0
  652. m66TkTfsFe 0 0 0 0
  653. EHPaNzEUFm -1 0 -1 0
  654. fpRJCevQhi 2 0 0 0
  655. OlQvnmfi3Q 0 0 -2 0
  656. ... .. .. .. ..
  657. uB1FPlz4uP 0 0 0 1
  658. EcSe6yNzCU 0 0 -1 0
  659. L50VudaiI8 -1 1 -2 0
  660. y3bpw4nwIp 0 -1 0 0
  661. H0RdLLwrCT 1 1 0 0
  662. rY82K0vMwm 0 0 0 0
  663. 1OPIUjnkjk 2 0 0 0
  664. [30 rows x 4 columns]
  665. """
  666. return DataFrame(tm.getSeriesData()).astype("int64")
  667. @pytest.fixture
  668. def datetime_frame() -> DataFrame:
  669. """
  670. Fixture for DataFrame of floats with DatetimeIndex
  671. Columns are ['A', 'B', 'C', 'D']
  672. A B C D
  673. 2000-01-03 -1.122153 0.468535 0.122226 1.693711
  674. 2000-01-04 0.189378 0.486100 0.007864 -1.216052
  675. 2000-01-05 0.041401 -0.835752 -0.035279 -0.414357
  676. 2000-01-06 0.430050 0.894352 0.090719 0.036939
  677. 2000-01-07 -0.620982 -0.668211 -0.706153 1.466335
  678. 2000-01-10 -0.752633 0.328434 -0.815325 0.699674
  679. 2000-01-11 -2.236969 0.615737 -0.829076 -1.196106
  680. ... ... ... ... ...
  681. 2000-02-03 1.642618 -0.579288 0.046005 1.385249
  682. 2000-02-04 -0.544873 -1.160962 -0.284071 -1.418351
  683. 2000-02-07 -2.656149 -0.601387 1.410148 0.444150
  684. 2000-02-08 -1.201881 -1.289040 0.772992 -1.445300
  685. 2000-02-09 1.377373 0.398619 1.008453 -0.928207
  686. 2000-02-10 0.473194 -0.636677 0.984058 0.511519
  687. 2000-02-11 -0.965556 0.408313 -1.312844 -0.381948
  688. [30 rows x 4 columns]
  689. """
  690. return DataFrame(tm.getTimeSeriesData())
  691. @pytest.fixture
  692. def float_frame() -> DataFrame:
  693. """
  694. Fixture for DataFrame of floats with index of unique strings
  695. Columns are ['A', 'B', 'C', 'D'].
  696. A B C D
  697. P7GACiRnxd -0.465578 -0.361863 0.886172 -0.053465
  698. qZKh6afn8n -0.466693 -0.373773 0.266873 1.673901
  699. tkp0r6Qble 0.148691 -0.059051 0.174817 1.598433
  700. wP70WOCtv8 0.133045 -0.581994 -0.992240 0.261651
  701. M2AeYQMnCz -1.207959 -0.185775 0.588206 0.563938
  702. QEPzyGDYDo -0.381843 -0.758281 0.502575 -0.565053
  703. r78Jwns6dn -0.653707 0.883127 0.682199 0.206159
  704. ... ... ... ... ...
  705. IHEGx9NO0T -0.277360 0.113021 -1.018314 0.196316
  706. lPMj8K27FA -1.313667 -0.604776 -1.305618 -0.863999
  707. qa66YMWQa5 1.110525 0.475310 -0.747865 0.032121
  708. yOa0ATsmcE -0.431457 0.067094 0.096567 -0.264962
  709. 65znX3uRNG 1.528446 0.160416 -0.109635 -0.032987
  710. eCOBvKqf3e 0.235281 1.622222 0.781255 0.392871
  711. xSucinXxuV -1.263557 0.252799 -0.552247 0.400426
  712. [30 rows x 4 columns]
  713. """
  714. return DataFrame(tm.getSeriesData())
  715. @pytest.fixture
  716. def mixed_type_frame() -> DataFrame:
  717. """
  718. Fixture for DataFrame of float/int/string columns with RangeIndex
  719. Columns are ['a', 'b', 'c', 'float32', 'int32'].
  720. """
  721. return DataFrame(
  722. {
  723. "a": 1.0,
  724. "b": 2,
  725. "c": "foo",
  726. "float32": np.array([1.0] * 10, dtype="float32"),
  727. "int32": np.array([1] * 10, dtype="int32"),
  728. },
  729. index=np.arange(10),
  730. )
  731. @pytest.fixture
  732. def rand_series_with_duplicate_datetimeindex() -> Series:
  733. """
  734. Fixture for Series with a DatetimeIndex that has duplicates.
  735. """
  736. dates = [
  737. datetime(2000, 1, 2),
  738. datetime(2000, 1, 2),
  739. datetime(2000, 1, 2),
  740. datetime(2000, 1, 3),
  741. datetime(2000, 1, 3),
  742. datetime(2000, 1, 3),
  743. datetime(2000, 1, 4),
  744. datetime(2000, 1, 4),
  745. datetime(2000, 1, 4),
  746. datetime(2000, 1, 5),
  747. ]
  748. return Series(np.random.randn(len(dates)), index=dates)
  749. # ----------------------------------------------------------------
  750. # Scalars
  751. # ----------------------------------------------------------------
  752. @pytest.fixture(
  753. params=[
  754. (Interval(left=0, right=5), IntervalDtype("int64", "right")),
  755. (Interval(left=0.1, right=0.5), IntervalDtype("float64", "right")),
  756. (Period("2012-01", freq="M"), "period[M]"),
  757. (Period("2012-02-01", freq="D"), "period[D]"),
  758. (
  759. Timestamp("2011-01-01", tz="US/Eastern"),
  760. DatetimeTZDtype(tz="US/Eastern"),
  761. ),
  762. (Timedelta(seconds=500), "timedelta64[ns]"),
  763. ]
  764. )
  765. def ea_scalar_and_dtype(request):
  766. return request.param
  767. # ----------------------------------------------------------------
  768. # Operators & Operations
  769. # ----------------------------------------------------------------
  770. _all_arithmetic_operators = [
  771. "__add__",
  772. "__radd__",
  773. "__sub__",
  774. "__rsub__",
  775. "__mul__",
  776. "__rmul__",
  777. "__floordiv__",
  778. "__rfloordiv__",
  779. "__truediv__",
  780. "__rtruediv__",
  781. "__pow__",
  782. "__rpow__",
  783. "__mod__",
  784. "__rmod__",
  785. ]
  786. @pytest.fixture(params=_all_arithmetic_operators)
  787. def all_arithmetic_operators(request):
  788. """
  789. Fixture for dunder names for common arithmetic operations.
  790. """
  791. return request.param
  792. @pytest.fixture(
  793. params=[
  794. operator.add,
  795. ops.radd,
  796. operator.sub,
  797. ops.rsub,
  798. operator.mul,
  799. ops.rmul,
  800. operator.truediv,
  801. ops.rtruediv,
  802. operator.floordiv,
  803. ops.rfloordiv,
  804. operator.mod,
  805. ops.rmod,
  806. operator.pow,
  807. ops.rpow,
  808. operator.eq,
  809. operator.ne,
  810. operator.lt,
  811. operator.le,
  812. operator.gt,
  813. operator.ge,
  814. operator.and_,
  815. ops.rand_,
  816. operator.xor,
  817. ops.rxor,
  818. operator.or_,
  819. ops.ror_,
  820. ]
  821. )
  822. def all_binary_operators(request):
  823. """
  824. Fixture for operator and roperator arithmetic, comparison, and logical ops.
  825. """
  826. return request.param
  827. @pytest.fixture(
  828. params=[
  829. operator.add,
  830. ops.radd,
  831. operator.sub,
  832. ops.rsub,
  833. operator.mul,
  834. ops.rmul,
  835. operator.truediv,
  836. ops.rtruediv,
  837. operator.floordiv,
  838. ops.rfloordiv,
  839. operator.mod,
  840. ops.rmod,
  841. operator.pow,
  842. ops.rpow,
  843. ]
  844. )
  845. def all_arithmetic_functions(request):
  846. """
  847. Fixture for operator and roperator arithmetic functions.
  848. Notes
  849. -----
  850. This includes divmod and rdivmod, whereas all_arithmetic_operators
  851. does not.
  852. """
  853. return request.param
  854. _all_numeric_reductions = [
  855. "count",
  856. "sum",
  857. "max",
  858. "min",
  859. "mean",
  860. "prod",
  861. "std",
  862. "var",
  863. "median",
  864. "kurt",
  865. "skew",
  866. "sem",
  867. ]
  868. @pytest.fixture(params=_all_numeric_reductions)
  869. def all_numeric_reductions(request):
  870. """
  871. Fixture for numeric reduction names.
  872. """
  873. return request.param
  874. _all_boolean_reductions = ["all", "any"]
  875. @pytest.fixture(params=_all_boolean_reductions)
  876. def all_boolean_reductions(request):
  877. """
  878. Fixture for boolean reduction names.
  879. """
  880. return request.param
  881. _all_reductions = _all_numeric_reductions + _all_boolean_reductions
  882. @pytest.fixture(params=_all_reductions)
  883. def all_reductions(request):
  884. """
  885. Fixture for all (boolean + numeric) reduction names.
  886. """
  887. return request.param
  888. @pytest.fixture(
  889. params=[
  890. operator.eq,
  891. operator.ne,
  892. operator.gt,
  893. operator.ge,
  894. operator.lt,
  895. operator.le,
  896. ]
  897. )
  898. def comparison_op(request):
  899. """
  900. Fixture for operator module comparison functions.
  901. """
  902. return request.param
  903. @pytest.fixture(params=["__le__", "__lt__", "__ge__", "__gt__"])
  904. def compare_operators_no_eq_ne(request):
  905. """
  906. Fixture for dunder names for compare operations except == and !=
  907. * >=
  908. * >
  909. * <
  910. * <=
  911. """
  912. return request.param
  913. @pytest.fixture(
  914. params=["__and__", "__rand__", "__or__", "__ror__", "__xor__", "__rxor__"]
  915. )
  916. def all_logical_operators(request):
  917. """
  918. Fixture for dunder names for common logical operations
  919. * |
  920. * &
  921. * ^
  922. """
  923. return request.param
  924. _all_numeric_accumulations = ["cumsum", "cumprod", "cummin", "cummax"]
  925. @pytest.fixture(params=_all_numeric_accumulations)
  926. def all_numeric_accumulations(request):
  927. """
  928. Fixture for numeric accumulation names
  929. """
  930. return request.param
  931. # ----------------------------------------------------------------
  932. # Data sets/files
  933. # ----------------------------------------------------------------
  934. @pytest.fixture
  935. def strict_data_files(pytestconfig):
  936. """
  937. Returns the configuration for the test setting `--strict-data-files`.
  938. """
  939. return pytestconfig.getoption("--strict-data-files")
  940. @pytest.fixture
  941. def datapath(strict_data_files: str) -> Callable[..., str]:
  942. """
  943. Get the path to a data file.
  944. Parameters
  945. ----------
  946. path : str
  947. Path to the file, relative to ``pandas/tests/``
  948. Returns
  949. -------
  950. path including ``pandas/tests``.
  951. Raises
  952. ------
  953. ValueError
  954. If the path doesn't exist and the --strict-data-files option is set.
  955. """
  956. BASE_PATH = os.path.join(os.path.dirname(__file__), "tests")
  957. def deco(*args):
  958. path = os.path.join(BASE_PATH, *args)
  959. if not os.path.exists(path):
  960. if strict_data_files:
  961. raise ValueError(
  962. f"Could not find file {path} and --strict-data-files is set."
  963. )
  964. pytest.skip(f"Could not find {path}.")
  965. return path
  966. return deco
  967. @pytest.fixture
  968. def iris(datapath) -> DataFrame:
  969. """
  970. The iris dataset as a DataFrame.
  971. """
  972. return pd.read_csv(datapath("io", "data", "csv", "iris.csv"))
  973. # ----------------------------------------------------------------
  974. # Time zones
  975. # ----------------------------------------------------------------
  976. TIMEZONES = [
  977. None,
  978. "UTC",
  979. "US/Eastern",
  980. "Asia/Tokyo",
  981. "dateutil/US/Pacific",
  982. "dateutil/Asia/Singapore",
  983. "+01:15",
  984. "-02:15",
  985. "UTC+01:15",
  986. "UTC-02:15",
  987. tzutc(),
  988. tzlocal(),
  989. FixedOffset(300),
  990. FixedOffset(0),
  991. FixedOffset(-300),
  992. timezone.utc,
  993. timezone(timedelta(hours=1)),
  994. timezone(timedelta(hours=-1), name="foo"),
  995. ]
  996. if zoneinfo is not None:
  997. TIMEZONES.extend([zoneinfo.ZoneInfo("US/Pacific"), zoneinfo.ZoneInfo("UTC")])
  998. TIMEZONE_IDS = [repr(i) for i in TIMEZONES]
  999. @td.parametrize_fixture_doc(str(TIMEZONE_IDS))
  1000. @pytest.fixture(params=TIMEZONES, ids=TIMEZONE_IDS)
  1001. def tz_naive_fixture(request):
  1002. """
  1003. Fixture for trying timezones including default (None): {0}
  1004. """
  1005. return request.param
  1006. @td.parametrize_fixture_doc(str(TIMEZONE_IDS[1:]))
  1007. @pytest.fixture(params=TIMEZONES[1:], ids=TIMEZONE_IDS[1:])
  1008. def tz_aware_fixture(request):
  1009. """
  1010. Fixture for trying explicit timezones: {0}
  1011. """
  1012. return request.param
  1013. # Generate cartesian product of tz_aware_fixture:
  1014. tz_aware_fixture2 = tz_aware_fixture
  1015. _UTCS = ["utc", "dateutil/UTC", utc, tzutc(), timezone.utc]
  1016. if zoneinfo is not None:
  1017. _UTCS.append(zoneinfo.ZoneInfo("UTC"))
  1018. @pytest.fixture(params=_UTCS)
  1019. def utc_fixture(request):
  1020. """
  1021. Fixture to provide variants of UTC timezone strings and tzinfo objects.
  1022. """
  1023. return request.param
  1024. utc_fixture2 = utc_fixture
  1025. # ----------------------------------------------------------------
  1026. # Dtypes
  1027. # ----------------------------------------------------------------
  1028. @pytest.fixture(params=tm.STRING_DTYPES)
  1029. def string_dtype(request):
  1030. """
  1031. Parametrized fixture for string dtypes.
  1032. * str
  1033. * 'str'
  1034. * 'U'
  1035. """
  1036. return request.param
  1037. @pytest.fixture(
  1038. params=[
  1039. "string[python]",
  1040. pytest.param("string[pyarrow]", marks=td.skip_if_no("pyarrow")),
  1041. ]
  1042. )
  1043. def nullable_string_dtype(request):
  1044. """
  1045. Parametrized fixture for string dtypes.
  1046. * 'string[python]'
  1047. * 'string[pyarrow]'
  1048. """
  1049. return request.param
  1050. @pytest.fixture(
  1051. params=[
  1052. "python",
  1053. pytest.param("pyarrow", marks=td.skip_if_no("pyarrow")),
  1054. ]
  1055. )
  1056. def string_storage(request):
  1057. """
  1058. Parametrized fixture for pd.options.mode.string_storage.
  1059. * 'python'
  1060. * 'pyarrow'
  1061. """
  1062. return request.param
  1063. @pytest.fixture(
  1064. params=[
  1065. "numpy_nullable",
  1066. pytest.param("pyarrow", marks=td.skip_if_no("pyarrow")),
  1067. ]
  1068. )
  1069. def dtype_backend(request):
  1070. """
  1071. Parametrized fixture for pd.options.mode.string_storage.
  1072. * 'python'
  1073. * 'pyarrow'
  1074. """
  1075. return request.param
  1076. # Alias so we can test with cartesian product of string_storage
  1077. string_storage2 = string_storage
  1078. @pytest.fixture(params=tm.BYTES_DTYPES)
  1079. def bytes_dtype(request):
  1080. """
  1081. Parametrized fixture for bytes dtypes.
  1082. * bytes
  1083. * 'bytes'
  1084. """
  1085. return request.param
  1086. @pytest.fixture(params=tm.OBJECT_DTYPES)
  1087. def object_dtype(request):
  1088. """
  1089. Parametrized fixture for object dtypes.
  1090. * object
  1091. * 'object'
  1092. """
  1093. return request.param
  1094. @pytest.fixture(
  1095. params=[
  1096. "object",
  1097. "string[python]",
  1098. pytest.param("string[pyarrow]", marks=td.skip_if_no("pyarrow")),
  1099. ]
  1100. )
  1101. def any_string_dtype(request):
  1102. """
  1103. Parametrized fixture for string dtypes.
  1104. * 'object'
  1105. * 'string[python]'
  1106. * 'string[pyarrow]'
  1107. """
  1108. return request.param
  1109. @pytest.fixture(params=tm.DATETIME64_DTYPES)
  1110. def datetime64_dtype(request):
  1111. """
  1112. Parametrized fixture for datetime64 dtypes.
  1113. * 'datetime64[ns]'
  1114. * 'M8[ns]'
  1115. """
  1116. return request.param
  1117. @pytest.fixture(params=tm.TIMEDELTA64_DTYPES)
  1118. def timedelta64_dtype(request):
  1119. """
  1120. Parametrized fixture for timedelta64 dtypes.
  1121. * 'timedelta64[ns]'
  1122. * 'm8[ns]'
  1123. """
  1124. return request.param
  1125. @pytest.fixture
  1126. def fixed_now_ts() -> Timestamp:
  1127. """
  1128. Fixture emits fixed Timestamp.now()
  1129. """
  1130. return Timestamp(
  1131. year=2021, month=1, day=1, hour=12, minute=4, second=13, microsecond=22
  1132. )
  1133. @pytest.fixture(params=tm.FLOAT_NUMPY_DTYPES)
  1134. def float_numpy_dtype(request):
  1135. """
  1136. Parameterized fixture for float dtypes.
  1137. * float
  1138. * 'float32'
  1139. * 'float64'
  1140. """
  1141. return request.param
  1142. @pytest.fixture(params=tm.FLOAT_EA_DTYPES)
  1143. def float_ea_dtype(request):
  1144. """
  1145. Parameterized fixture for float dtypes.
  1146. * 'Float32'
  1147. * 'Float64'
  1148. """
  1149. return request.param
  1150. @pytest.fixture(params=tm.ALL_FLOAT_DTYPES)
  1151. def any_float_dtype(request):
  1152. """
  1153. Parameterized fixture for float dtypes.
  1154. * float
  1155. * 'float32'
  1156. * 'float64'
  1157. * 'Float32'
  1158. * 'Float64'
  1159. """
  1160. return request.param
  1161. @pytest.fixture(params=tm.COMPLEX_DTYPES)
  1162. def complex_dtype(request):
  1163. """
  1164. Parameterized fixture for complex dtypes.
  1165. * complex
  1166. * 'complex64'
  1167. * 'complex128'
  1168. """
  1169. return request.param
  1170. @pytest.fixture(params=tm.SIGNED_INT_NUMPY_DTYPES)
  1171. def any_signed_int_numpy_dtype(request):
  1172. """
  1173. Parameterized fixture for signed integer dtypes.
  1174. * int
  1175. * 'int8'
  1176. * 'int16'
  1177. * 'int32'
  1178. * 'int64'
  1179. """
  1180. return request.param
  1181. @pytest.fixture(params=tm.UNSIGNED_INT_NUMPY_DTYPES)
  1182. def any_unsigned_int_numpy_dtype(request):
  1183. """
  1184. Parameterized fixture for unsigned integer dtypes.
  1185. * 'uint8'
  1186. * 'uint16'
  1187. * 'uint32'
  1188. * 'uint64'
  1189. """
  1190. return request.param
  1191. @pytest.fixture(params=tm.ALL_INT_NUMPY_DTYPES)
  1192. def any_int_numpy_dtype(request):
  1193. """
  1194. Parameterized fixture for any integer dtype.
  1195. * int
  1196. * 'int8'
  1197. * 'uint8'
  1198. * 'int16'
  1199. * 'uint16'
  1200. * 'int32'
  1201. * 'uint32'
  1202. * 'int64'
  1203. * 'uint64'
  1204. """
  1205. return request.param
  1206. @pytest.fixture(params=tm.ALL_INT_EA_DTYPES)
  1207. def any_int_ea_dtype(request):
  1208. """
  1209. Parameterized fixture for any nullable integer dtype.
  1210. * 'UInt8'
  1211. * 'Int8'
  1212. * 'UInt16'
  1213. * 'Int16'
  1214. * 'UInt32'
  1215. * 'Int32'
  1216. * 'UInt64'
  1217. * 'Int64'
  1218. """
  1219. return request.param
  1220. @pytest.fixture(params=tm.ALL_INT_DTYPES)
  1221. def any_int_dtype(request):
  1222. """
  1223. Parameterized fixture for any nullable integer dtype.
  1224. * int
  1225. * 'int8'
  1226. * 'uint8'
  1227. * 'int16'
  1228. * 'uint16'
  1229. * 'int32'
  1230. * 'uint32'
  1231. * 'int64'
  1232. * 'uint64'
  1233. * 'UInt8'
  1234. * 'Int8'
  1235. * 'UInt16'
  1236. * 'Int16'
  1237. * 'UInt32'
  1238. * 'Int32'
  1239. * 'UInt64'
  1240. * 'Int64'
  1241. """
  1242. return request.param
  1243. @pytest.fixture(params=tm.ALL_INT_EA_DTYPES + tm.FLOAT_EA_DTYPES)
  1244. def any_numeric_ea_dtype(request):
  1245. """
  1246. Parameterized fixture for any nullable integer dtype and
  1247. any float ea dtypes.
  1248. * 'UInt8'
  1249. * 'Int8'
  1250. * 'UInt16'
  1251. * 'Int16'
  1252. * 'UInt32'
  1253. * 'Int32'
  1254. * 'UInt64'
  1255. * 'Int64'
  1256. * 'Float32'
  1257. * 'Float64'
  1258. """
  1259. return request.param
  1260. # Unsupported operand types for + ("List[Union[str, ExtensionDtype, dtype[Any],
  1261. # Type[object]]]" and "List[str]")
  1262. @pytest.fixture(
  1263. params=tm.ALL_INT_EA_DTYPES
  1264. + tm.FLOAT_EA_DTYPES
  1265. + tm.ALL_INT_PYARROW_DTYPES_STR_REPR
  1266. + tm.FLOAT_PYARROW_DTYPES_STR_REPR # type: ignore[operator]
  1267. )
  1268. def any_numeric_ea_and_arrow_dtype(request):
  1269. """
  1270. Parameterized fixture for any nullable integer dtype and
  1271. any float ea dtypes.
  1272. * 'UInt8'
  1273. * 'Int8'
  1274. * 'UInt16'
  1275. * 'Int16'
  1276. * 'UInt32'
  1277. * 'Int32'
  1278. * 'UInt64'
  1279. * 'Int64'
  1280. * 'Float32'
  1281. * 'Float64'
  1282. * 'uint8[pyarrow]'
  1283. * 'int8[pyarrow]'
  1284. * 'uint16[pyarrow]'
  1285. * 'int16[pyarrow]'
  1286. * 'uint32[pyarrow]'
  1287. * 'int32[pyarrow]'
  1288. * 'uint64[pyarrow]'
  1289. * 'int64[pyarrow]'
  1290. * 'float32[pyarrow]'
  1291. * 'float64[pyarrow]'
  1292. """
  1293. return request.param
  1294. @pytest.fixture(params=tm.SIGNED_INT_EA_DTYPES)
  1295. def any_signed_int_ea_dtype(request):
  1296. """
  1297. Parameterized fixture for any signed nullable integer dtype.
  1298. * 'Int8'
  1299. * 'Int16'
  1300. * 'Int32'
  1301. * 'Int64'
  1302. """
  1303. return request.param
  1304. @pytest.fixture(params=tm.ALL_REAL_NUMPY_DTYPES)
  1305. def any_real_numpy_dtype(request):
  1306. """
  1307. Parameterized fixture for any (purely) real numeric dtype.
  1308. * int
  1309. * 'int8'
  1310. * 'uint8'
  1311. * 'int16'
  1312. * 'uint16'
  1313. * 'int32'
  1314. * 'uint32'
  1315. * 'int64'
  1316. * 'uint64'
  1317. * float
  1318. * 'float32'
  1319. * 'float64'
  1320. """
  1321. return request.param
  1322. @pytest.fixture(params=tm.ALL_REAL_DTYPES)
  1323. def any_real_numeric_dtype(request):
  1324. """
  1325. Parameterized fixture for any (purely) real numeric dtype.
  1326. * int
  1327. * 'int8'
  1328. * 'uint8'
  1329. * 'int16'
  1330. * 'uint16'
  1331. * 'int32'
  1332. * 'uint32'
  1333. * 'int64'
  1334. * 'uint64'
  1335. * float
  1336. * 'float32'
  1337. * 'float64'
  1338. and associated ea dtypes.
  1339. """
  1340. return request.param
  1341. @pytest.fixture(params=tm.ALL_NUMPY_DTYPES)
  1342. def any_numpy_dtype(request):
  1343. """
  1344. Parameterized fixture for all numpy dtypes.
  1345. * bool
  1346. * 'bool'
  1347. * int
  1348. * 'int8'
  1349. * 'uint8'
  1350. * 'int16'
  1351. * 'uint16'
  1352. * 'int32'
  1353. * 'uint32'
  1354. * 'int64'
  1355. * 'uint64'
  1356. * float
  1357. * 'float32'
  1358. * 'float64'
  1359. * complex
  1360. * 'complex64'
  1361. * 'complex128'
  1362. * str
  1363. * 'str'
  1364. * 'U'
  1365. * bytes
  1366. * 'bytes'
  1367. * 'datetime64[ns]'
  1368. * 'M8[ns]'
  1369. * 'timedelta64[ns]'
  1370. * 'm8[ns]'
  1371. * object
  1372. * 'object'
  1373. """
  1374. return request.param
  1375. @pytest.fixture(params=tm.ALL_NUMERIC_DTYPES)
  1376. def any_numeric_dtype(request):
  1377. """
  1378. Parameterized fixture for all numeric dtypes.
  1379. * int
  1380. * 'int8'
  1381. * 'uint8'
  1382. * 'int16'
  1383. * 'uint16'
  1384. * 'int32'
  1385. * 'uint32'
  1386. * 'int64'
  1387. * 'uint64'
  1388. * float
  1389. * 'float32'
  1390. * 'float64'
  1391. * complex
  1392. * 'complex64'
  1393. * 'complex128'
  1394. * 'UInt8'
  1395. * 'Int8'
  1396. * 'UInt16'
  1397. * 'Int16'
  1398. * 'UInt32'
  1399. * 'Int32'
  1400. * 'UInt64'
  1401. * 'Int64'
  1402. * 'Float32'
  1403. * 'Float64'
  1404. """
  1405. return request.param
  1406. # categoricals are handled separately
  1407. _any_skipna_inferred_dtype = [
  1408. ("string", ["a", np.nan, "c"]),
  1409. ("string", ["a", pd.NA, "c"]),
  1410. ("mixed", ["a", pd.NaT, "c"]), # pd.NaT not considered valid by is_string_array
  1411. ("bytes", [b"a", np.nan, b"c"]),
  1412. ("empty", [np.nan, np.nan, np.nan]),
  1413. ("empty", []),
  1414. ("mixed-integer", ["a", np.nan, 2]),
  1415. ("mixed", ["a", np.nan, 2.0]),
  1416. ("floating", [1.0, np.nan, 2.0]),
  1417. ("integer", [1, np.nan, 2]),
  1418. ("mixed-integer-float", [1, np.nan, 2.0]),
  1419. ("decimal", [Decimal(1), np.nan, Decimal(2)]),
  1420. ("boolean", [True, np.nan, False]),
  1421. ("boolean", [True, pd.NA, False]),
  1422. ("datetime64", [np.datetime64("2013-01-01"), np.nan, np.datetime64("2018-01-01")]),
  1423. ("datetime", [Timestamp("20130101"), np.nan, Timestamp("20180101")]),
  1424. ("date", [date(2013, 1, 1), np.nan, date(2018, 1, 1)]),
  1425. # The following two dtypes are commented out due to GH 23554
  1426. # ('complex', [1 + 1j, np.nan, 2 + 2j]),
  1427. # ('timedelta64', [np.timedelta64(1, 'D'),
  1428. # np.nan, np.timedelta64(2, 'D')]),
  1429. ("timedelta", [timedelta(1), np.nan, timedelta(2)]),
  1430. ("time", [time(1), np.nan, time(2)]),
  1431. ("period", [Period(2013), pd.NaT, Period(2018)]),
  1432. ("interval", [Interval(0, 1), np.nan, Interval(0, 2)]),
  1433. ]
  1434. ids, _ = zip(*_any_skipna_inferred_dtype) # use inferred type as fixture-id
  1435. @pytest.fixture(params=_any_skipna_inferred_dtype, ids=ids)
  1436. def any_skipna_inferred_dtype(request):
  1437. """
  1438. Fixture for all inferred dtypes from _libs.lib.infer_dtype
  1439. The covered (inferred) types are:
  1440. * 'string'
  1441. * 'empty'
  1442. * 'bytes'
  1443. * 'mixed'
  1444. * 'mixed-integer'
  1445. * 'mixed-integer-float'
  1446. * 'floating'
  1447. * 'integer'
  1448. * 'decimal'
  1449. * 'boolean'
  1450. * 'datetime64'
  1451. * 'datetime'
  1452. * 'date'
  1453. * 'timedelta'
  1454. * 'time'
  1455. * 'period'
  1456. * 'interval'
  1457. Returns
  1458. -------
  1459. inferred_dtype : str
  1460. The string for the inferred dtype from _libs.lib.infer_dtype
  1461. values : np.ndarray
  1462. An array of object dtype that will be inferred to have
  1463. `inferred_dtype`
  1464. Examples
  1465. --------
  1466. >>> from pandas._libs import lib
  1467. >>>
  1468. >>> def test_something(any_skipna_inferred_dtype):
  1469. ... inferred_dtype, values = any_skipna_inferred_dtype
  1470. ... # will pass
  1471. ... assert lib.infer_dtype(values, skipna=True) == inferred_dtype
  1472. """
  1473. inferred_dtype, values = request.param
  1474. values = np.array(values, dtype=object) # object dtype to avoid casting
  1475. # correctness of inference tested in tests/dtypes/test_inference.py
  1476. return inferred_dtype, values
  1477. # ----------------------------------------------------------------
  1478. # Misc
  1479. # ----------------------------------------------------------------
  1480. @pytest.fixture
  1481. def ip():
  1482. """
  1483. Get an instance of IPython.InteractiveShell.
  1484. Will raise a skip if IPython is not installed.
  1485. """
  1486. pytest.importorskip("IPython", minversion="6.0.0")
  1487. from IPython.core.interactiveshell import InteractiveShell
  1488. # GH#35711 make sure sqlite history file handle is not leaked
  1489. from traitlets.config import Config # isort:skip
  1490. c = Config()
  1491. c.HistoryManager.hist_file = ":memory:"
  1492. return InteractiveShell(config=c)
  1493. @pytest.fixture(params=["bsr", "coo", "csc", "csr", "dia", "dok", "lil"])
  1494. def spmatrix(request):
  1495. """
  1496. Yields scipy sparse matrix classes.
  1497. """
  1498. from scipy import sparse
  1499. return getattr(sparse, request.param + "_matrix")
  1500. @pytest.fixture(
  1501. params=[
  1502. getattr(pd.offsets, o)
  1503. for o in pd.offsets.__all__
  1504. if issubclass(getattr(pd.offsets, o), pd.offsets.Tick) and o != "Tick"
  1505. ]
  1506. )
  1507. def tick_classes(request):
  1508. """
  1509. Fixture for Tick based datetime offsets available for a time series.
  1510. """
  1511. return request.param
  1512. @pytest.fixture(params=[None, lambda x: x])
  1513. def sort_by_key(request):
  1514. """
  1515. Simple fixture for testing keys in sorting methods.
  1516. Tests None (no key) and the identity key.
  1517. """
  1518. return request.param
  1519. @pytest.fixture()
  1520. def fsspectest():
  1521. pytest.importorskip("fsspec")
  1522. from fsspec import register_implementation
  1523. from fsspec.implementations.memory import MemoryFileSystem
  1524. from fsspec.registry import _registry as registry
  1525. class TestMemoryFS(MemoryFileSystem):
  1526. protocol = "testmem"
  1527. test = [None]
  1528. def __init__(self, **kwargs) -> None:
  1529. self.test[0] = kwargs.pop("test", None)
  1530. super().__init__(**kwargs)
  1531. register_implementation("testmem", TestMemoryFS, clobber=True)
  1532. yield TestMemoryFS()
  1533. registry.pop("testmem", None)
  1534. TestMemoryFS.test[0] = None
  1535. TestMemoryFS.store.clear()
  1536. @pytest.fixture(
  1537. params=[
  1538. ("foo", None, None),
  1539. ("Egon", "Venkman", None),
  1540. ("NCC1701D", "NCC1701D", "NCC1701D"),
  1541. # possibly-matching NAs
  1542. (np.nan, np.nan, np.nan),
  1543. (np.nan, pd.NaT, None),
  1544. (np.nan, pd.NA, None),
  1545. (pd.NA, pd.NA, pd.NA),
  1546. ]
  1547. )
  1548. def names(request) -> tuple[Hashable, Hashable, Hashable]:
  1549. """
  1550. A 3-tuple of names, the first two for operands, the last for a result.
  1551. """
  1552. return request.param
  1553. @pytest.fixture(params=[tm.setitem, tm.loc, tm.iloc])
  1554. def indexer_sli(request):
  1555. """
  1556. Parametrize over __setitem__, loc.__setitem__, iloc.__setitem__
  1557. """
  1558. return request.param
  1559. @pytest.fixture(params=[tm.loc, tm.iloc])
  1560. def indexer_li(request):
  1561. """
  1562. Parametrize over loc.__getitem__, iloc.__getitem__
  1563. """
  1564. return request.param
  1565. @pytest.fixture(params=[tm.setitem, tm.iloc])
  1566. def indexer_si(request):
  1567. """
  1568. Parametrize over __setitem__, iloc.__setitem__
  1569. """
  1570. return request.param
  1571. @pytest.fixture(params=[tm.setitem, tm.loc])
  1572. def indexer_sl(request):
  1573. """
  1574. Parametrize over __setitem__, loc.__setitem__
  1575. """
  1576. return request.param
  1577. @pytest.fixture(params=[tm.at, tm.loc])
  1578. def indexer_al(request):
  1579. """
  1580. Parametrize over at.__setitem__, loc.__setitem__
  1581. """
  1582. return request.param
  1583. @pytest.fixture(params=[tm.iat, tm.iloc])
  1584. def indexer_ial(request):
  1585. """
  1586. Parametrize over iat.__setitem__, iloc.__setitem__
  1587. """
  1588. return request.param
  1589. @pytest.fixture
  1590. def using_array_manager() -> bool:
  1591. """
  1592. Fixture to check if the array manager is being used.
  1593. """
  1594. return pd.options.mode.data_manager == "array"
  1595. @pytest.fixture
  1596. def using_copy_on_write() -> bool:
  1597. """
  1598. Fixture to check if Copy-on-Write is enabled.
  1599. """
  1600. return pd.options.mode.copy_on_write and pd.options.mode.data_manager == "block"
  1601. warsaws = ["Europe/Warsaw", "dateutil/Europe/Warsaw"]
  1602. if zoneinfo is not None:
  1603. warsaws.append(zoneinfo.ZoneInfo("Europe/Warsaw"))
  1604. @pytest.fixture(params=warsaws)
  1605. def warsaw(request) -> str:
  1606. """
  1607. tzinfo for Europe/Warsaw using pytz, dateutil, or zoneinfo.
  1608. """
  1609. return request.param