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