diff --git a/conftest.py b/conftest.py new file mode 100644 index 000000000..9dc46f43b --- /dev/null +++ b/conftest.py @@ -0,0 +1,36 @@ +import gc + +import pytest + + +@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 + gc.collect(1) diff --git a/pandas-stubs/core/indexes/datetimelike.pyi b/pandas-stubs/core/indexes/datetimelike.pyi index caa10d36d..fb27fae21 100644 --- a/pandas-stubs/core/indexes/datetimelike.pyi +++ b/pandas-stubs/core/indexes/datetimelike.pyi @@ -19,7 +19,7 @@ class DatetimeIndexOpsMixin(ExtensionIndex[S1]): def argmin(self, axis=..., skipna: bool = ..., *args, **kwargs): ... def max(self, axis=..., skipna: bool = ..., *args, **kwargs): ... def argmax(self, axis=..., skipna: bool = ..., *args, **kwargs): ... - def __rsub__( # type: ignore[override] + def __rsub__( # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] self, other: DatetimeIndexOpsMixin ) -> TimedeltaIndex: ... diff --git a/pandas-stubs/core/series.pyi b/pandas-stubs/core/series.pyi index edfafe6c1..209237746 100644 --- a/pandas-stubs/core/series.pyi +++ b/pandas-stubs/core/series.pyi @@ -1506,21 +1506,23 @@ class Series(IndexOpsMixin[S1], NDFrame): self, other: bool | list[bool] | list[int] | np_ndarray_bool | Series[bool] ) -> Series[bool]: ... @overload - def __and__(self, other: int | np_ndarray_anyint | Series[int]) -> Series[int]: ... + def __and__( # pyright: ignore[reportIncompatibleMethodOverride] + self, other: int | np_ndarray_anyint | Series[int] + ) -> Series[int]: ... # def __array__(self, dtype: Optional[_bool] = ...) -> _np_ndarray def __div__(self, other: num | _ListLike | Series[S1]) -> Series[S1]: ... def __eq__(self, other: object) -> Series[_bool]: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] def __floordiv__(self, other: num | _ListLike | Series[S1]) -> Series[int]: ... - def __ge__( # type: ignore[override] + def __ge__( # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] self, other: S1 | _ListLike | Series[S1] | datetime | timedelta | date ) -> Series[_bool]: ... - def __gt__( # type: ignore[override] + def __gt__( # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] self, other: S1 | _ListLike | Series[S1] | datetime | timedelta | date ) -> Series[_bool]: ... - def __le__( # type: ignore[override] + def __le__( # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] self, other: S1 | _ListLike | Series[S1] | datetime | timedelta | date ) -> Series[_bool]: ... - def __lt__( # type: ignore[override] + def __lt__( # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] self, other: S1 | _ListLike | Series[S1] | datetime | timedelta | date ) -> Series[_bool]: ... @overload @@ -1538,7 +1540,9 @@ class Series(IndexOpsMixin[S1], NDFrame): self, other: bool | list[bool] | list[int] | np_ndarray_bool | Series[bool] ) -> Series[bool]: ... @overload - def __or__(self, other: int | np_ndarray_anyint | Series[int]) -> Series[int]: ... + def __or__( # pyright: ignore[reportIncompatibleMethodOverride] + self, other: int | np_ndarray_anyint | Series[int] + ) -> Series[int]: ... @overload def __radd__(self, other: S1 | Series[S1]) -> Self: ... @overload @@ -1549,7 +1553,7 @@ class Series(IndexOpsMixin[S1], NDFrame): self, other: bool | list[bool] | list[int] | np_ndarray_bool | Series[bool] ) -> Series[bool]: ... @overload - def __rand__(self, other: int | np_ndarray_anyint | Series[int]) -> Series[int]: ... # type: ignore[misc] + def __rand__(self, other: int | np_ndarray_anyint | Series[int]) -> Series[int]: ... # type: ignore[misc] # pyright: ignore[reportIncompatibleMethodOverride] def __rdiv__(self, other: num | _ListLike | Series[S1]) -> Series[S1]: ... def __rdivmod__(self, other: num | _ListLike | Series[S1]) -> Series[S1]: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] def __rfloordiv__(self, other: num | _ListLike | Series[S1]) -> Series[S1]: ... @@ -1568,7 +1572,7 @@ class Series(IndexOpsMixin[S1], NDFrame): self, other: bool | list[bool] | list[int] | np_ndarray_bool | Series[bool] ) -> Series[bool]: ... @overload - def __ror__(self, other: int | np_ndarray_anyint | Series[int]) -> Series[int]: ... # type: ignore[misc] + def __ror__(self, other: int | np_ndarray_anyint | Series[int]) -> Series[int]: ... # type: ignore[misc] # pyright: ignore[reportIncompatibleMethodOverride] def __rsub__(self, other: num | _ListLike | Series[S1]) -> Series: ... def __rtruediv__(self, other: num | _ListLike | Series[S1]) -> Series: ... # ignore needed for mypy as we want different results based on the arguments @@ -1577,7 +1581,7 @@ class Series(IndexOpsMixin[S1], NDFrame): self, other: bool | list[bool] | list[int] | np_ndarray_bool | Series[bool] ) -> Series[bool]: ... @overload - def __rxor__(self, other: int | np_ndarray_anyint | Series[int]) -> Series[int]: ... # type: ignore[misc] + def __rxor__(self, other: int | np_ndarray_anyint | Series[int]) -> Series[int]: ... # type: ignore[misc] # pyright: ignore[reportIncompatibleMethodOverride] @overload def __sub__( self: Series[Timestamp], @@ -1601,7 +1605,9 @@ class Series(IndexOpsMixin[S1], NDFrame): self, other: bool | list[bool] | list[int] | np_ndarray_bool | Series[bool] ) -> Series[bool]: ... @overload - def __xor__(self, other: int | np_ndarray_anyint | Series[int]) -> Series[int]: ... + def __xor__( # pyright: ignore[reportIncompatibleMethodOverride] + self, other: int | np_ndarray_anyint | Series[int] + ) -> Series[int]: ... def __invert__(self) -> Series[bool]: ... # properties # @property diff --git a/pyproject.toml b/pyproject.toml index d0158c90d..54da448ee 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,7 @@ packages = [{ "include" = "pandas-stubs" }] [tool.poetry.dependencies] python = ">=3.9" types-pytz = ">= 2022.1.1" -numpy = ">= 1.23.5" +numpy = ">= 1.23.5, <= 2.0.1" [tool.poetry.group.dev.dependencies] mypy = "1.10.1" diff --git a/tests/test_plotting.py b/tests/test_plotting.py index e6ebcec20..5d744350a 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -24,6 +24,11 @@ ) +@pytest.fixture(autouse=True) +def autouse_mpl_cleanup(mpl_cleanup): + pass + + @pytest.fixture def close_figures(): plt.close("all")