| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159 |
- """
- This file is very long and growing, but it was decided to not split it yet, as
- it's still manageable (2020-03-17, ~1.1k LoC). See gh-31989
- Instead of splitting it was decided to define sections here:
- - Configuration / Settings
- - Autouse fixtures
- - Common arguments
- - Missing values & co.
- - Classes
- - Indices
- - Series'
- - DataFrames
- - Operators & Operations
- - Data sets/files
- - Time zones
- - Dtypes
- - Misc
- """
- from __future__ import annotations
- from collections import abc
- from datetime import (
- date,
- datetime,
- time,
- timedelta,
- timezone,
- )
- from decimal import Decimal
- import gc
- import operator
- import os
- from typing import (
- TYPE_CHECKING,
- Any,
- )
- import uuid
- from dateutil.tz import (
- tzlocal,
- tzutc,
- )
- import hypothesis
- from hypothesis import strategies as st
- import numpy as np
- import pytest
- from pandas.compat._optional import import_optional_dependency
- import pandas.util._test_decorators as td
- from pandas.core.dtypes.dtypes import (
- DatetimeTZDtype,
- IntervalDtype,
- )
- import pandas as pd
- from pandas import (
- CategoricalIndex,
- DataFrame,
- Interval,
- IntervalIndex,
- Period,
- RangeIndex,
- Series,
- Timedelta,
- Timestamp,
- date_range,
- period_range,
- timedelta_range,
- )
- import pandas._testing as tm
- from pandas.core import ops
- from pandas.core.indexes.api import (
- Index,
- MultiIndex,
- )
- if TYPE_CHECKING:
- from collections.abc import (
- Callable,
- Hashable,
- Iterator,
- )
- try:
- import pyarrow as pa
- except ImportError:
- has_pyarrow = False
- else:
- del pa
- has_pyarrow = True
- pytz = import_optional_dependency("pytz", errors="ignore")
- # ----------------------------------------------------------------
- # Configuration / Settings
- # ----------------------------------------------------------------
- # pytest
- def pytest_addoption(parser) -> None:
- parser.addoption(
- "--no-strict-data-files",
- action="store_false",
- help="Don't fail if a test is skipped for missing data file.",
- )
- def pytest_sessionstart(session):
- import doctest
- import inspect
- # https://github.com/pandas-dev/pandas/pull/62988
- # When we modify the __module__ of a class, the __module__ on the methods
- # of that class do not change. When these two disagree, doctests would not
- # typically run. We hack `DocTestFinder` to avoid this.
- orig = doctest.DocTestFinder._from_module # type: ignore[attr-defined]
- def _from_module(self, module, object):
- # When . is in __qualname__, object is a method of a class.
- if inspect.isfunction(object) and "." in object.__qualname__:
- # We only get here when the class that the method is on is from the
- # appropriate module. So ignore checking the __module__ of the method
- # itself and run the doctest.
- return True
- return orig(self, module, object)
- doctest.DocTestFinder._from_module = _from_module # type: ignore[attr-defined]
- def ignore_doctest_warning(item: pytest.Item, path: str, message: str) -> None:
- """Ignore doctest warning.
- Parameters
- ----------
- item : pytest.Item
- pytest test item.
- path : str
- Module path to Python object, e.g. "pandas.DataFrame.append". A
- warning will be filtered when item.name ends with in given path. So it is
- sufficient to specify e.g. "DataFrame.append".
- message : str
- Message to be filtered.
- """
- if item.name.endswith(path):
- item.add_marker(pytest.mark.filterwarnings(f"ignore:{message}"))
- def pytest_collection_modifyitems(items, config) -> None:
- is_doctest = config.getoption("--doctest-modules") or config.getoption(
- "--doctest-cython", default=False
- )
- # Warnings from doctests that can be ignored; place reason in comment above.
- # Each entry specifies (path, message) - see the ignore_doctest_warning function
- ignored_doctest_warnings = [
- ("api.interchange.from_dataframe", "The DataFrame Interchange Protocol"),
- ("is_int64_dtype", "is_int64_dtype is deprecated"),
- ("is_interval_dtype", "is_interval_dtype is deprecated"),
- ("is_period_dtype", "is_period_dtype is deprecated"),
- ("is_datetime64tz_dtype", "is_datetime64tz_dtype is deprecated"),
- ("is_categorical_dtype", "is_categorical_dtype is deprecated"),
- ("is_sparse", "is_sparse is deprecated"),
- ("CategoricalDtype._from_values_or_dtype", "Constructing a Categorical"),
- ("DataFrame.__dataframe__", "The DataFrame Interchange Protocol"),
- ("DataFrameGroupBy.fillna", "DataFrameGroupBy.fillna is deprecated"),
- ("DataFrameGroupBy.corrwith", "DataFrameGroupBy.corrwith is deprecated"),
- ("NDFrame.replace", "Series.replace without 'value'"),
- ("NDFrame.clip", "Downcasting behavior in Series and DataFrame methods"),
- ("Series.idxmin", "The behavior of Series.idxmin"),
- ("Series.idxmax", "The behavior of Series.idxmax"),
- ("SeriesGroupBy.fillna", "SeriesGroupBy.fillna is deprecated"),
- ("SeriesGroupBy.idxmin", "The behavior of Series.idxmin"),
- ("SeriesGroupBy.idxmax", "The behavior of Series.idxmax"),
- ("to_pytimedelta", "The behavior of TimedeltaProperties.to_pytimedelta"),
- ("NDFrame.reindex_like", "keyword argument 'method' is deprecated"),
- # Docstring divides by zero to show behavior difference
- ("missing.mask_zero_div_zero", "divide by zero encountered"),
- (
- "pandas.core.generic.NDFrame.first",
- "first is deprecated and will be removed in a future version. "
- "Please create a mask and filter using `.loc` instead",
- ),
- (
- "Resampler.fillna",
- "DatetimeIndexResampler.fillna is deprecated",
- ),
- (
- "DataFrameGroupBy.fillna",
- "DataFrameGroupBy.fillna with 'method' is deprecated",
- ),
- ("read_parquet", "Passing a BlockManager to DataFrame is deprecated"),
- ]
- if is_doctest:
- for item in items:
- for path, message in ignored_doctest_warnings:
- ignore_doctest_warning(item, path, message)
- # Similar to "ci" config in
- # https://hypothesis.readthedocs.io/en/latest/reference/api.html#built-in-profiles
- hypothesis.settings.register_profile(
- "pandas_ci",
- database=None,
- deadline=None,
- max_examples=15,
- suppress_health_check=(
- hypothesis.HealthCheck.too_slow,
- hypothesis.HealthCheck.differing_executors,
- ),
- )
- hypothesis.settings.load_profile("pandas_ci")
- # Registering these strategies makes them globally available via st.from_type,
- # which is use for offsets in tests/tseries/offsets/test_offsets_properties.py
- for name in "MonthBegin MonthEnd BMonthBegin BMonthEnd".split():
- cls = getattr(pd.tseries.offsets, name)
- st.register_type_strategy(
- cls, st.builds(cls, n=st.integers(-99, 99), normalize=st.booleans())
- )
- for name in "YearBegin YearEnd BYearBegin BYearEnd".split():
- cls = getattr(pd.tseries.offsets, name)
- st.register_type_strategy(
- cls,
- st.builds(
- cls,
- n=st.integers(-5, 5),
- normalize=st.booleans(),
- month=st.integers(min_value=1, max_value=12),
- ),
- )
- for name in "QuarterBegin QuarterEnd BQuarterBegin BQuarterEnd".split():
- cls = getattr(pd.tseries.offsets, name)
- st.register_type_strategy(
- cls,
- st.builds(
- cls,
- n=st.integers(-24, 24),
- normalize=st.booleans(),
- startingMonth=st.integers(min_value=1, max_value=12),
- ),
- )
- # ----------------------------------------------------------------
- # Autouse fixtures
- # ----------------------------------------------------------------
- # https://github.com/pytest-dev/pytest/issues/11873
- # Would like to avoid autouse=True, but cannot as of pytest 8.0.0
- @pytest.fixture(autouse=True)
- def add_doctest_imports(doctest_namespace) -> None:
- """
- Make `np` and `pd` names available for doctests.
- """
- doctest_namespace["np"] = np
- doctest_namespace["pd"] = pd
- @pytest.fixture(autouse=True)
- def configure_tests() -> None:
- """
- Configure settings for all tests and test modules.
- """
- pd.set_option("chained_assignment", "raise")
- # ----------------------------------------------------------------
- # Common arguments
- # ----------------------------------------------------------------
- @pytest.fixture(params=[0, 1, "index", "columns"], ids=lambda x: f"axis={x!r}")
- def axis(request):
- """
- Fixture for returning the axis numbers of a DataFrame.
- """
- return request.param
- @pytest.fixture(params=[True, False])
- def observed(request):
- """
- Pass in the observed keyword to groupby for [True, False]
- This indicates whether categoricals should return values for
- values which are not in the grouper [False / None], or only values which
- appear in the grouper [True]. [None] is supported for future compatibility
- if we decide to change the default (and would need to warn if this
- parameter is not passed).
- """
- return request.param
- @pytest.fixture(params=[True, False, None])
- def ordered(request):
- """
- Boolean 'ordered' parameter for Categorical.
- """
- return request.param
- @pytest.fixture(params=[True, False])
- def dropna(request):
- """
- Boolean 'dropna' parameter.
- """
- return request.param
- @pytest.fixture(params=[True, False])
- def sort(request):
- """
- Boolean 'sort' parameter.
- """
- return request.param
- @pytest.fixture(params=[True, False])
- def skipna(request):
- """
- Boolean 'skipna' parameter.
- """
- return request.param
- @pytest.fixture(params=["first", "last", False])
- def keep(request):
- """
- Valid values for the 'keep' parameter used in
- .duplicated or .drop_duplicates
- """
- return request.param
- @pytest.fixture(params=["both", "neither", "left", "right"])
- def inclusive_endpoints_fixture(request):
- """
- Fixture for trying all interval 'inclusive' parameters.
- """
- return request.param
- @pytest.fixture(params=["left", "right", "both", "neither"])
- def closed(request):
- """
- Fixture for trying all interval closed parameters.
- """
- return request.param
- @pytest.fixture(params=["left", "right", "both", "neither"])
- def other_closed(request):
- """
- Secondary closed fixture to allow parametrizing over all pairs of closed.
- """
- return request.param
- @pytest.fixture(
- params=[
- None,
- "gzip",
- "bz2",
- "zip",
- "xz",
- "tar",
- pytest.param("zstd", marks=td.skip_if_no("zstandard")),
- ]
- )
- def compression(request):
- """
- Fixture for trying common compression types in compression tests.
- """
- return request.param
- @pytest.fixture(
- params=[
- "gzip",
- "bz2",
- "zip",
- "xz",
- "tar",
- pytest.param("zstd", marks=td.skip_if_no("zstandard")),
- ]
- )
- def compression_only(request):
- """
- Fixture for trying common compression types in compression tests excluding
- uncompressed case.
- """
- return request.param
- @pytest.fixture(params=[True, False])
- def writable(request):
- """
- Fixture that an array is writable.
- """
- return request.param
- @pytest.fixture(params=["inner", "outer", "left", "right"])
- def join_type(request):
- """
- Fixture for trying all types of join operations.
- """
- return request.param
- @pytest.fixture(params=["nlargest", "nsmallest"])
- def nselect_method(request):
- """
- Fixture for trying all nselect methods.
- """
- return request.param
- @pytest.fixture(params=[None, "ignore"])
- def na_action(request):
- """
- Fixture for 'na_action' argument in map.
- """
- return request.param
- @pytest.fixture(params=[True, False])
- def ascending(request):
- """
- Fixture for 'na_action' argument in sort_values/sort_index/rank.
- """
- return request.param
- @pytest.fixture(params=["average", "min", "max", "first", "dense"])
- def rank_method(request):
- """
- Fixture for 'rank' argument in rank.
- """
- return request.param
- @pytest.fixture(params=[True, False])
- def as_index(request):
- """
- Fixture for 'as_index' argument in groupby.
- """
- return request.param
- @pytest.fixture(params=[True, False])
- def cache(request):
- """
- Fixture for 'cache' argument in to_datetime.
- """
- return request.param
- @pytest.fixture(params=[True, False])
- def parallel(request):
- """
- Fixture for parallel keyword argument for numba.jit.
- """
- return request.param
- # Can parameterize nogil & nopython over True | False, but limiting per
- # https://github.com/pandas-dev/pandas/pull/41971#issuecomment-860607472
- @pytest.fixture(params=[False])
- def nogil(request):
- """
- Fixture for nogil keyword argument for numba.jit.
- """
- return request.param
- @pytest.fixture(params=[True])
- def nopython(request):
- """
- Fixture for nopython keyword argument for numba.jit.
- """
- return request.param
- # ----------------------------------------------------------------
- # Missing values & co.
- # ----------------------------------------------------------------
- @pytest.fixture(params=tm.NULL_OBJECTS, ids=lambda x: type(x).__name__)
- def nulls_fixture(request):
- """
- Fixture for each null type in pandas.
- """
- return request.param
- nulls_fixture2 = nulls_fixture # Generate cartesian product of nulls_fixture
- @pytest.fixture(params=[None, np.nan, pd.NaT])
- def unique_nulls_fixture(request):
- """
- Fixture for each null type in pandas, each null type exactly once.
- """
- return request.param
- # Generate cartesian product of unique_nulls_fixture:
- unique_nulls_fixture2 = unique_nulls_fixture
- @pytest.fixture(params=tm.NP_NAT_OBJECTS, ids=lambda x: type(x).__name__)
- def np_nat_fixture(request):
- """
- Fixture for each NaT type in numpy.
- """
- return request.param
- # Generate cartesian product of np_nat_fixture:
- np_nat_fixture2 = np_nat_fixture
- # ----------------------------------------------------------------
- # Classes
- # ----------------------------------------------------------------
- @pytest.fixture(params=[DataFrame, Series])
- def frame_or_series(request):
- """
- Fixture to parametrize over DataFrame and Series.
- """
- return request.param
- @pytest.fixture(params=[Index, Series], ids=["index", "series"])
- def index_or_series(request):
- """
- Fixture to parametrize over Index and Series, made necessary by a mypy
- bug, giving an error:
- List item 0 has incompatible type "Type[Series]"; expected "Type[PandasObject]"
- See GH#29725
- """
- return request.param
- @pytest.fixture(params=[Index, Series, pd.array], ids=["index", "series", "array"])
- def index_or_series_or_array(request):
- """
- Fixture to parametrize over Index, Series, and ExtensionArray
- """
- return request.param
- @pytest.fixture(params=[Index, Series, DataFrame, pd.array], ids=lambda x: x.__name__)
- def box_with_array(request):
- """
- Fixture to test behavior for Index, Series, DataFrame, and pandas Array
- classes
- """
- return request.param
- box_with_array2 = box_with_array
- @pytest.fixture
- def dict_subclass() -> type[dict]:
- """
- Fixture for a dictionary subclass.
- """
- class TestSubDict(dict):
- def __init__(self, *args, **kwargs) -> None:
- dict.__init__(self, *args, **kwargs)
- return TestSubDict
- @pytest.fixture
- def non_dict_mapping_subclass() -> type[abc.Mapping]:
- """
- Fixture for a non-mapping dictionary subclass.
- """
- class TestNonDictMapping(abc.Mapping):
- def __init__(self, underlying_dict) -> None:
- self._data = underlying_dict
- def __getitem__(self, key):
- return self._data.__getitem__(key)
- def __iter__(self) -> Iterator:
- return self._data.__iter__()
- def __len__(self) -> int:
- return self._data.__len__()
- return TestNonDictMapping
- # ----------------------------------------------------------------
- # Indices
- # ----------------------------------------------------------------
- @pytest.fixture
- def multiindex_year_month_day_dataframe_random_data():
- """
- DataFrame with 3 level MultiIndex (year, month, day) covering
- first 100 business days from 2000-01-01 with random data
- """
- tdf = DataFrame(
- np.random.default_rng(2).standard_normal((100, 4)),
- columns=Index(list("ABCD")),
- index=date_range("2000-01-01", periods=100, freq="B"),
- )
- ymd = tdf.groupby([lambda x: x.year, lambda x: x.month, lambda x: x.day]).sum()
- # use int64 Index, to make sure things work
- ymd.index = ymd.index.set_levels([lev.astype("i8") for lev in ymd.index.levels])
- ymd.index.set_names(["year", "month", "day"], inplace=True)
- return ymd
- @pytest.fixture
- def lexsorted_two_level_string_multiindex() -> MultiIndex:
- """
- 2-level MultiIndex, lexsorted, with string names.
- """
- return MultiIndex(
- levels=[["foo", "bar", "baz", "qux"], ["one", "two", "three"]],
- codes=[[0, 0, 0, 1, 1, 2, 2, 3, 3, 3], [0, 1, 2, 0, 1, 1, 2, 0, 1, 2]],
- names=["first", "second"],
- )
- @pytest.fixture
- def multiindex_dataframe_random_data(
- lexsorted_two_level_string_multiindex,
- ) -> DataFrame:
- """DataFrame with 2 level MultiIndex with random data"""
- index = lexsorted_two_level_string_multiindex
- return DataFrame(
- np.random.default_rng(2).standard_normal((10, 3)),
- index=index,
- columns=Index(["A", "B", "C"], name="exp"),
- )
- def _create_multiindex():
- """
- MultiIndex used to test the general functionality of this object
- """
- # See Also: tests.multi.conftest.idx
- major_axis = Index(["foo", "bar", "baz", "qux"])
- minor_axis = Index(["one", "two"])
- major_codes = np.array([0, 0, 1, 2, 3, 3])
- minor_codes = np.array([0, 1, 0, 1, 0, 1])
- index_names = ["first", "second"]
- return MultiIndex(
- levels=[major_axis, minor_axis],
- codes=[major_codes, minor_codes],
- names=index_names,
- verify_integrity=False,
- )
- def _create_mi_with_dt64tz_level():
- """
- MultiIndex with a level that is a tzaware DatetimeIndex.
- """
- # GH#8367 round trip with pickle
- return MultiIndex.from_product(
- [[1, 2], ["a", "b"], date_range("20130101", periods=3, tz="US/Eastern")],
- names=["one", "two", "three"],
- )
- indices_dict = {
- "object": Index([f"pandas_{i}" for i in range(10)], dtype=object),
- "string": Index([f"pandas_{i}" for i in range(10)], dtype="str"),
- "datetime": date_range("2020-01-01", periods=10),
- "datetime-tz": date_range("2020-01-01", periods=10, tz="US/Pacific"),
- "period": period_range("2020-01-01", periods=10, freq="D"),
- "timedelta": timedelta_range(start="1 day", periods=10, freq="D"),
- "range": RangeIndex(10),
- "int8": Index(np.arange(10), dtype="int8"),
- "int16": Index(np.arange(10), dtype="int16"),
- "int32": Index(np.arange(10), dtype="int32"),
- "int64": Index(np.arange(10), dtype="int64"),
- "uint8": Index(np.arange(10), dtype="uint8"),
- "uint16": Index(np.arange(10), dtype="uint16"),
- "uint32": Index(np.arange(10), dtype="uint32"),
- "uint64": Index(np.arange(10), dtype="uint64"),
- "float32": Index(np.arange(10), dtype="float32"),
- "float64": Index(np.arange(10), dtype="float64"),
- "bool-object": Index([True, False] * 5, dtype=object),
- "bool-dtype": Index([True, False] * 5, dtype=bool),
- "complex64": Index(
- np.arange(10, dtype="complex64") + 1.0j * np.arange(10, dtype="complex64")
- ),
- "complex128": Index(
- np.arange(10, dtype="complex128") + 1.0j * np.arange(10, dtype="complex128")
- ),
- "categorical": CategoricalIndex(list("abcd") * 2),
- "interval": IntervalIndex.from_breaks(np.linspace(0, 100, num=11)),
- "empty": Index([]),
- "tuples": MultiIndex.from_tuples(
- zip(["foo", "bar", "baz"], [1, 2, 3], strict=True)
- ),
- "mi-with-dt64tz-level": _create_mi_with_dt64tz_level(),
- "multi": _create_multiindex(),
- "repeats": Index([0, 0, 1, 1, 2, 2]),
- "nullable_int": Index(np.arange(10), dtype="Int64"),
- "nullable_uint": Index(np.arange(10), dtype="UInt16"),
- "nullable_float": Index(np.arange(10), dtype="Float32"),
- "nullable_bool": Index(np.arange(10).astype(bool), dtype="boolean"),
- "string-python": Index(
- pd.array([f"pandas_{i}" for i in range(10)], dtype="string[python]")
- ),
- }
- if has_pyarrow:
- idx = Index(pd.array([f"pandas_{i}" for i in range(10)], dtype="string[pyarrow]"))
- indices_dict["string-pyarrow"] = idx
- @pytest.fixture(params=indices_dict.keys())
- def index(request):
- """
- Fixture for many "simple" kinds of indices.
- These indices are unlikely to cover corner cases, e.g.
- - no names
- - no NaTs/NaNs
- - no values near implementation bounds
- - ...
- """
- # copy to avoid mutation, e.g. setting .name
- return indices_dict[request.param].copy(deep=False)
- @pytest.fixture(
- params=[
- key for key, value in indices_dict.items() if not isinstance(value, MultiIndex)
- ]
- )
- def index_flat(request):
- """
- index fixture, but excluding MultiIndex cases.
- """
- key = request.param
- return indices_dict[key].copy(deep=False)
- @pytest.fixture(
- params=[
- key
- for key, value in indices_dict.items()
- if not (
- key.startswith(("int", "uint", "float"))
- or key in ["range", "empty", "repeats", "bool-dtype"]
- )
- and not isinstance(value, MultiIndex)
- ]
- )
- def index_with_missing(request):
- """
- Fixture for indices with missing values.
- Integer-dtype and empty cases are excluded because they cannot hold missing
- values.
- MultiIndex is excluded because isna() is not defined for MultiIndex.
- """
- ind = indices_dict[request.param]
- if request.param in ["tuples", "mi-with-dt64tz-level", "multi"]:
- # For setting missing values in the top level of MultiIndex
- vals = ind.tolist()
- vals[0] = (None, *vals[0][1:])
- vals[-1] = (None, *vals[-1][1:])
- return MultiIndex.from_tuples(vals)
- else:
- vals = ind.values.copy()
- vals[0] = None
- vals[-1] = None
- return type(ind)(vals, copy=False)
- # ----------------------------------------------------------------
- # Series'
- # ----------------------------------------------------------------
- @pytest.fixture
- def string_series() -> Series:
- """
- Fixture for Series of floats with Index of unique strings
- """
- return Series(
- np.arange(30, dtype=np.float64) * 1.1,
- index=Index([f"i_{i}" for i in range(30)]),
- name="series",
- )
- @pytest.fixture
- def object_series() -> Series:
- """
- Fixture for Series of dtype object with Index of unique strings
- """
- data = [f"foo_{i}" for i in range(30)]
- index = Index([f"bar_{i}" for i in range(30)])
- return Series(data, index=index, name="objects", dtype=object)
- @pytest.fixture
- def datetime_series() -> Series:
- """
- Fixture for Series of floats with DatetimeIndex
- """
- return Series(
- np.random.default_rng(2).standard_normal(30),
- index=date_range("2000-01-01", periods=30, freq="B"),
- name="ts",
- )
- def _create_series(index):
- """Helper for the _series dict"""
- size = len(index)
- data = np.random.default_rng(2).standard_normal(size)
- return Series(data, index=index, name="a", copy=False)
- _series = {
- f"series-with-{index_id}-index": _create_series(index)
- for index_id, index in indices_dict.items()
- }
- @pytest.fixture
- def series_with_simple_index(index) -> Series:
- """
- Fixture for tests on series with changing types of indices.
- """
- return _create_series(index)
- _narrow_series = {
- f"{dtype.__name__}-series": Series(
- range(30), index=[f"i-{i}" for i in range(30)], name="a", dtype=dtype
- )
- for dtype in tm.NARROW_NP_DTYPES
- }
- _index_or_series_objs = {**indices_dict, **_series, **_narrow_series}
- @pytest.fixture(params=_index_or_series_objs.keys())
- def index_or_series_obj(request):
- """
- Fixture for tests on indexes, series and series with a narrow dtype
- copy to avoid mutation, e.g. setting .name
- """
- return _index_or_series_objs[request.param].copy(deep=False)
- _typ_objects_series = {
- f"{dtype.__name__}-series": Series(dtype) for dtype in tm.PYTHON_DATA_TYPES
- }
- _index_or_series_memory_objs = {
- **indices_dict,
- **_series,
- **_narrow_series,
- **_typ_objects_series,
- }
- @pytest.fixture(params=_index_or_series_memory_objs.keys())
- def index_or_series_memory_obj(request):
- """
- Fixture for tests on indexes, series, series with a narrow dtype and
- series with empty objects type
- copy to avoid mutation, e.g. setting .name
- """
- return _index_or_series_memory_objs[request.param].copy(deep=False)
- # ----------------------------------------------------------------
- # DataFrames
- # ----------------------------------------------------------------
- @pytest.fixture
- def int_frame() -> DataFrame:
- """
- Fixture for DataFrame of ints with index of unique strings
- Columns are ['A', 'B', 'C', 'D']
- """
- return DataFrame(
- np.ones((30, 4), dtype=np.int64),
- index=Index([f"foo_{i}" for i in range(30)]),
- columns=Index(list("ABCD")),
- )
- @pytest.fixture
- def float_frame() -> DataFrame:
- """
- Fixture for DataFrame of floats with index of unique strings
- Columns are ['A', 'B', 'C', 'D'].
- """
- return DataFrame(
- np.random.default_rng(2).standard_normal((30, 4)),
- index=Index([f"foo_{i}" for i in range(30)]),
- columns=Index(list("ABCD")),
- )
- @pytest.fixture
- def rand_series_with_duplicate_datetimeindex() -> Series:
- """
- Fixture for Series with a DatetimeIndex that has duplicates.
- """
- dates = [
- datetime(2000, 1, 2),
- datetime(2000, 1, 2),
- datetime(2000, 1, 2),
- datetime(2000, 1, 3),
- datetime(2000, 1, 3),
- datetime(2000, 1, 3),
- datetime(2000, 1, 4),
- datetime(2000, 1, 4),
- datetime(2000, 1, 4),
- datetime(2000, 1, 5),
- ]
- return Series(np.random.default_rng(2).standard_normal(len(dates)), index=dates)
- # ----------------------------------------------------------------
- # Scalars
- # ----------------------------------------------------------------
- @pytest.fixture(
- params=[
- (Interval(left=0, right=5), IntervalDtype("int64", "right")),
- (Interval(left=0.1, right=0.5), IntervalDtype("float64", "right")),
- (Period("2012-01", freq="M"), "period[M]"),
- (Period("2012-02-01", freq="D"), "period[D]"),
- (
- Timestamp("2011-01-01", tz="US/Eastern").as_unit("s"),
- DatetimeTZDtype(unit="s", tz="US/Eastern"),
- ),
- (Timedelta(seconds=500), "timedelta64[us]"),
- ]
- )
- def ea_scalar_and_dtype(request):
- """
- Fixture that tests each scalar and datetime type.
- """
- return request.param
- # ----------------------------------------------------------------
- # Operators & Operations
- # ----------------------------------------------------------------
- @pytest.fixture(params=tm.arithmetic_dunder_methods)
- def all_arithmetic_operators(request):
- """
- Fixture for dunder names for common arithmetic operations.
- """
- return request.param
- @pytest.fixture(
- params=[
- operator.add,
- ops.radd,
- operator.sub,
- ops.rsub,
- operator.mul,
- ops.rmul,
- operator.truediv,
- ops.rtruediv,
- operator.floordiv,
- ops.rfloordiv,
- operator.mod,
- ops.rmod,
- operator.pow,
- ops.rpow,
- operator.eq,
- operator.ne,
- operator.lt,
- operator.le,
- operator.gt,
- operator.ge,
- operator.and_,
- ops.rand_,
- operator.xor,
- ops.rxor,
- operator.or_,
- ops.ror_,
- ]
- )
- def all_binary_operators(request):
- """
- Fixture for operator and roperator arithmetic, comparison, and logical ops.
- """
- return request.param
- @pytest.fixture(
- params=[
- operator.add,
- ops.radd,
- operator.sub,
- ops.rsub,
- operator.mul,
- ops.rmul,
- operator.truediv,
- ops.rtruediv,
- operator.floordiv,
- ops.rfloordiv,
- operator.mod,
- ops.rmod,
- operator.pow,
- ops.rpow,
- ]
- )
- def all_arithmetic_functions(request):
- """
- Fixture for operator and roperator arithmetic functions.
- Notes
- -----
- This includes divmod and rdivmod, whereas all_arithmetic_operators
- does not.
- """
- return request.param
- _all_numeric_reductions = [
- "count",
- "sum",
- "max",
- "min",
- "mean",
- "prod",
- "std",
- "var",
- "median",
- "kurt",
- "skew",
- "sem",
- ]
- @pytest.fixture(params=_all_numeric_reductions)
- def all_numeric_reductions(request):
- """
- Fixture for numeric reduction names.
- """
- return request.param
- _all_boolean_reductions = ["all", "any"]
- @pytest.fixture(params=_all_boolean_reductions)
- def all_boolean_reductions(request):
- """
- Fixture for boolean reduction names.
- """
- return request.param
- _all_reductions = _all_numeric_reductions + _all_boolean_reductions
- @pytest.fixture(params=_all_reductions)
- def all_reductions(request):
- """
- Fixture for all (boolean + numeric) reduction names.
- """
- return request.param
- @pytest.fixture(
- params=[
- operator.eq,
- operator.ne,
- operator.gt,
- operator.ge,
- operator.lt,
- operator.le,
- ]
- )
- def comparison_op(request):
- """
- Fixture for operator module comparison functions.
- """
- return request.param
- @pytest.fixture(params=["__le__", "__lt__", "__ge__", "__gt__"])
- def compare_operators_no_eq_ne(request):
- """
- Fixture for dunder names for compare operations except == and !=
- * >=
- * >
- * <
- * <=
- """
- return request.param
- @pytest.fixture(
- params=["__and__", "__rand__", "__or__", "__ror__", "__xor__", "__rxor__"]
- )
- def all_logical_operators(request):
- """
- Fixture for dunder names for common logical operations
- * |
- * &
- * ^
- """
- return request.param
- _all_numeric_accumulations = ["cumsum", "cumprod", "cummin", "cummax"]
- @pytest.fixture(params=_all_numeric_accumulations)
- def all_numeric_accumulations(request):
- """
- Fixture for numeric accumulation names
- """
- return request.param
- # ----------------------------------------------------------------
- # Data sets/files
- # ----------------------------------------------------------------
- @pytest.fixture
- def strict_data_files(pytestconfig):
- """
- Returns the configuration for the test setting `--no-strict-data-files`.
- """
- return pytestconfig.getoption("--no-strict-data-files")
- @pytest.fixture
- def datapath(strict_data_files: str) -> Callable[..., str]:
- """
- Get the path to a data file.
- Parameters
- ----------
- path : str
- Path to the file, relative to ``pandas/tests/``
- Returns
- -------
- path including ``pandas/tests``.
- Raises
- ------
- ValueError
- If the path doesn't exist and the --no-strict-data-files option is not set.
- """
- BASE_PATH = os.path.join(os.path.dirname(__file__), "tests")
- def deco(*args):
- path = os.path.join(BASE_PATH, *args)
- if not os.path.exists(path):
- if strict_data_files:
- raise ValueError(
- f"Could not find file {path} and --no-strict-data-files is not set."
- )
- pytest.skip(f"Could not find {path}.")
- return path
- return deco
- # ----------------------------------------------------------------
- # Time zones
- # ----------------------------------------------------------------
- TIMEZONES = [
- None,
- "UTC",
- "US/Eastern",
- "Asia/Tokyo",
- "dateutil/US/Pacific",
- "dateutil/Asia/Singapore",
- "+01:15",
- "-02:15",
- "UTC+01:15",
- "UTC-02:15",
- tzutc(),
- tzlocal(),
- timezone.utc,
- timezone(timedelta(hours=1)),
- timezone(timedelta(hours=-1), name="foo"),
- ]
- if pytz is not None:
- TIMEZONES.extend(
- (
- pytz.FixedOffset(300),
- pytz.FixedOffset(0),
- pytz.FixedOffset(-300),
- pytz.timezone("US/Pacific"),
- pytz.timezone("UTC"),
- )
- )
- TIMEZONE_IDS = [repr(i) for i in TIMEZONES]
- @td.parametrize_fixture_doc(str(TIMEZONE_IDS))
- @pytest.fixture(params=TIMEZONES, ids=TIMEZONE_IDS)
- def tz_naive_fixture(request):
- """
- Fixture for trying timezones including default (None): {0}
- """
- return request.param
- @td.parametrize_fixture_doc(str(TIMEZONE_IDS[1:]))
- @pytest.fixture(params=TIMEZONES[1:], ids=TIMEZONE_IDS[1:])
- def tz_aware_fixture(request):
- """
- Fixture for trying explicit timezones: {0}
- """
- return request.param
- _UTCS = ["utc", "dateutil/UTC", tzutc(), timezone.utc]
- if pytz is not None:
- _UTCS.append(pytz.utc)
- @pytest.fixture(params=_UTCS)
- def utc_fixture(request):
- """
- Fixture to provide variants of UTC timezone strings and tzinfo objects.
- """
- return request.param
- utc_fixture2 = utc_fixture
- @pytest.fixture(params=["s", "ms", "us", "ns"])
- def unit(request):
- """
- datetime64 units we support.
- """
- return request.param
- unit2 = unit
- # ----------------------------------------------------------------
- # Dtypes
- # ----------------------------------------------------------------
- @pytest.fixture(params=tm.STRING_DTYPES)
- def string_dtype(request):
- """
- Parametrized fixture for string dtypes.
- * str
- * 'str'
- * 'U'
- """
- return request.param
- @pytest.fixture(
- params=[
- ("python", pd.NA),
- pytest.param(("pyarrow", pd.NA), marks=td.skip_if_no("pyarrow")),
- pytest.param(("pyarrow", np.nan), marks=td.skip_if_no("pyarrow")),
- ("python", np.nan),
- ],
- ids=[
- "string=string[python]",
- "string=string[pyarrow]",
- "string=str[pyarrow]",
- "string=str[python]",
- ],
- )
- def string_dtype_no_object(request):
- """
- Parametrized fixture for string dtypes.
- * 'string[python]' (NA variant)
- * 'string[pyarrow]' (NA variant)
- * 'str' (NaN variant, with pyarrow)
- * 'str' (NaN variant, without pyarrow)
- """
- # need to instantiate the StringDtype here instead of in the params
- # to avoid importing pyarrow during test collection
- storage, na_value = request.param
- return pd.StringDtype(storage, na_value)
- @pytest.fixture(
- params=[
- "string[python]",
- pytest.param("string[pyarrow]", marks=td.skip_if_no("pyarrow")),
- ]
- )
- def nullable_string_dtype(request):
- """
- Parametrized fixture for string dtypes.
- * 'string[python]'
- * 'string[pyarrow]'
- """
- return request.param
- @pytest.fixture(
- params=[
- pytest.param(("pyarrow", np.nan), marks=td.skip_if_no("pyarrow")),
- pytest.param(("pyarrow", pd.NA), marks=td.skip_if_no("pyarrow")),
- ]
- )
- def pyarrow_string_dtype(request):
- """
- Parametrized fixture for string dtypes backed by Pyarrow.
- * 'str[pyarrow]'
- * 'string[pyarrow]'
- """
- return pd.StringDtype(*request.param)
- @pytest.fixture(
- params=[
- "python",
- pytest.param("pyarrow", marks=td.skip_if_no("pyarrow")),
- ]
- )
- def string_storage(request):
- """
- Parametrized fixture for pd.options.mode.string_storage.
- * 'python'
- * 'pyarrow'
- """
- return request.param
- @pytest.fixture(
- params=[
- ("python", pd.NA),
- pytest.param(("pyarrow", pd.NA), marks=td.skip_if_no("pyarrow")),
- pytest.param(("pyarrow", np.nan), marks=td.skip_if_no("pyarrow")),
- ("python", np.nan),
- ],
- ids=[
- "string=string[python]",
- "string=string[pyarrow]",
- "string=str[pyarrow]",
- "string=str[python]",
- ],
- )
- def string_dtype_arguments(request):
- """
- Parametrized fixture for StringDtype storage and na_value.
- * 'python' + pd.NA
- * 'pyarrow' + pd.NA
- * 'pyarrow' + np.nan
- """
- return request.param
- @pytest.fixture(
- params=[
- "numpy_nullable",
- pytest.param("pyarrow", marks=td.skip_if_no("pyarrow")),
- ]
- )
- def dtype_backend(request):
- """
- Parametrized fixture for pd.options.mode.string_storage.
- * 'python'
- * 'pyarrow'
- """
- return request.param
- # Alias so we can test with cartesian product of string_storage
- string_storage2 = string_storage
- string_dtype_arguments2 = string_dtype_arguments
- @pytest.fixture(params=tm.BYTES_DTYPES)
- def bytes_dtype(request):
- """
- Parametrized fixture for bytes dtypes.
- * bytes
- * 'bytes'
- """
- return request.param
- @pytest.fixture(params=tm.OBJECT_DTYPES)
- def object_dtype(request):
- """
- Parametrized fixture for object dtypes.
- * object
- * 'object'
- """
- return request.param
- @pytest.fixture(
- params=[
- np.dtype("object"),
- ("python", pd.NA),
- pytest.param(("pyarrow", pd.NA), marks=td.skip_if_no("pyarrow")),
- pytest.param(("pyarrow", np.nan), marks=td.skip_if_no("pyarrow")),
- ("python", np.nan),
- ],
- ids=[
- "string=object",
- "string=string[python]",
- "string=string[pyarrow]",
- "string=str[pyarrow]",
- "string=str[python]",
- ],
- )
- def any_string_dtype(request):
- """
- Parametrized fixture for string dtypes.
- * 'object'
- * 'string[python]' (NA variant)
- * 'string[pyarrow]' (NA variant)
- * 'str' (NaN variant, with pyarrow)
- * 'str' (NaN variant, without pyarrow)
- """
- if isinstance(request.param, np.dtype):
- return request.param
- else:
- # need to instantiate the StringDtype here instead of in the params
- # to avoid importing pyarrow during test collection
- storage, na_value = request.param
- return pd.StringDtype(storage, na_value)
- any_string_dtype2 = any_string_dtype
- @pytest.fixture(params=tm.DATETIME64_DTYPES)
- def datetime64_dtype(request):
- """
- Parametrized fixture for datetime64 dtypes.
- * 'datetime64[ns]'
- * 'M8[ns]'
- """
- return request.param
- @pytest.fixture(params=tm.TIMEDELTA64_DTYPES)
- def timedelta64_dtype(request):
- """
- Parametrized fixture for timedelta64 dtypes.
- * 'timedelta64[ns]'
- * 'm8[ns]'
- """
- return request.param
- @pytest.fixture
- def fixed_now_ts() -> Timestamp:
- """
- Fixture emits fixed Timestamp.now()
- """
- return Timestamp( # pyright: ignore[reportReturnType]
- year=2021, month=1, day=1, hour=12, minute=4, second=13, microsecond=22
- )
- @pytest.fixture(params=tm.FLOAT_NUMPY_DTYPES)
- def float_numpy_dtype(request):
- """
- Parameterized fixture for float dtypes.
- * float
- * 'float32'
- * 'float64'
- """
- return request.param
- @pytest.fixture(params=tm.FLOAT_EA_DTYPES)
- def float_ea_dtype(request):
- """
- Parameterized fixture for float dtypes.
- * 'Float32'
- * 'Float64'
- """
- return request.param
- @pytest.fixture(params=tm.ALL_FLOAT_DTYPES)
- def any_float_dtype(request):
- """
- Parameterized fixture for float dtypes.
- * float
- * 'float32'
- * 'float64'
- * 'Float32'
- * 'Float64'
- """
- return request.param
- @pytest.fixture(params=tm.COMPLEX_DTYPES)
- def complex_dtype(request):
- """
- Parameterized fixture for complex dtypes.
- * complex
- * 'complex64'
- * 'complex128'
- """
- return request.param
- @pytest.fixture(params=tm.COMPLEX_FLOAT_DTYPES)
- def complex_or_float_dtype(request):
- """
- Parameterized fixture for complex and numpy float dtypes.
- * complex
- * 'complex64'
- * 'complex128'
- * float
- * 'float32'
- * 'float64'
- """
- return request.param
- @pytest.fixture(params=tm.SIGNED_INT_NUMPY_DTYPES)
- def any_signed_int_numpy_dtype(request):
- """
- Parameterized fixture for signed integer dtypes.
- * int
- * 'int8'
- * 'int16'
- * 'int32'
- * 'int64'
- """
- return request.param
- @pytest.fixture(params=tm.UNSIGNED_INT_NUMPY_DTYPES)
- def any_unsigned_int_numpy_dtype(request):
- """
- Parameterized fixture for unsigned integer dtypes.
- * 'uint8'
- * 'uint16'
- * 'uint32'
- * 'uint64'
- """
- return request.param
- @pytest.fixture(params=tm.ALL_INT_NUMPY_DTYPES)
- def any_int_numpy_dtype(request):
- """
- Parameterized fixture for any integer dtype.
- * int
- * 'int8'
- * 'uint8'
- * 'int16'
- * 'uint16'
- * 'int32'
- * 'uint32'
- * 'int64'
- * 'uint64'
- """
- return request.param
- @pytest.fixture(params=tm.ALL_INT_EA_DTYPES)
- def any_int_ea_dtype(request):
- """
- Parameterized fixture for any nullable integer dtype.
- * 'UInt8'
- * 'Int8'
- * 'UInt16'
- * 'Int16'
- * 'UInt32'
- * 'Int32'
- * 'UInt64'
- * 'Int64'
- """
- return request.param
- @pytest.fixture(params=tm.ALL_INT_DTYPES)
- def any_int_dtype(request):
- """
- Parameterized fixture for any nullable integer dtype.
- * int
- * 'int8'
- * 'uint8'
- * 'int16'
- * 'uint16'
- * 'int32'
- * 'uint32'
- * 'int64'
- * 'uint64'
- * 'UInt8'
- * 'Int8'
- * 'UInt16'
- * 'Int16'
- * 'UInt32'
- * 'Int32'
- * 'UInt64'
- * 'Int64'
- """
- return request.param
- @pytest.fixture(params=tm.ALL_INT_EA_DTYPES + tm.FLOAT_EA_DTYPES)
- def any_numeric_ea_dtype(request):
- """
- Parameterized fixture for any nullable integer dtype and
- any float ea dtypes.
- * 'UInt8'
- * 'Int8'
- * 'UInt16'
- * 'Int16'
- * 'UInt32'
- * 'Int32'
- * 'UInt64'
- * 'Int64'
- * 'Float32'
- * 'Float64'
- """
- return request.param
- # Unsupported operand types for + ("List[Union[str, ExtensionDtype, dtype[Any],
- # Type[object]]]" and "List[str]")
- @pytest.fixture(
- params=tm.ALL_INT_EA_DTYPES
- + tm.FLOAT_EA_DTYPES
- + tm.ALL_INT_PYARROW_DTYPES_STR_REPR
- + tm.FLOAT_PYARROW_DTYPES_STR_REPR # type: ignore[operator]
- )
- def any_numeric_ea_and_arrow_dtype(request):
- """
- Parameterized fixture for any nullable integer dtype and
- any float ea dtypes.
- * 'UInt8'
- * 'Int8'
- * 'UInt16'
- * 'Int16'
- * 'UInt32'
- * 'Int32'
- * 'UInt64'
- * 'Int64'
- * 'Float32'
- * 'Float64'
- * 'uint8[pyarrow]'
- * 'int8[pyarrow]'
- * 'uint16[pyarrow]'
- * 'int16[pyarrow]'
- * 'uint32[pyarrow]'
- * 'int32[pyarrow]'
- * 'uint64[pyarrow]'
- * 'int64[pyarrow]'
- * 'float32[pyarrow]'
- * 'float64[pyarrow]'
- """
- return request.param
- @pytest.fixture(params=tm.SIGNED_INT_EA_DTYPES)
- def any_signed_int_ea_dtype(request):
- """
- Parameterized fixture for any signed nullable integer dtype.
- * 'Int8'
- * 'Int16'
- * 'Int32'
- * 'Int64'
- """
- return request.param
- @pytest.fixture(params=tm.ALL_REAL_NUMPY_DTYPES)
- def any_real_numpy_dtype(request):
- """
- Parameterized fixture for any (purely) real numeric dtype.
- * int
- * 'int8'
- * 'uint8'
- * 'int16'
- * 'uint16'
- * 'int32'
- * 'uint32'
- * 'int64'
- * 'uint64'
- * float
- * 'float32'
- * 'float64'
- """
- return request.param
- @pytest.fixture(params=tm.ALL_REAL_DTYPES)
- def any_real_numeric_dtype(request):
- """
- Parameterized fixture for any (purely) real numeric dtype.
- * int
- * 'int8'
- * 'uint8'
- * 'int16'
- * 'uint16'
- * 'int32'
- * 'uint32'
- * 'int64'
- * 'uint64'
- * float
- * 'float32'
- * 'float64'
- and associated ea dtypes.
- """
- return request.param
- @pytest.fixture(params=tm.ALL_NUMPY_DTYPES)
- def any_numpy_dtype(request):
- """
- Parameterized fixture for all numpy dtypes.
- * bool
- * 'bool'
- * int
- * 'int8'
- * 'uint8'
- * 'int16'
- * 'uint16'
- * 'int32'
- * 'uint32'
- * 'int64'
- * 'uint64'
- * float
- * 'float32'
- * 'float64'
- * complex
- * 'complex64'
- * 'complex128'
- * str
- * 'str'
- * 'U'
- * bytes
- * 'bytes'
- * 'datetime64[ns]'
- * 'M8[ns]'
- * 'timedelta64[ns]'
- * 'm8[ns]'
- * object
- * 'object'
- """
- return request.param
- @pytest.fixture(params=tm.ALL_REAL_NULLABLE_DTYPES)
- def any_real_nullable_dtype(request):
- """
- Parameterized fixture for all real dtypes that can hold NA.
- * float
- * 'float32'
- * 'float64'
- * 'Float32'
- * 'Float64'
- * 'UInt8'
- * 'UInt16'
- * 'UInt32'
- * 'UInt64'
- * 'Int8'
- * 'Int16'
- * 'Int32'
- * 'Int64'
- * 'uint8[pyarrow]'
- * 'uint16[pyarrow]'
- * 'uint32[pyarrow]'
- * 'uint64[pyarrow]'
- * 'int8[pyarrow]'
- * 'int16[pyarrow]'
- * 'int32[pyarrow]'
- * 'int64[pyarrow]'
- * 'float[pyarrow]'
- * 'double[pyarrow]'
- """
- return request.param
- @pytest.fixture(params=tm.ALL_NUMERIC_DTYPES)
- def any_numeric_dtype(request):
- """
- Parameterized fixture for all numeric dtypes.
- * int
- * 'int8'
- * 'uint8'
- * 'int16'
- * 'uint16'
- * 'int32'
- * 'uint32'
- * 'int64'
- * 'uint64'
- * float
- * 'float32'
- * 'float64'
- * complex
- * 'complex64'
- * 'complex128'
- * 'UInt8'
- * 'Int8'
- * 'UInt16'
- * 'Int16'
- * 'UInt32'
- * 'Int32'
- * 'UInt64'
- * 'Int64'
- * 'Float32'
- * 'Float64'
- """
- return request.param
- # categoricals are handled separately
- _any_skipna_inferred_dtype = [
- ("string", ["a", np.nan, "c"]),
- ("string", ["a", pd.NA, "c"]),
- ("mixed", ["a", pd.NaT, "c"]), # pd.NaT not considered valid by is_string_array
- ("bytes", [b"a", np.nan, b"c"]),
- ("empty", [np.nan, np.nan, np.nan]),
- ("empty", []),
- ("mixed-integer", ["a", np.nan, 2]),
- ("mixed", ["a", np.nan, 2.0]),
- ("floating", [1.0, np.nan, 2.0]),
- ("integer", [1, np.nan, 2]),
- ("mixed-integer-float", [1, np.nan, 2.0]),
- ("decimal", [Decimal(1), np.nan, Decimal(2)]),
- ("boolean", [True, np.nan, False]),
- ("boolean", [True, pd.NA, False]),
- ("datetime64", [np.datetime64("2013-01-01"), np.nan, np.datetime64("2018-01-01")]),
- ("datetime", [Timestamp("20130101"), np.nan, Timestamp("20180101")]),
- ("date", [date(2013, 1, 1), np.nan, date(2018, 1, 1)]),
- ("complex", [1 + 1j, np.nan, 2 + 2j]),
- # The following dtype is commented out due to GH 23554
- # ('timedelta64', [np.timedelta64(1, 'D'),
- # np.nan, np.timedelta64(2, 'D')]),
- ("timedelta", [timedelta(1), np.nan, timedelta(2)]),
- ("time", [time(1), np.nan, time(2)]),
- ("period", [Period(2013), pd.NaT, Period(2018)]),
- ("interval", [Interval(0, 1), np.nan, Interval(0, 2)]),
- ]
- ids = [
- pair[0] for pair in _any_skipna_inferred_dtype
- ] # use inferred type as fixture-id
- @pytest.fixture(params=_any_skipna_inferred_dtype, ids=ids)
- def any_skipna_inferred_dtype(request):
- """
- Fixture for all inferred dtypes from _libs.lib.infer_dtype
- The covered (inferred) types are:
- * 'string'
- * 'empty'
- * 'bytes'
- * 'mixed'
- * 'mixed-integer'
- * 'mixed-integer-float'
- * 'floating'
- * 'integer'
- * 'decimal'
- * 'boolean'
- * 'datetime64'
- * 'datetime'
- * 'date'
- * 'timedelta'
- * 'time'
- * 'period'
- * 'interval'
- Returns
- -------
- inferred_dtype : str
- The string for the inferred dtype from _libs.lib.infer_dtype
- values : np.ndarray
- An array of object dtype that will be inferred to have
- `inferred_dtype`
- Examples
- --------
- >>> from pandas._libs import lib
- >>>
- >>> def test_something(any_skipna_inferred_dtype):
- ... inferred_dtype, values = any_skipna_inferred_dtype
- ... # will pass
- ... assert lib.infer_dtype(values, skipna=True) == inferred_dtype
- """
- inferred_dtype, values = request.param
- values = np.array(values, dtype=object) # object dtype to avoid casting
- # correctness of inference tested in tests/dtypes/test_inference.py
- return inferred_dtype, values
- # ----------------------------------------------------------------
- # Misc
- # ----------------------------------------------------------------
- @pytest.fixture
- def ip():
- """
- Get an instance of IPython.InteractiveShell.
- Will raise a skip if IPython is not installed.
- """
- pytest.importorskip("IPython", minversion="6.0.0")
- from IPython.core.interactiveshell import InteractiveShell
- # GH#35711 make sure sqlite history file handle is not leaked
- from traitlets.config import Config # isort:skip
- c = Config()
- c.HistoryManager.hist_file = ":memory:"
- return InteractiveShell(config=c)
- @pytest.fixture
- def mpl_cleanup():
- """
- Ensure Matplotlib is cleaned up around a test.
- Before a test is run:
- 1) Set the backend to "template" to avoid requiring a GUI.
- After a test is run:
- 1) Reset units registry
- 2) Reset rc_context
- 3) Close all figures
- See matplotlib/testing/decorators.py#L24.
- """
- mpl = pytest.importorskip("matplotlib")
- mpl_units = pytest.importorskip("matplotlib.units")
- plt = pytest.importorskip("matplotlib.pyplot")
- orig_units_registry = mpl_units.registry.copy()
- try:
- with mpl.rc_context():
- mpl.use("template")
- yield
- finally:
- mpl_units.registry.clear()
- mpl_units.registry.update(orig_units_registry)
- plt.close("all")
- # https://matplotlib.org/stable/users/prev_whats_new/whats_new_3.6.0.html#garbage-collection-is-no-longer-run-on-figure-close # noqa: E501
- gc.collect(1)
- @pytest.fixture(
- params=[
- getattr(pd.offsets, o)
- for o in pd.offsets.__all__
- if issubclass(getattr(pd.offsets, o), pd.offsets.Tick) and o != "Tick"
- ]
- )
- def tick_classes(request):
- """
- Fixture for Tick based datetime offsets available for a time series.
- """
- return request.param
- @pytest.fixture(params=[None, lambda x: x])
- def sort_by_key(request):
- """
- Simple fixture for testing keys in sorting methods.
- Tests None (no key) and the identity key.
- """
- return request.param
- @pytest.fixture(
- params=[
- ("foo", None, None),
- ("Egon", "Venkman", None),
- ("NCC1701D", "NCC1701D", "NCC1701D"),
- # possibly-matching NAs
- (np.nan, np.nan, np.nan),
- (np.nan, pd.NaT, None),
- (np.nan, pd.NA, None),
- (pd.NA, pd.NA, pd.NA),
- ]
- )
- def names(request) -> tuple[Hashable, Hashable, Hashable]:
- """
- A 3-tuple of names, the first two for operands, the last for a result.
- """
- return request.param
- @pytest.fixture(params=[tm.setitem, tm.loc, tm.iloc])
- def indexer_sli(request):
- """
- Parametrize over __setitem__, loc.__setitem__, iloc.__setitem__
- """
- return request.param
- @pytest.fixture(params=[tm.loc, tm.iloc])
- def indexer_li(request):
- """
- Parametrize over loc.__getitem__, iloc.__getitem__
- """
- return request.param
- @pytest.fixture(params=[tm.setitem, tm.iloc])
- def indexer_si(request):
- """
- Parametrize over __setitem__, iloc.__setitem__
- """
- return request.param
- @pytest.fixture(params=[tm.setitem, tm.loc])
- def indexer_sl(request):
- """
- Parametrize over __setitem__, loc.__setitem__
- """
- return request.param
- @pytest.fixture(params=[tm.at, tm.loc])
- def indexer_al(request):
- """
- Parametrize over at.__setitem__, loc.__setitem__
- """
- return request.param
- @pytest.fixture(params=[tm.iat, tm.iloc])
- def indexer_ial(request):
- """
- Parametrize over iat.__setitem__, iloc.__setitem__
- """
- return request.param
- @pytest.fixture(params=[True, False])
- def performance_warning(request) -> Iterator[bool | type[Warning]]:
- """
- Fixture to check if performance warnings are enabled. Either produces
- ``PerformanceWarning`` if they are enabled, otherwise ``False``.
- """
- with pd.option_context("mode.performance_warnings", request.param):
- yield pd.errors.PerformanceWarning if request.param else False
- @pytest.fixture
- def using_infer_string() -> bool:
- """
- Fixture to check if infer string option is enabled.
- """
- return pd.options.future.infer_string is True
- @pytest.fixture
- def using_python_scalars() -> bool:
- return pd.options.future.python_scalars is True
- _warsaws: list[Any] = ["Europe/Warsaw", "dateutil/Europe/Warsaw"]
- if pytz is not None:
- _warsaws.append(pytz.timezone("Europe/Warsaw"))
- @pytest.fixture(params=_warsaws)
- def warsaw(request) -> str:
- """
- tzinfo for Europe/Warsaw using pytz, dateutil, or zoneinfo.
- """
- return request.param
- @pytest.fixture
- def temp_file(tmp_path):
- """
- Generate a unique file for testing use. See link for removal policy.
- https://docs.pytest.org/en/7.1.x/how-to/tmp_path.html#the-default-base-temporary-directory
- """
- file_path = tmp_path / str(uuid.uuid4())
- file_path.touch()
- return file_path
- @pytest.fixture(scope="session")
- def monkeysession():
- with pytest.MonkeyPatch.context() as mp:
- yield mp
- @pytest.fixture(params=[True, False])
- def using_nan_is_na(request):
- opt = request.param
- with pd.option_context("future.distinguish_nan_and_na", not opt):
- yield opt
|