From 52485583b1620c490ebb0a5722df3a786b65f4a0 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Fri, 12 Apr 2024 12:06:41 -0700 Subject: [PATCH 01/16] DEPS: Drop Python 3.9 --- .github/workflows/package-checks.yml | 2 +- .github/workflows/wheels.yml | 2 +- ...yaml => actions-310-minimum_versions.yaml} | 2 +- ci/deps/actions-39.yaml | 63 ------------------- ...ons-pypy-39.yaml => actions-pypy-310.yaml} | 2 +- .../development/contributing_environment.rst | 2 +- doc/source/getting_started/install.rst | 4 +- doc/source/whatsnew/v3.0.0.rst | 5 ++ pandas/core/strings/object_array.py | 11 +--- pandas/tests/groupby/test_numeric_only.py | 3 +- pyproject.toml | 3 +- scripts/tests/data/deps_minimum.toml | 1 - 12 files changed, 15 insertions(+), 85 deletions(-) rename ci/deps/{actions-39-minimum_versions.yaml => actions-310-minimum_versions.yaml} (98%) delete mode 100644 ci/deps/actions-39.yaml rename ci/deps/{actions-pypy-39.yaml => actions-pypy-310.yaml} (94%) diff --git a/.github/workflows/package-checks.yml b/.github/workflows/package-checks.yml index 2de1649d42dfd..97f90c1588962 100644 --- a/.github/workflows/package-checks.yml +++ b/.github/workflows/package-checks.yml @@ -53,7 +53,7 @@ jobs: runs-on: ubuntu-22.04 strategy: matrix: - python-version: ['3.9', '3.10', '3.11'] + python-version: ['3.10', '3.11'] fail-fast: false name: Test Conda Forge Recipe - Python ${{ matrix.python-version }} concurrency: diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 4bd9068e91b67..bbe466aa4e294 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -99,7 +99,7 @@ jobs: - [macos-14, macosx_arm64] - [windows-2022, win_amd64] # TODO: support PyPy? - python: [["cp39", "3.9"], ["cp310", "3.10"], ["cp311", "3.11"], ["cp312", "3.12"]] + python: [["cp310", "3.10"], ["cp311", "3.11"], ["cp312", "3.12"]] env: IS_PUSH: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }} IS_SCHEDULE_DISPATCH: ${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }} diff --git a/ci/deps/actions-39-minimum_versions.yaml b/ci/deps/actions-310-minimum_versions.yaml similarity index 98% rename from ci/deps/actions-39-minimum_versions.yaml rename to ci/deps/actions-310-minimum_versions.yaml index b760f27a3d4d3..a9c205d24d212 100644 --- a/ci/deps/actions-39-minimum_versions.yaml +++ b/ci/deps/actions-310-minimum_versions.yaml @@ -4,7 +4,7 @@ name: pandas-dev channels: - conda-forge dependencies: - - python=3.9 + - python=3.10 # build dependencies - versioneer[toml] diff --git a/ci/deps/actions-39.yaml b/ci/deps/actions-39.yaml deleted file mode 100644 index 8f235a836bb3d..0000000000000 --- a/ci/deps/actions-39.yaml +++ /dev/null @@ -1,63 +0,0 @@ -name: pandas-dev -channels: - - conda-forge -dependencies: - - python=3.9 - - # build dependencies - - versioneer[toml] - - cython>=0.29.33 - - meson[ninja]=1.2.1 - - meson-python=0.13.1 - - # test dependencies - - pytest>=7.3.2 - - pytest-cov - - pytest-xdist>=2.2.0 - - pytest-qt>=4.2.0 - - boto3 - - # required dependencies - - python-dateutil - - numpy - - pytz - - # optional dependencies - - beautifulsoup4>=4.11.2 - - blosc>=1.21.3 - - bottleneck>=1.3.6 - - fastparquet>=2023.10.0 - - fsspec>=2022.11.0 - - html5lib>=1.1 - - hypothesis>=6.46.1 - - gcsfs>=2022.11.0 - - jinja2>=3.1.2 - - lxml>=4.9.2 - - matplotlib>=3.6.3 - - numba>=0.56.4 - - numexpr>=2.8.4 - - odfpy>=1.4.1 - - qtpy>=2.3.0 - - openpyxl>=3.1.0 - - psycopg2>=2.9.6 - - pyarrow>=10.0.1 - - pymysql>=1.0.2 - - pyqt>=5.15.9 - - pyreadstat>=1.2.0 - - pytables>=3.8.0 - - python-calamine>=0.1.7 - - pyxlsb>=1.0.10 - - s3fs>=2022.11.0 - - scipy>=1.10.0 - - sqlalchemy>=2.0.0 - - tabulate>=0.9.0 - - xarray>=2022.12.0 - - xlrd>=2.0.1 - - xlsxwriter>=3.0.5 - - zstandard>=0.19.0 - - - pip: - - adbc-driver-postgresql>=0.10.0 - - adbc-driver-sqlite>=0.8.0 - - tzdata>=2022.7 - - pytest-localserver>=0.7.1 diff --git a/ci/deps/actions-pypy-39.yaml b/ci/deps/actions-pypy-310.yaml similarity index 94% rename from ci/deps/actions-pypy-39.yaml rename to ci/deps/actions-pypy-310.yaml index d9c8dd81b7c33..05f48375c6e0c 100644 --- a/ci/deps/actions-pypy-39.yaml +++ b/ci/deps/actions-pypy-310.yaml @@ -5,7 +5,7 @@ dependencies: # TODO: Add the rest of the dependencies in here # once the other plentiful failures/segfaults # with base pandas has been dealt with - - python=3.9[build=*_pypy] + - python=3.10[build=*_pypy] # build dependencies - versioneer[toml] diff --git a/doc/source/development/contributing_environment.rst b/doc/source/development/contributing_environment.rst index 325c902dd4f9e..0691414f53306 100644 --- a/doc/source/development/contributing_environment.rst +++ b/doc/source/development/contributing_environment.rst @@ -130,7 +130,7 @@ Consult the docs for setting up pyenv `here `__. pyenv virtualenv # For instance: - pyenv virtualenv 3.9.10 pandas-dev + pyenv virtualenv 3.10 pandas-dev # Activate the virtualenv pyenv activate pandas-dev diff --git a/doc/source/getting_started/install.rst b/doc/source/getting_started/install.rst index 3cd9e030d6b3c..555b64604be9f 100644 --- a/doc/source/getting_started/install.rst +++ b/doc/source/getting_started/install.rst @@ -21,7 +21,7 @@ Instructions for installing :ref:`from source `, Python version support ---------------------- -Officially Python 3.9, 3.10, 3.11 and 3.12. +Officially Python 3.10, 3.11 and 3.12. Installing pandas ----------------- @@ -161,7 +161,7 @@ Python terminal. >>> import pandas as pd >>> pd.test() - running: pytest -m "not slow and not network and not db" /home/user/anaconda3/lib/python3.9/site-packages/pandas + running: pytest -m "not slow and not network and not db" /home/user/anaconda3/lib/python3.10/site-packages/pandas ============================= test session starts ============================== platform linux -- Python 3.9.7, pytest-6.2.5, py-1.11.0, pluggy-1.0.0 diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index e05cc87d1af14..f3e3481e7d893 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -117,6 +117,11 @@ Backwards incompatible API changes .. _whatsnew_300.api_breaking.deps: +Increased minimum version for Python +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +pandas 3.0.0 supports Python 3.10 and higher. + Increased minimum versions for dependencies ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Some minimum supported versions of dependencies were updated. diff --git a/pandas/core/strings/object_array.py b/pandas/core/strings/object_array.py index bdcf55e61d2d1..73283936998ab 100644 --- a/pandas/core/strings/object_array.py +++ b/pandas/core/strings/object_array.py @@ -457,16 +457,7 @@ def _str_rstrip(self, to_strip=None): return self._str_map(lambda x: x.rstrip(to_strip)) def _str_removeprefix(self, prefix: str): - # outstanding question on whether to use native methods for users on Python 3.9+ - # https://github.com/pandas-dev/pandas/pull/39226#issuecomment-836719770, - # in which case we could do return self._str_map(str.removeprefix) - - def removeprefix(text: str) -> str: - if text.startswith(prefix): - return text[len(prefix) :] - return text - - return self._str_map(removeprefix) + return self._str_map(lambda x: x.removeprefix(prefix)) def _str_removesuffix(self, suffix: str): return self._str_map(lambda x: x.removesuffix(suffix)) diff --git a/pandas/tests/groupby/test_numeric_only.py b/pandas/tests/groupby/test_numeric_only.py index 33cdd1883e1b9..b9c1bd10c3d3e 100644 --- a/pandas/tests/groupby/test_numeric_only.py +++ b/pandas/tests/groupby/test_numeric_only.py @@ -284,8 +284,7 @@ def test_numeric_only(kernel, has_arg, numeric_only, keys): [ "not allowed for this dtype", "cannot be performed against 'object' dtypes", - # On PY39 message is "a number"; on PY310 and after is "a real number" - "must be a string or a.* number", + "must be a string or a real number", "unsupported operand type", "function is not implemented for this dtype", re.escape(f"agg function failed [how->{kernel},dtype->object]"), diff --git a/pyproject.toml b/pyproject.toml index 085c054f8241a..c438db5a80325 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ authors = [ { name = 'The Pandas Development Team', email='pandas-dev@python.org' }, ] license = {file = 'LICENSE'} -requires-python = '>=3.9' +requires-python = '>=3.10' dependencies = [ "numpy>=1.23.5; python_version<'3.12'", "numpy>=1.26.0; python_version>='3.12'", @@ -43,7 +43,6 @@ classifiers = [ 'Programming Language :: Python', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', diff --git a/scripts/tests/data/deps_minimum.toml b/scripts/tests/data/deps_minimum.toml index ed7b9affe9a50..5723950029575 100644 --- a/scripts/tests/data/deps_minimum.toml +++ b/scripts/tests/data/deps_minimum.toml @@ -40,7 +40,6 @@ classifiers = [ 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3 :: Only', 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', 'Topic :: Scientific/Engineering' From 309991bb0cb06953dff3fa62541eb3b16ee5d738 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Fri, 12 Apr 2024 12:11:05 -0700 Subject: [PATCH 02/16] Update GHA files --- .github/workflows/unit-tests.yml | 8 ++++---- pandas/compat/_optional.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index f93950224eaae..2683c7a61009c 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -26,7 +26,7 @@ jobs: timeout-minutes: 90 strategy: matrix: - env_file: [actions-39.yaml, actions-310.yaml, actions-311.yaml, actions-312.yaml] + env_file: [actions-310.yaml, actions-311.yaml, actions-312.yaml] # Prevent the include jobs from overriding other jobs pattern: [""] include: @@ -35,7 +35,7 @@ jobs: pattern: "not slow and not network and not single_cpu" pytest_target: "pandas/tests/test_downstream.py" - name: "Minimum Versions" - env_file: actions-39-minimum_versions.yaml + env_file: actions-310-minimum_versions.yaml pattern: "not slow and not network and not single_cpu" - name: "Locale: it_IT" env_file: actions-311.yaml @@ -58,7 +58,7 @@ jobs: # It will be temporarily activated during tests with locale.setlocale extra_loc: "zh_CN" - name: "Pypy" - env_file: actions-pypy-39.yaml + env_file: actions-pypy-310.yaml pattern: "not slow and not network and not single_cpu" test_args: "--max-worker-restart 0" - name: "Numpy Dev" @@ -170,7 +170,7 @@ jobs: matrix: # Note: Don't use macOS latest since macos 14 appears to be arm64 only os: [macos-13, macos-14, windows-latest] - env_file: [actions-39.yaml, actions-310.yaml, actions-311.yaml, actions-312.yaml] + env_file: [actions-310.yaml, actions-311.yaml, actions-312.yaml] fail-fast: false runs-on: ${{ matrix.os }} name: ${{ format('{0} {1}', matrix.os, matrix.env_file) }} diff --git a/pandas/compat/_optional.py b/pandas/compat/_optional.py index f4e717c26d6fd..b62a4c8dcc8c8 100644 --- a/pandas/compat/_optional.py +++ b/pandas/compat/_optional.py @@ -16,7 +16,7 @@ if TYPE_CHECKING: import types -# Update install.rst, actions-39-minimum_versions.yaml, +# Update install.rst, actions-310-minimum_versions.yaml, # deps_minimum.toml & pyproject.toml when updating versions! VERSIONS = { From 997c6b1327ea9d6e4f59210c4e4975b15e84b3eb Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Fri, 12 Apr 2024 13:47:00 -0700 Subject: [PATCH 03/16] remove 3.8 ref in test file --- scripts/tests/data/deps_minimum.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/tests/data/deps_minimum.toml b/scripts/tests/data/deps_minimum.toml index 5723950029575..b832b6aa95198 100644 --- a/scripts/tests/data/deps_minimum.toml +++ b/scripts/tests/data/deps_minimum.toml @@ -39,7 +39,6 @@ classifiers = [ 'Programming Language :: Python', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', 'Topic :: Scientific/Engineering' From 4ddcf755803cbfbc2dee82c8c7eb98925d6bf26d Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Fri, 12 Apr 2024 14:09:35 -0700 Subject: [PATCH 04/16] Move back to 3.9 for pypy --- ci/deps/{actions-pypy-310.yaml => actions-pypy-39.yaml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename ci/deps/{actions-pypy-310.yaml => actions-pypy-39.yaml} (94%) diff --git a/ci/deps/actions-pypy-310.yaml b/ci/deps/actions-pypy-39.yaml similarity index 94% rename from ci/deps/actions-pypy-310.yaml rename to ci/deps/actions-pypy-39.yaml index 05f48375c6e0c..d9c8dd81b7c33 100644 --- a/ci/deps/actions-pypy-310.yaml +++ b/ci/deps/actions-pypy-39.yaml @@ -5,7 +5,7 @@ dependencies: # TODO: Add the rest of the dependencies in here # once the other plentiful failures/segfaults # with base pandas has been dealt with - - python=3.10[build=*_pypy] + - python=3.9[build=*_pypy] # build dependencies - versioneer[toml] From 1dbe0361a54f9a1d3097080bf05b438ed671e880 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Fri, 12 Apr 2024 16:47:50 -0700 Subject: [PATCH 05/16] Bump pyupgrade --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8c546ccae41e5..eb585d1606bcc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -75,7 +75,7 @@ repos: rev: v3.15.2 hooks: - id: pyupgrade - args: [--py39-plus] + args: [--py310-plus] - repo: https://github.com/pre-commit/pygrep-hooks rev: v1.10.0 hooks: From 3986c3a9f4e6c3fef5ccc49eb717f025de0234a7 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Fri, 12 Apr 2024 16:56:59 -0700 Subject: [PATCH 06/16] Run pyupgrade --- pandas/_config/config.py | 2 +- pandas/_testing/__init__.py | 3 ++- pandas/_testing/_io.py | 3 ++- pandas/_typing.py | 20 +++++++------------ pandas/_version.py | 2 +- pandas/conftest.py | 6 ++---- pandas/core/_numba/executor.py | 2 +- pandas/core/accessor.py | 5 ++++- pandas/core/apply.py | 2 +- .../array_algos/datetimelike_accumulations.py | 5 ++++- .../core/array_algos/masked_accumulations.py | 7 +++---- pandas/core/array_algos/masked_reductions.py | 7 +++---- pandas/core/arrays/arrow/array.py | 6 ++++-- pandas/core/arrays/base.py | 2 +- pandas/core/arrays/datetimelike.py | 2 +- pandas/core/arrays/interval.py | 2 +- pandas/core/arrays/masked.py | 2 +- pandas/core/arrays/numeric.py | 6 ++++-- pandas/core/arrays/period.py | 6 ++++-- pandas/core/arrays/sparse/array.py | 6 ++++-- pandas/core/arrays/string_arrow.py | 6 ++++-- pandas/core/common.py | 2 +- pandas/core/computation/align.py | 10 +++++----- pandas/core/computation/expr.py | 5 ++++- pandas/core/computation/ops.py | 2 +- pandas/core/config_init.py | 2 +- pandas/core/dtypes/common.py | 3 ++- pandas/core/frame.py | 2 +- pandas/core/generic.py | 2 +- pandas/core/groupby/generic.py | 2 +- pandas/core/groupby/groupby.py | 2 +- pandas/core/groupby/numba_.py | 3 ++- pandas/core/groupby/ops.py | 2 +- pandas/core/indexes/base.py | 2 +- pandas/core/indexes/extension.py | 3 ++- pandas/core/indexes/multi.py | 2 +- pandas/core/indexes/range.py | 2 +- pandas/core/internals/blocks.py | 2 +- pandas/core/internals/managers.py | 2 +- pandas/core/methods/describe.py | 2 +- pandas/core/nanops.py | 5 ++++- pandas/core/ops/common.py | 7 +++---- pandas/core/ops/invalid.py | 3 ++- pandas/core/resample.py | 6 ++++-- pandas/core/reshape/concat.py | 2 +- pandas/core/reshape/pivot.py | 6 ++++-- pandas/core/reshape/tile.py | 3 ++- pandas/core/series.py | 2 +- pandas/core/sorting.py | 2 +- pandas/core/strings/accessor.py | 2 +- pandas/core/strings/base.py | 6 ++++-- pandas/core/strings/object_array.py | 6 ++++-- pandas/core/tools/datetimes.py | 6 ++++-- pandas/core/util/numba_.py | 8 ++++---- pandas/core/window/expanding.py | 3 ++- pandas/core/window/numba_.py | 3 ++- pandas/core/window/rolling.py | 2 +- pandas/io/_util.py | 5 ++++- pandas/io/excel/_base.py | 2 +- pandas/io/excel/_util.py | 2 +- pandas/io/formats/css.py | 6 ++---- pandas/io/formats/excel.py | 2 +- pandas/io/formats/format.py | 2 +- pandas/io/formats/printing.py | 2 +- pandas/io/formats/style.py | 2 +- pandas/io/formats/style_render.py | 6 ++++-- pandas/io/json/_json.py | 2 +- pandas/io/parsers/base_parser.py | 2 +- pandas/io/parsers/readers.py | 2 +- pandas/io/pytables.py | 2 +- pandas/io/sql.py | 2 +- pandas/io/stata.py | 2 +- pandas/io/xml.py | 6 ++++-- pandas/plotting/_core.py | 2 +- pandas/tseries/holiday.py | 5 ++++- pandas/util/_decorators.py | 6 ++++-- pandas/util/_test_decorators.py | 6 ++---- pandas/util/version/__init__.py | 6 ++++-- ...check_for_inconsistent_pandas_namespace.py | 9 +++------ scripts/validate_unwanted_patterns.py | 10 +++++----- 80 files changed, 177 insertions(+), 140 deletions(-) diff --git a/pandas/_config/config.py b/pandas/_config/config.py index 8921e1b686303..5f1a48ecc12ce 100644 --- a/pandas/_config/config.py +++ b/pandas/_config/config.py @@ -55,7 +55,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, NamedTuple, cast, ) @@ -66,6 +65,7 @@ if TYPE_CHECKING: from collections.abc import ( + Callable, Generator, Sequence, ) diff --git a/pandas/_testing/__init__.py b/pandas/_testing/__init__.py index 12395b42bba19..89ad56fc485b7 100644 --- a/pandas/_testing/__init__.py +++ b/pandas/_testing/__init__.py @@ -6,7 +6,6 @@ from sys import byteorder from typing import ( TYPE_CHECKING, - Callable, ContextManager, cast, ) @@ -87,6 +86,8 @@ from pandas.core.construction import extract_array if TYPE_CHECKING: + from collections.abc import Callable + from pandas._typing import ( Dtype, NpDtype, diff --git a/pandas/_testing/_io.py b/pandas/_testing/_io.py index 2955108d3db1a..ca8813e29c62d 100644 --- a/pandas/_testing/_io.py +++ b/pandas/_testing/_io.py @@ -7,7 +7,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, ) import uuid import zipfile @@ -22,6 +21,8 @@ from pandas._testing.contexts import ensure_clean if TYPE_CHECKING: + from collections.abc import Callable + from pandas._typing import ( FilePath, ReadPickleBuffer, diff --git a/pandas/_typing.py b/pandas/_typing.py index f868a92554b39..592c31cb8d0e8 100644 --- a/pandas/_typing.py +++ b/pandas/_typing.py @@ -1,6 +1,7 @@ from __future__ import annotations from collections.abc import ( + Callable, Hashable, Iterator, Mapping, @@ -18,7 +19,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, Literal, Optional, Protocol, @@ -90,18 +90,12 @@ # Name "npt._ArrayLikeInt_co" is not defined [name-defined] NumpySorter = Optional[npt._ArrayLikeInt_co] # type: ignore[name-defined] - from typing import SupportsIndex - - if sys.version_info >= (3, 10): - from typing import Concatenate # pyright: ignore[reportUnusedImport] - from typing import ParamSpec - from typing import TypeGuard # pyright: ignore[reportUnusedImport] - else: - from typing_extensions import ( # pyright: ignore[reportUnusedImport] - Concatenate, - ParamSpec, - TypeGuard, - ) + from typing import ( + ParamSpec, + SupportsIndex, + ) + from typing import Concatenate # pyright: ignore[reportUnusedImport] + from typing import TypeGuard # pyright: ignore[reportUnusedImport] P = ParamSpec("P") diff --git a/pandas/_version.py b/pandas/_version.py index 7bd9da2bb1cfa..b32c9e67fdbb6 100644 --- a/pandas/_version.py +++ b/pandas/_version.py @@ -10,13 +10,13 @@ """Git implementation of _version.py.""" +from collections.abc import Callable import errno import functools import os import re import subprocess import sys -from typing import Callable def get_keywords(): diff --git a/pandas/conftest.py b/pandas/conftest.py index 34489bb70575a..94c86ae92e877 100644 --- a/pandas/conftest.py +++ b/pandas/conftest.py @@ -32,10 +32,7 @@ import gc import operator import os -from typing import ( - TYPE_CHECKING, - Callable, -) +from typing import TYPE_CHECKING import uuid from dateutil.tz import ( @@ -83,6 +80,7 @@ if TYPE_CHECKING: from collections.abc import ( + Callable, Hashable, Iterator, ) diff --git a/pandas/core/_numba/executor.py b/pandas/core/_numba/executor.py index 0a26acb7df60a..121dd8eeac632 100644 --- a/pandas/core/_numba/executor.py +++ b/pandas/core/_numba/executor.py @@ -4,10 +4,10 @@ from typing import ( TYPE_CHECKING, Any, - Callable, ) if TYPE_CHECKING: + from collections.abc import Callable from pandas._typing import Scalar import numpy as np diff --git a/pandas/core/accessor.py b/pandas/core/accessor.py index aa2bf2f527bd8..5db115c98b562 100644 --- a/pandas/core/accessor.py +++ b/pandas/core/accessor.py @@ -8,7 +8,7 @@ from __future__ import annotations from typing import ( - Callable, + TYPE_CHECKING, final, ) import warnings @@ -16,6 +16,9 @@ from pandas.util._decorators import doc from pandas.util._exceptions import find_stack_level +if TYPE_CHECKING: + from collections.abc import Callable + class DirNamesMixin: _accessors: set[str] = set() diff --git a/pandas/core/apply.py b/pandas/core/apply.py index 832beeddcef3c..cbed3867d3b54 100644 --- a/pandas/core/apply.py +++ b/pandas/core/apply.py @@ -2,13 +2,13 @@ import abc from collections import defaultdict +from collections.abc import Callable import functools from functools import partial import inspect from typing import ( TYPE_CHECKING, Any, - Callable, Literal, cast, ) diff --git a/pandas/core/array_algos/datetimelike_accumulations.py b/pandas/core/array_algos/datetimelike_accumulations.py index c3a7c2e4fefb2..bc10dbfbec90d 100644 --- a/pandas/core/array_algos/datetimelike_accumulations.py +++ b/pandas/core/array_algos/datetimelike_accumulations.py @@ -4,7 +4,7 @@ from __future__ import annotations -from typing import Callable +from typing import TYPE_CHECKING import numpy as np @@ -12,6 +12,9 @@ from pandas.core.dtypes.missing import isna +if TYPE_CHECKING: + from collections.abc import Callable + def _cum_func( func: Callable, diff --git a/pandas/core/array_algos/masked_accumulations.py b/pandas/core/array_algos/masked_accumulations.py index b31d32a606eed..b4e116388b85e 100644 --- a/pandas/core/array_algos/masked_accumulations.py +++ b/pandas/core/array_algos/masked_accumulations.py @@ -5,14 +5,13 @@ from __future__ import annotations -from typing import ( - TYPE_CHECKING, - Callable, -) +from typing import TYPE_CHECKING import numpy as np if TYPE_CHECKING: + from collections.abc import Callable + from pandas._typing import npt diff --git a/pandas/core/array_algos/masked_reductions.py b/pandas/core/array_algos/masked_reductions.py index 3784689995802..f2a32fbe2b0e5 100644 --- a/pandas/core/array_algos/masked_reductions.py +++ b/pandas/core/array_algos/masked_reductions.py @@ -5,10 +5,7 @@ from __future__ import annotations -from typing import ( - TYPE_CHECKING, - Callable, -) +from typing import TYPE_CHECKING import warnings import numpy as np @@ -18,6 +15,8 @@ from pandas.core.nanops import check_below_min_count if TYPE_CHECKING: + from collections.abc import Callable + from pandas._typing import ( AxisInt, npt, diff --git a/pandas/core/arrays/arrow/array.py b/pandas/core/arrays/arrow/array.py index 34ca81e36cbc5..acabd0e426d06 100644 --- a/pandas/core/arrays/arrow/array.py +++ b/pandas/core/arrays/arrow/array.py @@ -7,7 +7,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, Literal, cast, overload, @@ -175,7 +174,10 @@ def floordiv_compat( } if TYPE_CHECKING: - from collections.abc import Sequence + from collections.abc import ( + Callable, + Sequence, + ) from pandas._libs.missing import NAType from pandas._typing import ( diff --git a/pandas/core/arrays/base.py b/pandas/core/arrays/base.py index 8a2856d0a7e64..f8598d0ad408c 100644 --- a/pandas/core/arrays/base.py +++ b/pandas/core/arrays/base.py @@ -13,7 +13,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, ClassVar, Literal, cast, @@ -78,6 +77,7 @@ if TYPE_CHECKING: from collections.abc import ( + Callable, Iterator, Sequence, ) diff --git a/pandas/core/arrays/datetimelike.py b/pandas/core/arrays/datetimelike.py index f4f076103d8c3..11b0f9a3172e5 100644 --- a/pandas/core/arrays/datetimelike.py +++ b/pandas/core/arrays/datetimelike.py @@ -9,7 +9,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, Literal, Union, cast, @@ -148,6 +147,7 @@ if TYPE_CHECKING: from collections.abc import ( + Callable, Iterator, Sequence, ) diff --git a/pandas/core/arrays/interval.py b/pandas/core/arrays/interval.py index af666a591b1bc..ca5cc8772cdc2 100644 --- a/pandas/core/arrays/interval.py +++ b/pandas/core/arrays/interval.py @@ -8,7 +8,6 @@ import textwrap from typing import ( TYPE_CHECKING, - Callable, Literal, Union, overload, @@ -99,6 +98,7 @@ if TYPE_CHECKING: from collections.abc import ( + Callable, Iterator, Sequence, ) diff --git a/pandas/core/arrays/masked.py b/pandas/core/arrays/masked.py index d20d7f98b8aa8..8205912f11761 100644 --- a/pandas/core/arrays/masked.py +++ b/pandas/core/arrays/masked.py @@ -3,7 +3,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, Literal, overload, ) @@ -88,6 +87,7 @@ from pandas.core.util.hashing import hash_array if TYPE_CHECKING: + from collections.abc import Callable from collections.abc import ( Iterator, Sequence, diff --git a/pandas/core/arrays/numeric.py b/pandas/core/arrays/numeric.py index fe7b32ec9652e..8d81a86b94f29 100644 --- a/pandas/core/arrays/numeric.py +++ b/pandas/core/arrays/numeric.py @@ -4,7 +4,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, ) import numpy as np @@ -28,7 +27,10 @@ ) if TYPE_CHECKING: - from collections.abc import Mapping + from collections.abc import ( + Callable, + Mapping, + ) import pyarrow diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py index 8baf363b909fb..e762c3e547819 100644 --- a/pandas/core/arrays/period.py +++ b/pandas/core/arrays/period.py @@ -5,7 +5,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, Literal, TypeVar, cast, @@ -75,7 +74,10 @@ import pandas.core.common as com if TYPE_CHECKING: - from collections.abc import Sequence + from collections.abc import ( + Callable, + Sequence, + ) from pandas._typing import ( AnyArrayLike, diff --git a/pandas/core/arrays/sparse/array.py b/pandas/core/arrays/sparse/array.py index 134702099371d..07bddaa829012 100644 --- a/pandas/core/arrays/sparse/array.py +++ b/pandas/core/arrays/sparse/array.py @@ -10,7 +10,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, Literal, cast, overload, @@ -87,7 +86,10 @@ # See https://github.com/python/typing/issues/684 if TYPE_CHECKING: - from collections.abc import Sequence + from collections.abc import ( + Callable, + Sequence, + ) from enum import Enum class ellipsis(Enum): diff --git a/pandas/core/arrays/string_arrow.py b/pandas/core/arrays/string_arrow.py index ec2534ce174ac..cd5a877562a12 100644 --- a/pandas/core/arrays/string_arrow.py +++ b/pandas/core/arrays/string_arrow.py @@ -5,7 +5,6 @@ import re from typing import ( TYPE_CHECKING, - Callable, Union, cast, ) @@ -53,7 +52,10 @@ if TYPE_CHECKING: - from collections.abc import Sequence + from collections.abc import ( + Callable, + Sequence, + ) from pandas._typing import ( ArrayLike, diff --git a/pandas/core/common.py b/pandas/core/common.py index 77e986a26fbe9..9390765ac36f9 100644 --- a/pandas/core/common.py +++ b/pandas/core/common.py @@ -12,6 +12,7 @@ defaultdict, ) from collections.abc import ( + Callable, Collection, Generator, Hashable, @@ -24,7 +25,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, TypeVar, cast, overload, diff --git a/pandas/core/computation/align.py b/pandas/core/computation/align.py index c5562fb0284b7..ff908d9082337 100644 --- a/pandas/core/computation/align.py +++ b/pandas/core/computation/align.py @@ -8,10 +8,7 @@ partial, wraps, ) -from typing import ( - TYPE_CHECKING, - Callable, -) +from typing import TYPE_CHECKING import warnings import numpy as np @@ -31,7 +28,10 @@ from pandas.core.computation.common import result_type_many if TYPE_CHECKING: - from collections.abc import Sequence + from collections.abc import ( + Callable, + Sequence, + ) from pandas._typing import F diff --git a/pandas/core/computation/expr.py b/pandas/core/computation/expr.py index a8123a898b4fe..b287cd542068d 100644 --- a/pandas/core/computation/expr.py +++ b/pandas/core/computation/expr.py @@ -12,7 +12,7 @@ from keyword import iskeyword import tokenize from typing import ( - Callable, + TYPE_CHECKING, ClassVar, TypeVar, ) @@ -47,6 +47,9 @@ from pandas.io.formats import printing +if TYPE_CHECKING: + from collections.abc import Callable + def _rewrite_assign(tok: tuple[int, str]) -> tuple[int, str]: """ diff --git a/pandas/core/computation/ops.py b/pandas/core/computation/ops.py index 7d8e23abf43b6..df60717fcce39 100644 --- a/pandas/core/computation/ops.py +++ b/pandas/core/computation/ops.py @@ -9,7 +9,6 @@ import operator from typing import ( TYPE_CHECKING, - Callable, Literal, ) @@ -36,6 +35,7 @@ if TYPE_CHECKING: from collections.abc import ( + Callable, Iterable, Iterator, ) diff --git a/pandas/core/config_init.py b/pandas/core/config_init.py index 46c9139c3456c..05661033bd5ed 100644 --- a/pandas/core/config_init.py +++ b/pandas/core/config_init.py @@ -12,8 +12,8 @@ from __future__ import annotations +from collections.abc import Callable import os -from typing import Callable import pandas._config.config as cf from pandas._config.config import ( diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index 4d8d3c2816f69..967c28afe1ed9 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -7,7 +7,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, ) import warnings @@ -55,6 +54,8 @@ ) if TYPE_CHECKING: + from collections.abc import Callable + from pandas._typing import ( ArrayLike, DtypeObj, diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 0b386efb5a867..1702c625ff0c3 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -14,6 +14,7 @@ import collections from collections import abc from collections.abc import ( + Callable, Hashable, Iterable, Iterator, @@ -30,7 +31,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, Literal, cast, overload, diff --git a/pandas/core/generic.py b/pandas/core/generic.py index e1c1b21249362..e36970f9d6bad 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -13,7 +13,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, ClassVar, Literal, NoReturn, @@ -183,6 +182,7 @@ from pandas.io.formats.printing import pprint_thing if TYPE_CHECKING: + from collections.abc import Callable from collections.abc import ( Hashable, Iterator, diff --git a/pandas/core/groupby/generic.py b/pandas/core/groupby/generic.py index 0a048d11d0b4d..2683b3e7408d8 100644 --- a/pandas/core/groupby/generic.py +++ b/pandas/core/groupby/generic.py @@ -9,12 +9,12 @@ from __future__ import annotations from collections import abc +from collections.abc import Callable from functools import partial from textwrap import dedent from typing import ( TYPE_CHECKING, Any, - Callable, Literal, NamedTuple, TypeVar, diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index bc37405b25a16..c52354ca23155 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -10,6 +10,7 @@ class providing the base-class of operations. from __future__ import annotations from collections.abc import ( + Callable, Hashable, Iterator, Mapping, @@ -23,7 +24,6 @@ class providing the base-class of operations. from textwrap import dedent from typing import ( TYPE_CHECKING, - Callable, Literal, TypeVar, Union, diff --git a/pandas/core/groupby/numba_.py b/pandas/core/groupby/numba_.py index b22fc9248eeca..73b681c64c3a3 100644 --- a/pandas/core/groupby/numba_.py +++ b/pandas/core/groupby/numba_.py @@ -7,7 +7,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, ) import numpy as np @@ -20,6 +19,8 @@ ) if TYPE_CHECKING: + from collections.abc import Callable + from pandas._typing import Scalar diff --git a/pandas/core/groupby/ops.py b/pandas/core/groupby/ops.py index 0d88882c9b7ef..23c3f0a2b2853 100644 --- a/pandas/core/groupby/ops.py +++ b/pandas/core/groupby/ops.py @@ -12,7 +12,6 @@ import functools from typing import ( TYPE_CHECKING, - Callable, Generic, final, ) @@ -70,6 +69,7 @@ if TYPE_CHECKING: from collections.abc import ( + Callable, Hashable, Iterator, Sequence, diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index d5517a210b39d..a60709d940258 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -8,7 +8,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, ClassVar, Literal, NoReturn, @@ -193,6 +192,7 @@ if TYPE_CHECKING: from collections.abc import ( + Callable, Hashable, Iterable, Sequence, diff --git a/pandas/core/indexes/extension.py b/pandas/core/indexes/extension.py index fc806a3546571..48d5e59250f35 100644 --- a/pandas/core/indexes/extension.py +++ b/pandas/core/indexes/extension.py @@ -7,7 +7,6 @@ from inspect import signature from typing import ( TYPE_CHECKING, - Callable, TypeVar, ) @@ -18,6 +17,8 @@ from pandas.core.indexes.base import Index if TYPE_CHECKING: + from collections.abc import Callable + import numpy as np from pandas._typing import ( diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index 4affa1337aa2a..d6b575239f1a5 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -1,6 +1,7 @@ from __future__ import annotations from collections.abc import ( + Callable, Collection, Generator, Hashable, @@ -12,7 +13,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, Literal, cast, ) diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py index 0ba3c22093c69..bd0fc4cfcd309 100644 --- a/pandas/core/indexes/range.py +++ b/pandas/core/indexes/range.py @@ -1,6 +1,7 @@ from __future__ import annotations from collections.abc import ( + Callable, Hashable, Iterator, ) @@ -10,7 +11,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, Literal, cast, overload, diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 7be1d5d95ffdf..91ec3a15463c1 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -5,7 +5,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, Literal, cast, final, @@ -118,6 +117,7 @@ if TYPE_CHECKING: from collections.abc import ( + Callable, Iterable, Sequence, ) diff --git a/pandas/core/internals/managers.py b/pandas/core/internals/managers.py index 8fda9cd23b508..fbe67ea7eb077 100644 --- a/pandas/core/internals/managers.py +++ b/pandas/core/internals/managers.py @@ -1,6 +1,7 @@ from __future__ import annotations from collections.abc import ( + Callable, Hashable, Sequence, ) @@ -8,7 +9,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, Literal, NoReturn, cast, diff --git a/pandas/core/methods/describe.py b/pandas/core/methods/describe.py index ef20d4c509732..17d4d38c97f33 100644 --- a/pandas/core/methods/describe.py +++ b/pandas/core/methods/describe.py @@ -12,7 +12,6 @@ ) from typing import ( TYPE_CHECKING, - Callable, cast, ) @@ -42,6 +41,7 @@ if TYPE_CHECKING: from collections.abc import ( + Callable, Hashable, Sequence, ) diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index 22092551ec882..e775156a6ae2f 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -3,8 +3,8 @@ import functools import itertools from typing import ( + TYPE_CHECKING, Any, - Callable, cast, ) import warnings @@ -48,6 +48,9 @@ notna, ) +if TYPE_CHECKING: + from collections.abc import Callable + bn = import_optional_dependency("bottleneck", errors="warn") _BOTTLENECK_INSTALLED = bn is not None _USE_BOTTLENECK = False diff --git a/pandas/core/ops/common.py b/pandas/core/ops/common.py index d19ac6246e1cd..5cbe1c421e05a 100644 --- a/pandas/core/ops/common.py +++ b/pandas/core/ops/common.py @@ -5,10 +5,7 @@ from __future__ import annotations from functools import wraps -from typing import ( - TYPE_CHECKING, - Callable, -) +from typing import TYPE_CHECKING from pandas._libs.lib import item_from_zerodim from pandas._libs.missing import is_matching_na @@ -19,6 +16,8 @@ ) if TYPE_CHECKING: + from collections.abc import Callable + from pandas._typing import F diff --git a/pandas/core/ops/invalid.py b/pandas/core/ops/invalid.py index c300db8c114c1..395db1617cb63 100644 --- a/pandas/core/ops/invalid.py +++ b/pandas/core/ops/invalid.py @@ -8,13 +8,14 @@ from typing import ( TYPE_CHECKING, Any, - Callable, NoReturn, ) import numpy as np if TYPE_CHECKING: + from collections.abc import Callable + from pandas._typing import ( ArrayLike, Scalar, diff --git a/pandas/core/resample.py b/pandas/core/resample.py index 4392f54d9c442..1ff959e9f175e 100644 --- a/pandas/core/resample.py +++ b/pandas/core/resample.py @@ -4,7 +4,6 @@ from textwrap import dedent from typing import ( TYPE_CHECKING, - Callable, Literal, cast, final, @@ -91,7 +90,10 @@ ) if TYPE_CHECKING: - from collections.abc import Hashable + from collections.abc import ( + Callable, + Hashable, + ) from pandas._typing import ( Any, diff --git a/pandas/core/reshape/concat.py b/pandas/core/reshape/concat.py index d17e5b475ae57..efd71c4357103 100644 --- a/pandas/core/reshape/concat.py +++ b/pandas/core/reshape/concat.py @@ -7,7 +7,6 @@ from collections import abc from typing import ( TYPE_CHECKING, - Callable, Literal, cast, overload, @@ -46,6 +45,7 @@ if TYPE_CHECKING: from collections.abc import ( + Callable, Hashable, Iterable, Mapping, diff --git a/pandas/core/reshape/pivot.py b/pandas/core/reshape/pivot.py index e0126d439a79c..f08bb67632191 100644 --- a/pandas/core/reshape/pivot.py +++ b/pandas/core/reshape/pivot.py @@ -3,7 +3,6 @@ import itertools from typing import ( TYPE_CHECKING, - Callable, Literal, cast, ) @@ -41,7 +40,10 @@ from pandas.core.series import Series if TYPE_CHECKING: - from collections.abc import Hashable + from collections.abc import ( + Callable, + Hashable, + ) from pandas._typing import ( AggFuncType, diff --git a/pandas/core/reshape/tile.py b/pandas/core/reshape/tile.py index 1499afbde56d3..8347864604ad2 100644 --- a/pandas/core/reshape/tile.py +++ b/pandas/core/reshape/tile.py @@ -7,7 +7,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, Literal, ) @@ -44,6 +43,8 @@ from pandas.core.arrays.datetimelike import dtype_to_unit if TYPE_CHECKING: + from collections.abc import Callable + from pandas._typing import ( DtypeObj, IntervalLeftRight, diff --git a/pandas/core/series.py b/pandas/core/series.py index 0f796964eb56d..8062bc3434610 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -5,6 +5,7 @@ from __future__ import annotations from collections.abc import ( + Callable, Hashable, Iterable, Mapping, @@ -17,7 +18,6 @@ IO, TYPE_CHECKING, Any, - Callable, Literal, cast, overload, diff --git a/pandas/core/sorting.py b/pandas/core/sorting.py index 4fba243f73536..0d8f42694ccb4 100644 --- a/pandas/core/sorting.py +++ b/pandas/core/sorting.py @@ -5,7 +5,6 @@ import itertools from typing import ( TYPE_CHECKING, - Callable, cast, ) @@ -32,6 +31,7 @@ if TYPE_CHECKING: from collections.abc import ( + Callable, Hashable, Sequence, ) diff --git a/pandas/core/strings/accessor.py b/pandas/core/strings/accessor.py index d274c1d7a5aff..85da4ddc8f4c3 100644 --- a/pandas/core/strings/accessor.py +++ b/pandas/core/strings/accessor.py @@ -5,7 +5,6 @@ import re from typing import ( TYPE_CHECKING, - Callable, Literal, cast, ) @@ -50,6 +49,7 @@ if TYPE_CHECKING: from collections.abc import ( + Callable, Hashable, Iterator, ) diff --git a/pandas/core/strings/base.py b/pandas/core/strings/base.py index c1f94abff428a..1281a03e297f9 100644 --- a/pandas/core/strings/base.py +++ b/pandas/core/strings/base.py @@ -3,14 +3,16 @@ import abc from typing import ( TYPE_CHECKING, - Callable, Literal, ) import numpy as np if TYPE_CHECKING: - from collections.abc import Sequence + from collections.abc import ( + Callable, + Sequence, + ) import re from pandas._typing import ( diff --git a/pandas/core/strings/object_array.py b/pandas/core/strings/object_array.py index 73283936998ab..290a28ab60ae1 100644 --- a/pandas/core/strings/object_array.py +++ b/pandas/core/strings/object_array.py @@ -5,7 +5,6 @@ import textwrap from typing import ( TYPE_CHECKING, - Callable, Literal, cast, ) @@ -22,7 +21,10 @@ from pandas.core.strings.base import BaseStringArrayMethods if TYPE_CHECKING: - from collections.abc import Sequence + from collections.abc import ( + Callable, + Sequence, + ) from pandas._typing import ( NpDtype, diff --git a/pandas/core/tools/datetimes.py b/pandas/core/tools/datetimes.py index 2aeb1aff07a54..3b6bf9d46eb6f 100644 --- a/pandas/core/tools/datetimes.py +++ b/pandas/core/tools/datetimes.py @@ -6,7 +6,6 @@ from itertools import islice from typing import ( TYPE_CHECKING, - Callable, TypedDict, Union, cast, @@ -76,7 +75,10 @@ from pandas.core.indexes.datetimes import DatetimeIndex if TYPE_CHECKING: - from collections.abc import Hashable + from collections.abc import ( + Callable, + Hashable, + ) from pandas._libs.tslibs.nattype import NaTType from pandas._libs.tslibs.timedeltas import UnitChoices diff --git a/pandas/core/util/numba_.py b/pandas/core/util/numba_.py index a6079785e7475..15f904ad6c967 100644 --- a/pandas/core/util/numba_.py +++ b/pandas/core/util/numba_.py @@ -3,16 +3,16 @@ from __future__ import annotations import types -from typing import ( - TYPE_CHECKING, - Callable, -) +from typing import TYPE_CHECKING import numpy as np from pandas.compat._optional import import_optional_dependency from pandas.errors import NumbaUtilError +if TYPE_CHECKING: + from collections.abc import Callable + GLOBAL_USE_NUMBA: bool = False diff --git a/pandas/core/window/expanding.py b/pandas/core/window/expanding.py index abe853a8aa259..ed6ec02ff8ee5 100644 --- a/pandas/core/window/expanding.py +++ b/pandas/core/window/expanding.py @@ -4,7 +4,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, Literal, ) @@ -35,6 +34,8 @@ ) if TYPE_CHECKING: + from collections.abc import Callable + from pandas._typing import ( QuantileInterpolation, WindowingRankType, diff --git a/pandas/core/window/numba_.py b/pandas/core/window/numba_.py index eb06479fc325e..5ca9ee88f0a7e 100644 --- a/pandas/core/window/numba_.py +++ b/pandas/core/window/numba_.py @@ -4,7 +4,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, ) import numpy as np @@ -14,6 +13,8 @@ from pandas.core.util.numba_ import jit_user_function if TYPE_CHECKING: + from collections.abc import Callable + from pandas._typing import Scalar diff --git a/pandas/core/window/rolling.py b/pandas/core/window/rolling.py index db6078ae636e3..248e05a9f681c 100644 --- a/pandas/core/window/rolling.py +++ b/pandas/core/window/rolling.py @@ -13,7 +13,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, Literal, ) @@ -93,6 +92,7 @@ ) if TYPE_CHECKING: + from collections.abc import Callable from collections.abc import ( Hashable, Iterator, diff --git a/pandas/io/_util.py b/pandas/io/_util.py index 3b2ae5daffdba..cb0f89945e440 100644 --- a/pandas/io/_util.py +++ b/pandas/io/_util.py @@ -1,11 +1,14 @@ from __future__ import annotations -from typing import Callable +from typing import TYPE_CHECKING from pandas.compat._optional import import_optional_dependency import pandas as pd +if TYPE_CHECKING: + from collections.abc import Callable + def _arrow_dtype_mapping() -> dict: pa = import_optional_dependency("pyarrow") diff --git a/pandas/io/excel/_base.py b/pandas/io/excel/_base.py index a9da95054b81a..0cf04a6628f52 100644 --- a/pandas/io/excel/_base.py +++ b/pandas/io/excel/_base.py @@ -1,6 +1,7 @@ from __future__ import annotations from collections.abc import ( + Callable, Hashable, Iterable, Mapping, @@ -14,7 +15,6 @@ IO, TYPE_CHECKING, Any, - Callable, Generic, Literal, TypeVar, diff --git a/pandas/io/excel/_util.py b/pandas/io/excel/_util.py index f879f16aa5dc8..e7c5d518abaee 100644 --- a/pandas/io/excel/_util.py +++ b/pandas/io/excel/_util.py @@ -1,6 +1,7 @@ from __future__ import annotations from collections.abc import ( + Callable, Hashable, Iterable, MutableMapping, @@ -9,7 +10,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, Literal, TypeVar, overload, diff --git a/pandas/io/formats/css.py b/pandas/io/formats/css.py index d3d0da6f562a7..0af04526ea96d 100644 --- a/pandas/io/formats/css.py +++ b/pandas/io/formats/css.py @@ -5,10 +5,7 @@ from __future__ import annotations import re -from typing import ( - TYPE_CHECKING, - Callable, -) +from typing import TYPE_CHECKING import warnings from pandas.errors import CSSWarning @@ -16,6 +13,7 @@ if TYPE_CHECKING: from collections.abc import ( + Callable, Generator, Iterable, Iterator, diff --git a/pandas/io/formats/excel.py b/pandas/io/formats/excel.py index b6c6112b05ab3..a98d9c175c2bd 100644 --- a/pandas/io/formats/excel.py +++ b/pandas/io/formats/excel.py @@ -5,6 +5,7 @@ from __future__ import annotations from collections.abc import ( + Callable, Hashable, Iterable, Mapping, @@ -16,7 +17,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, cast, ) import warnings diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index c503121328f53..9ad5ac83e9eae 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -6,6 +6,7 @@ from __future__ import annotations from collections.abc import ( + Callable, Generator, Hashable, Mapping, @@ -22,7 +23,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, Final, cast, ) diff --git a/pandas/io/formats/printing.py b/pandas/io/formats/printing.py index 0bd4f2935f4d0..67b5eb6f5ee5b 100644 --- a/pandas/io/formats/printing.py +++ b/pandas/io/formats/printing.py @@ -5,6 +5,7 @@ from __future__ import annotations from collections.abc import ( + Callable, Iterable, Mapping, Sequence, @@ -13,7 +14,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, TypeVar, Union, ) diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index b2b0d711c6b54..22f14d6935966 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -10,7 +10,6 @@ import operator from typing import ( TYPE_CHECKING, - Callable, overload, ) @@ -56,6 +55,7 @@ if TYPE_CHECKING: from collections.abc import ( + Callable, Generator, Hashable, Sequence, diff --git a/pandas/io/formats/style_render.py b/pandas/io/formats/style_render.py index 92afbc0e150ef..19a3563f43b4e 100644 --- a/pandas/io/formats/style_render.py +++ b/pandas/io/formats/style_render.py @@ -1,13 +1,15 @@ from __future__ import annotations from collections import defaultdict -from collections.abc import Sequence +from collections.abc import ( + Callable, + Sequence, +) from functools import partial import re from typing import ( TYPE_CHECKING, Any, - Callable, DefaultDict, Optional, TypedDict, diff --git a/pandas/io/json/_json.py b/pandas/io/json/_json.py index 13d74e935f786..0a6e1ea0c21ab 100644 --- a/pandas/io/json/_json.py +++ b/pandas/io/json/_json.py @@ -9,7 +9,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, Generic, Literal, TypeVar, @@ -65,6 +64,7 @@ if TYPE_CHECKING: from collections.abc import ( + Callable, Hashable, Mapping, ) diff --git a/pandas/io/parsers/base_parser.py b/pandas/io/parsers/base_parser.py index 510097aed2a25..4019dfc61d002 100644 --- a/pandas/io/parsers/base_parser.py +++ b/pandas/io/parsers/base_parser.py @@ -9,7 +9,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, cast, final, overload, @@ -84,6 +83,7 @@ if TYPE_CHECKING: from collections.abc import ( + Callable, Iterable, Mapping, Sequence, diff --git a/pandas/io/parsers/readers.py b/pandas/io/parsers/readers.py index 70f9a68244164..3ac6cf96efae4 100644 --- a/pandas/io/parsers/readers.py +++ b/pandas/io/parsers/readers.py @@ -17,7 +17,6 @@ IO, TYPE_CHECKING, Any, - Callable, Generic, Literal, TypedDict, @@ -71,6 +70,7 @@ if TYPE_CHECKING: from collections.abc import ( + Callable, Hashable, Iterable, Mapping, diff --git a/pandas/io/pytables.py b/pandas/io/pytables.py index 5ecf7e287ea58..1d331762de9be 100644 --- a/pandas/io/pytables.py +++ b/pandas/io/pytables.py @@ -18,7 +18,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, Final, Literal, cast, @@ -101,6 +100,7 @@ if TYPE_CHECKING: from collections.abc import ( + Callable, Hashable, Iterator, Sequence, diff --git a/pandas/io/sql.py b/pandas/io/sql.py index 8c4c4bac884e5..0d55084b13e5d 100644 --- a/pandas/io/sql.py +++ b/pandas/io/sql.py @@ -23,7 +23,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, Literal, cast, overload, @@ -67,6 +66,7 @@ if TYPE_CHECKING: from collections.abc import ( + Callable, Generator, Iterator, Mapping, diff --git a/pandas/io/stata.py b/pandas/io/stata.py index 47d879c022ee6..eadc2cb9c3bd6 100644 --- a/pandas/io/stata.py +++ b/pandas/io/stata.py @@ -25,7 +25,6 @@ IO, TYPE_CHECKING, AnyStr, - Callable, Final, cast, ) @@ -74,6 +73,7 @@ if TYPE_CHECKING: from collections.abc import ( + Callable, Hashable, Sequence, ) diff --git a/pandas/io/xml.py b/pandas/io/xml.py index a6cd06cd61687..8c7381a926e72 100644 --- a/pandas/io/xml.py +++ b/pandas/io/xml.py @@ -9,7 +9,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, ) from pandas._libs import lib @@ -35,7 +34,10 @@ from pandas.io.parsers import TextParser if TYPE_CHECKING: - from collections.abc import Sequence + from collections.abc import ( + Callable, + Sequence, + ) from xml.etree.ElementTree import Element from lxml import etree diff --git a/pandas/plotting/_core.py b/pandas/plotting/_core.py index 60bb45d3ac1dc..4066e8076a116 100644 --- a/pandas/plotting/_core.py +++ b/pandas/plotting/_core.py @@ -3,7 +3,6 @@ import importlib from typing import ( TYPE_CHECKING, - Callable, Literal, ) @@ -27,6 +26,7 @@ if TYPE_CHECKING: from collections.abc import ( + Callable, Hashable, Sequence, ) diff --git a/pandas/tseries/holiday.py b/pandas/tseries/holiday.py index 8e51183138b5c..bf4ec2e551f01 100644 --- a/pandas/tseries/holiday.py +++ b/pandas/tseries/holiday.py @@ -4,7 +4,7 @@ datetime, timedelta, ) -from typing import Callable +from typing import TYPE_CHECKING import warnings from dateutil.relativedelta import ( @@ -35,6 +35,9 @@ Easter, ) +if TYPE_CHECKING: + from collections.abc import Callable + def next_monday(dt: datetime) -> datetime: """ diff --git a/pandas/util/_decorators.py b/pandas/util/_decorators.py index d287fa72d552d..e7fcd6caf3406 100644 --- a/pandas/util/_decorators.py +++ b/pandas/util/_decorators.py @@ -6,7 +6,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, cast, ) import warnings @@ -19,7 +18,10 @@ from pandas.util._exceptions import find_stack_level if TYPE_CHECKING: - from collections.abc import Mapping + from collections.abc import ( + Callable, + Mapping, + ) def deprecate( diff --git a/pandas/util/_test_decorators.py b/pandas/util/_test_decorators.py index d4a79cae61772..814b565523fe8 100644 --- a/pandas/util/_test_decorators.py +++ b/pandas/util/_test_decorators.py @@ -27,14 +27,12 @@ def test_foo(): from __future__ import annotations import locale -from typing import ( - TYPE_CHECKING, - Callable, -) +from typing import TYPE_CHECKING import pytest if TYPE_CHECKING: + from collections.abc import Callable from pandas._typing import F from pandas.compat import ( diff --git a/pandas/util/version/__init__.py b/pandas/util/version/__init__.py index 153424e339c45..9838e371f0d00 100644 --- a/pandas/util/version/__init__.py +++ b/pandas/util/version/__init__.py @@ -8,11 +8,13 @@ from __future__ import annotations import collections -from collections.abc import Iterator +from collections.abc import ( + Callable, + Iterator, +) import itertools import re from typing import ( - Callable, SupportsInt, Tuple, Union, diff --git a/scripts/check_for_inconsistent_pandas_namespace.py b/scripts/check_for_inconsistent_pandas_namespace.py index 52eca6f6d93ac..ec0a4a408c800 100644 --- a/scripts/check_for_inconsistent_pandas_namespace.py +++ b/scripts/check_for_inconsistent_pandas_namespace.py @@ -27,10 +27,7 @@ Sequence, ) import sys -from typing import ( - NamedTuple, - Optional, -) +from typing import NamedTuple ERROR_MESSAGE = ( "{path}:{lineno}:{col_offset}: " @@ -89,7 +86,7 @@ def replace_inconsistent_pandas_namespace(visitor: Visitor, content: str) -> str def check_for_inconsistent_pandas_namespace( content: str, path: str, *, replace: bool -) -> Optional[str]: +) -> str | None: tree = ast.parse(content) visitor = Visitor() @@ -121,7 +118,7 @@ def check_for_inconsistent_pandas_namespace( return replace_inconsistent_pandas_namespace(visitor, content) -def main(argv: Optional[Sequence[str]] = None) -> None: +def main(argv: Sequence[str] | None = None) -> None: parser = argparse.ArgumentParser() parser.add_argument("paths", nargs="*") parser.add_argument("--replace", action="store_true") diff --git a/scripts/validate_unwanted_patterns.py b/scripts/validate_unwanted_patterns.py index a732d3f83a40a..cf7eba6415108 100755 --- a/scripts/validate_unwanted_patterns.py +++ b/scripts/validate_unwanted_patterns.py @@ -12,14 +12,14 @@ import argparse import ast -from collections.abc import Iterable +from collections.abc import ( + Callable, + Iterable, +) import sys import token import tokenize -from typing import ( - IO, - Callable, -) +from typing import IO PRIVATE_IMPORTS_TO_IGNORE: set[str] = { "_extension_array_shared_docs", From a6b79382bd418c2d0d751738b80d2694eebc76bc Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Fri, 12 Apr 2024 17:06:17 -0700 Subject: [PATCH 07/16] Remove pandas.compat.compressors --- pandas/_testing/_io.py | 12 +-- pandas/compat/__init__.py | 49 ------------ pandas/compat/_constants.py | 2 - pandas/compat/compressors.py | 77 ------------------- pandas/io/common.py | 12 +-- pandas/tests/io/excel/test_writers.py | 14 ++-- pandas/tests/io/test_pickle.py | 40 +--------- .../scalar/timestamp/test_constructors.py | 7 +- pandas/tests/test_common.py | 19 ----- pyproject.toml | 1 - 10 files changed, 23 insertions(+), 210 deletions(-) delete mode 100644 pandas/compat/compressors.py diff --git a/pandas/_testing/_io.py b/pandas/_testing/_io.py index ca8813e29c62d..e1841c95dcdfe 100644 --- a/pandas/_testing/_io.py +++ b/pandas/_testing/_io.py @@ -11,10 +11,6 @@ import uuid import zipfile -from pandas.compat import ( - get_bz2_file, - get_lzma_file, -) from pandas.compat._optional import import_optional_dependency import pandas as pd @@ -130,11 +126,15 @@ def write_to_compressed(compression, path, data, dest: str = "test") -> None: elif compression == "gzip": compress_method = gzip.GzipFile elif compression == "bz2": - compress_method = get_bz2_file() + import bz2 + + compress_method = bz2.BZ2File elif compression == "zstd": compress_method = import_optional_dependency("zstandard").open elif compression == "xz": - compress_method = get_lzma_file() + import lzma + + compress_method = lzma.LZMAFile else: raise ValueError(f"Unrecognized compression type: {compression}") diff --git a/pandas/compat/__init__.py b/pandas/compat/__init__.py index caa00b205a29c..7a50026fa5a19 100644 --- a/pandas/compat/__init__.py +++ b/pandas/compat/__init__.py @@ -18,12 +18,10 @@ from pandas.compat._constants import ( IS64, ISMUSL, - PY310, PY311, PY312, PYPY, ) -import pandas.compat.compressors from pandas.compat.numpy import is_numpy_dev from pandas.compat.pyarrow import ( pa_version_under10p1, @@ -135,52 +133,6 @@ def is_ci_environment() -> bool: return os.environ.get("PANDAS_CI", "0") == "1" -def get_lzma_file() -> type[pandas.compat.compressors.LZMAFile]: - """ - Importing the `LZMAFile` class from the `lzma` module. - - Returns - ------- - class - The `LZMAFile` class from the `lzma` module. - - Raises - ------ - RuntimeError - If the `lzma` module was not imported correctly, or didn't exist. - """ - if not pandas.compat.compressors.has_lzma: - raise RuntimeError( - "lzma module not available. " - "A Python re-install with the proper dependencies, " - "might be required to solve this issue." - ) - return pandas.compat.compressors.LZMAFile - - -def get_bz2_file() -> type[pandas.compat.compressors.BZ2File]: - """ - Importing the `BZ2File` class from the `bz2` module. - - Returns - ------- - class - The `BZ2File` class from the `bz2` module. - - Raises - ------ - RuntimeError - If the `bz2` module was not imported correctly, or didn't exist. - """ - if not pandas.compat.compressors.has_bz2: - raise RuntimeError( - "bz2 module not available. " - "A Python re-install with the proper dependencies, " - "might be required to solve this issue." - ) - return pandas.compat.compressors.BZ2File - - __all__ = [ "is_numpy_dev", "pa_version_under10p1", @@ -191,7 +143,6 @@ def get_bz2_file() -> type[pandas.compat.compressors.BZ2File]: "pa_version_under16p0", "IS64", "ISMUSL", - "PY310", "PY311", "PY312", "PYPY", diff --git a/pandas/compat/_constants.py b/pandas/compat/_constants.py index 7bc3fbaaefebf..52a48613c5dfc 100644 --- a/pandas/compat/_constants.py +++ b/pandas/compat/_constants.py @@ -13,7 +13,6 @@ IS64 = sys.maxsize > 2**32 -PY310 = sys.version_info >= (3, 10) PY311 = sys.version_info >= (3, 11) PY312 = sys.version_info >= (3, 12) PYPY = platform.python_implementation() == "PyPy" @@ -23,7 +22,6 @@ __all__ = [ "IS64", "ISMUSL", - "PY310", "PY311", "PY312", "PYPY", diff --git a/pandas/compat/compressors.py b/pandas/compat/compressors.py deleted file mode 100644 index 1f31e34c092c9..0000000000000 --- a/pandas/compat/compressors.py +++ /dev/null @@ -1,77 +0,0 @@ -""" -Patched ``BZ2File`` and ``LZMAFile`` to handle pickle protocol 5. -""" - -from __future__ import annotations - -from pickle import PickleBuffer - -from pandas.compat._constants import PY310 - -try: - import bz2 - - has_bz2 = True -except ImportError: - has_bz2 = False - -try: - import lzma - - has_lzma = True -except ImportError: - has_lzma = False - - -def flatten_buffer( - b: bytes | bytearray | memoryview | PickleBuffer, -) -> bytes | bytearray | memoryview: - """ - Return some 1-D `uint8` typed buffer. - - Coerces anything that does not match that description to one that does - without copying if possible (otherwise will copy). - """ - - if isinstance(b, (bytes, bytearray)): - return b - - if not isinstance(b, PickleBuffer): - b = PickleBuffer(b) - - try: - # coerce to 1-D `uint8` C-contiguous `memoryview` zero-copy - return b.raw() - except BufferError: - # perform in-memory copy if buffer is not contiguous - return memoryview(b).tobytes("A") - - -if has_bz2: - - class BZ2File(bz2.BZ2File): - if not PY310: - - def write(self, b) -> int: - # Workaround issue where `bz2.BZ2File` expects `len` - # to return the number of bytes in `b` by converting - # `b` into something that meets that constraint with - # minimal copying. - # - # Note: This is fixed in Python 3.10. - return super().write(flatten_buffer(b)) - - -if has_lzma: - - class LZMAFile(lzma.LZMAFile): - if not PY310: - - def write(self, b) -> int: - # Workaround issue where `lzma.LZMAFile` expects `len` - # to return the number of bytes in `b` by converting - # `b` into something that meets that constraint with - # minimal copying. - # - # Note: This is fixed in Python 3.10. - return super().write(flatten_buffer(b)) diff --git a/pandas/io/common.py b/pandas/io/common.py index 4507a7d08c8ba..a76f0cf6dd34d 100644 --- a/pandas/io/common.py +++ b/pandas/io/common.py @@ -55,10 +55,6 @@ BaseBuffer, ReadCsvBuffer, ) -from pandas.compat import ( - get_bz2_file, - get_lzma_file, -) from pandas.compat._optional import import_optional_dependency from pandas.util._decorators import doc from pandas.util._exceptions import find_stack_level @@ -784,9 +780,11 @@ def get_handle( # BZ Compression elif compression == "bz2": + import bz2 + # Overload of "BZ2File" to handle pickle protocol 5 # "Union[str, BaseBuffer]", "str", "Dict[str, Any]" - handle = get_bz2_file()( # type: ignore[call-overload] + handle = bz2.BZ2File( # type: ignore[call-overload] handle, mode=ioargs.mode, **compression_args, @@ -849,7 +847,9 @@ def get_handle( # error: Argument 1 to "LZMAFile" has incompatible type "Union[str, # BaseBuffer]"; expected "Optional[Union[Union[str, bytes, PathLike[str], # PathLike[bytes]], IO[bytes]], None]" - handle = get_lzma_file()( + import lzma + + handle = lzma.LZMAFile( handle, # type: ignore[arg-type] ioargs.mode, **compression_args, diff --git a/pandas/tests/io/excel/test_writers.py b/pandas/tests/io/excel/test_writers.py index 508fc47d0920b..063a64f34964f 100644 --- a/pandas/tests/io/excel/test_writers.py +++ b/pandas/tests/io/excel/test_writers.py @@ -12,7 +12,6 @@ import numpy as np import pytest -from pandas.compat._constants import PY310 from pandas.compat._optional import import_optional_dependency import pandas.util._test_decorators as td @@ -1256,13 +1255,12 @@ def test_engine_kwargs(self, engine, tmp_excel): "xlsxwriter": r"__init__() got an unexpected keyword argument 'foo'", } - if PY310: - msgs["openpyxl"] = ( - "Workbook.__init__() got an unexpected keyword argument 'foo'" - ) - msgs["xlsxwriter"] = ( - "Workbook.__init__() got an unexpected keyword argument 'foo'" - ) + msgs["openpyxl"] = ( + "Workbook.__init__() got an unexpected keyword argument 'foo'" + ) + msgs["xlsxwriter"] = ( + "Workbook.__init__() got an unexpected keyword argument 'foo'" + ) # Handle change in error message for openpyxl (write and append mode) if engine == "openpyxl" and not os.path.exists(tmp_excel): diff --git a/pandas/tests/io/test_pickle.py b/pandas/tests/io/test_pickle.py index 1420e24858ffb..98abbe3905204 100644 --- a/pandas/tests/io/test_pickle.py +++ b/pandas/tests/io/test_pickle.py @@ -13,7 +13,6 @@ from __future__ import annotations -from array import array import bz2 import datetime import functools @@ -32,12 +31,8 @@ import numpy as np import pytest -from pandas.compat import ( - get_lzma_file, - is_platform_little_endian, -) +from pandas.compat import is_platform_little_endian from pandas.compat._optional import import_optional_dependency -from pandas.compat.compressors import flatten_buffer import pandas as pd from pandas import ( @@ -81,35 +76,6 @@ def compare_element(result, expected, typ): # --------------------- -@pytest.mark.parametrize( - "data", - [ - b"123", - b"123456", - bytearray(b"123"), - memoryview(b"123"), - pickle.PickleBuffer(b"123"), - array("I", [1, 2, 3]), - memoryview(b"123456").cast("B", (3, 2)), - memoryview(b"123456").cast("B", (3, 2))[::2], - np.arange(12).reshape((3, 4), order="C"), - np.arange(12).reshape((3, 4), order="F"), - np.arange(12).reshape((3, 4), order="C")[:, ::2], - ], -) -def test_flatten_buffer(data): - result = flatten_buffer(data) - expected = memoryview(data).tobytes("A") - assert result == expected - if isinstance(data, (bytes, bytearray)): - assert result is data - elif isinstance(result, memoryview): - assert result.ndim == 1 - assert result.format == "B" - assert result.contiguous - assert result.shape == (result.nbytes,) - - def test_pickles(datapath): if not is_platform_little_endian(): pytest.skip("known failure on non-little endian") @@ -261,7 +227,9 @@ def compress_file(self, src_path, dest_path, compression): tarinfo = tar.gettarinfo(src_path, os.path.basename(src_path)) tar.addfile(tarinfo, fh) elif compression == "xz": - f = get_lzma_file()(dest_path, "w") + import lzma + + f = lzma.LZMAFile(dest_path, "w") elif compression == "zstd": f = import_optional_dependency("zstandard").open(dest_path, "wb") else: diff --git a/pandas/tests/scalar/timestamp/test_constructors.py b/pandas/tests/scalar/timestamp/test_constructors.py index bbda9d3ee7dce..c616f19d6f4d0 100644 --- a/pandas/tests/scalar/timestamp/test_constructors.py +++ b/pandas/tests/scalar/timestamp/test_constructors.py @@ -18,7 +18,6 @@ import pytz from pandas._libs.tslibs.dtypes import NpyDatetimeUnit -from pandas.compat import PY310 from pandas.errors import OutOfBoundsDatetime from pandas import ( @@ -211,11 +210,7 @@ def test_timestamp_constructor_adjust_value_for_fold(self, tz, fold, value_out): class TestTimestampConstructorPositionalAndKeywordSupport: def test_constructor_positional(self): # see GH#10758 - msg = ( - "'NoneType' object cannot be interpreted as an integer" - if PY310 - else "an integer is required" - ) + msg = "an integer is required" with pytest.raises(TypeError, match=msg): Timestamp(2000, 1) diff --git a/pandas/tests/test_common.py b/pandas/tests/test_common.py index bcecd1b2d5eec..7b93416600f8f 100644 --- a/pandas/tests/test_common.py +++ b/pandas/tests/test_common.py @@ -3,7 +3,6 @@ import string import subprocess import sys -import textwrap import numpy as np import pytest @@ -247,21 +246,3 @@ def test_str_size(): ] result = subprocess.check_output(call).decode()[-4:-1].strip("\n") assert int(result) == int(expected) - - -@pytest.mark.single_cpu -def test_bz2_missing_import(): - # Check whether bz2 missing import is handled correctly (issue #53857) - code = """ - import sys - sys.modules['bz2'] = None - import pytest - import pandas as pd - from pandas.compat import get_bz2_file - msg = 'bz2 module not available.' - with pytest.raises(RuntimeError, match=msg): - get_bz2_file() - """ - code = textwrap.dedent(code) - call = [sys.executable, "-c", code] - subprocess.check_output(call) diff --git a/pyproject.toml b/pyproject.toml index c438db5a80325..c88b697e85307 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -520,7 +520,6 @@ module = [ "pandas._libs.*", "pandas._testing.*", # TODO "pandas.compat.numpy.function", # TODO - "pandas.compat.compressors", # TODO "pandas.core._numba.executor", # TODO "pandas.core.array_algos.masked_reductions", # TODO "pandas.core.array_algos.putmask", # TODO From fc65cc5ec58741c7de583ea3f93a8ea00958f9f0 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Fri, 12 Apr 2024 17:08:14 -0700 Subject: [PATCH 08/16] Fix env file --- .github/workflows/unit-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 2683c7a61009c..78acb2e139b38 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -58,7 +58,7 @@ jobs: # It will be temporarily activated during tests with locale.setlocale extra_loc: "zh_CN" - name: "Pypy" - env_file: actions-pypy-310.yaml + env_file: actions-pypy-39.yaml pattern: "not slow and not network and not single_cpu" test_args: "--max-worker-restart 0" - name: "Numpy Dev" From ab17fa15eb3d7e5cd0b0f85db9e42cd6542cebec Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Fri, 12 Apr 2024 17:09:37 -0700 Subject: [PATCH 09/16] Wronge error message --- pandas/tests/scalar/timestamp/test_constructors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/scalar/timestamp/test_constructors.py b/pandas/tests/scalar/timestamp/test_constructors.py index c616f19d6f4d0..98784b4e19475 100644 --- a/pandas/tests/scalar/timestamp/test_constructors.py +++ b/pandas/tests/scalar/timestamp/test_constructors.py @@ -210,7 +210,7 @@ def test_timestamp_constructor_adjust_value_for_fold(self, tz, fold, value_out): class TestTimestampConstructorPositionalAndKeywordSupport: def test_constructor_positional(self): # see GH#10758 - msg = "an integer is required" + msg = "'NoneType' object cannot be interpreted as an integer" with pytest.raises(TypeError, match=msg): Timestamp(2000, 1) From 2402302e0facf7680eca1bd4e3e31317c7af6dd0 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Fri, 12 Apr 2024 17:16:39 -0700 Subject: [PATCH 10/16] Ignore pypy --- .github/workflows/unit-tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 78acb2e139b38..9083294b81fc1 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -146,6 +146,8 @@ jobs: - name: Build Pandas id: build uses: ./.github/actions/build_pandas + # TODO: Re-enable once Pypy has Pypy 3.10 on conda-forge + if: ${{ matrix.name != 'Pypy' }} with: meson_args: ${{ matrix.meson_args }} cflags_adds: ${{ matrix.cflags_adds }} From 709a132a8f409b40776b111a7500d2112b3eeccc Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Mon, 15 Apr 2024 10:43:36 -0700 Subject: [PATCH 11/16] Test package checks with 3.12 --- .github/workflows/package-checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/package-checks.yml b/.github/workflows/package-checks.yml index 97f90c1588962..a93b2c7907473 100644 --- a/.github/workflows/package-checks.yml +++ b/.github/workflows/package-checks.yml @@ -53,7 +53,7 @@ jobs: runs-on: ubuntu-22.04 strategy: matrix: - python-version: ['3.10', '3.11'] + python-version: ['3.10', '3.11', '3.12'] fail-fast: false name: Test Conda Forge Recipe - Python ${{ matrix.python-version }} concurrency: From 4e2a4def1ca63ae3bcca75c456dd3554d91f353f Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Mon, 15 Apr 2024 10:48:40 -0700 Subject: [PATCH 12/16] Modify subprocess test --- pandas/tests/io/test_compression.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/tests/io/test_compression.py b/pandas/tests/io/test_compression.py index 3a58dda9e8dc4..9e95781fa252c 100644 --- a/pandas/tests/io/test_compression.py +++ b/pandas/tests/io/test_compression.py @@ -231,7 +231,7 @@ def test_with_missing_lzma(): @pytest.mark.single_cpu def test_with_missing_lzma_runtime(): - """Tests if RuntimeError is hit when calling lzma without + """Tests if ModuleNotFoundError is hit when calling lzma without having the module available. """ code = textwrap.dedent( @@ -241,7 +241,7 @@ def test_with_missing_lzma_runtime(): sys.modules['lzma'] = None import pandas as pd df = pd.DataFrame() - with pytest.raises(RuntimeError, match='lzma module'): + with pytest.raises(ModuleNotFoundError, match='import of lzma'): df.to_csv('foo.csv', compression='xz') """ ) From ba2d2cf2fa102f3048245479662b1b33dabc9337 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Mon, 15 Apr 2024 10:55:59 -0700 Subject: [PATCH 13/16] revert conda-forge checks --- .github/workflows/package-checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/package-checks.yml b/.github/workflows/package-checks.yml index a93b2c7907473..97f90c1588962 100644 --- a/.github/workflows/package-checks.yml +++ b/.github/workflows/package-checks.yml @@ -53,7 +53,7 @@ jobs: runs-on: ubuntu-22.04 strategy: matrix: - python-version: ['3.10', '3.11', '3.12'] + python-version: ['3.10', '3.11'] fail-fast: false name: Test Conda Forge Recipe - Python ${{ matrix.python-version }} concurrency: From f083f68b8e547c932f7cfb03ba5de560b68c764a Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Wed, 17 Apr 2024 09:55:04 -0700 Subject: [PATCH 14/16] Remove 3.9 from circleci --- .circleci/config.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6f134c9a7a7bd..99d5ffdc10784 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -123,11 +123,9 @@ workflows: only: /^v.*/ matrix: parameters: - cibw-build: ["cp39-manylinux_aarch64", - "cp310-manylinux_aarch64", + cibw-build: ["cp310-manylinux_aarch64", "cp311-manylinux_aarch64", "cp312-manylinux_aarch64", - "cp39-musllinux_aarch64", "cp310-musllinux_aarch64", "cp311-musllinux_aarch64", "cp312-musllinux_aarch64",] From 0d8defc842046a67a10590c507333ce5b1e7c00a Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Wed, 24 Apr 2024 12:43:44 -0700 Subject: [PATCH 15/16] Pyupgrade --- pandas/core/arrays/categorical.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/arrays/categorical.py b/pandas/core/arrays/categorical.py index 6a3cf4590568c..c2e555a4a4882 100644 --- a/pandas/core/arrays/categorical.py +++ b/pandas/core/arrays/categorical.py @@ -6,7 +6,6 @@ from shutil import get_terminal_size from typing import ( TYPE_CHECKING, - Callable, Literal, cast, overload, @@ -94,6 +93,7 @@ if TYPE_CHECKING: from collections.abc import ( + Callable, Hashable, Iterator, Sequence, From 21f803820b45577bc9e4f9644b93c0b83fcd7765 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Mon, 3 Jun 2024 11:47:09 -0700 Subject: [PATCH 16/16] Don't build 39 wheels --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c88b697e85307..6f0bc84f32064 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -145,7 +145,7 @@ parentdir_prefix = "pandas-" setup = ['--vsenv'] # For Windows [tool.cibuildwheel] -skip = "cp36-* cp37-* cp38-* pp* *_i686 *_ppc64le *_s390x" +skip = "cp36-* cp37-* cp38-* cp39-* pp* *_i686 *_ppc64le *_s390x" build-verbosity = "3" environment = {LDFLAGS="-Wl,--strip-all"} test-requires = "hypothesis>=6.46.1 pytest>=7.3.2 pytest-xdist>=2.2.0"