From 28510eae293f6051862a28969429591927757834 Mon Sep 17 00:00:00 2001 From: MarcoGorelli <> Date: Tue, 28 Feb 2023 10:18:45 +0000 Subject: [PATCH 1/3] start enabling TCH --- pandas/_config/config.py | 11 +++++--- pandas/_testing/__init__.py | 11 ++++---- pandas/_testing/_io.py | 9 ++++--- pandas/_testing/_random.py | 5 ++-- pandas/_testing/compat.py | 5 +++- pandas/_testing/contexts.py | 13 ++++++---- pandas/_typing.py | 16 ++++++------ pandas/compat/__init__.py | 5 +++- pandas/compat/_optional.py | 5 +++- pandas/compat/numpy/function.py | 11 +++++--- pandas/core/_numba/executor.py | 4 ++- pandas/core/_numba/kernels/shared.py | 6 ++++- pandas/core/computation/expressions.py | 5 +++- pandas/core/computation/pytables.py | 9 +++++-- pandas/core/indexing.py | 9 ++++--- pandas/core/interchange/utils.py | 5 ++-- pandas/core/sample.py | 3 ++- pyproject.toml | 36 ++++++++++++++++++++++++++ typings/numba.pyi | 6 +++-- 19 files changed, 125 insertions(+), 49 deletions(-) diff --git a/pandas/_config/config.py b/pandas/_config/config.py index 4d87e8dca6d16..961da3db0ac31 100644 --- a/pandas/_config/config.py +++ b/pandas/_config/config.py @@ -56,6 +56,7 @@ ) import re from typing import ( + TYPE_CHECKING, Any, Callable, Generator, @@ -66,12 +67,14 @@ ) import warnings -from pandas._typing import ( - F, - T, -) from pandas.util._exceptions import find_stack_level +if TYPE_CHECKING: + from pandas._typing import ( + F, + T, + ) + class DeprecatedOption(NamedTuple): key: str diff --git a/pandas/_testing/__init__.py b/pandas/_testing/__init__.py index 69ca809e4f498..a82a00d3de70a 100644 --- a/pandas/_testing/__init__.py +++ b/pandas/_testing/__init__.py @@ -25,11 +25,6 @@ set_locale, ) -from pandas._typing import ( - Dtype, - Frequency, - NpDtype, -) from pandas.compat import pa_version_under7p0 from pandas.core.dtypes.common import ( @@ -118,6 +113,12 @@ from pandas.core.construction import extract_array if TYPE_CHECKING: + from pandas._typing import ( + Dtype, + Frequency, + NpDtype, + ) + from pandas import ( PeriodIndex, TimedeltaIndex, diff --git a/pandas/_testing/_io.py b/pandas/_testing/_io.py index 29618bdd64912..37a75d9f59920 100644 --- a/pandas/_testing/_io.py +++ b/pandas/_testing/_io.py @@ -13,10 +13,6 @@ ) import zipfile -from pandas._typing import ( - FilePath, - ReadPickleBuffer, -) from pandas.compat import get_lzma_file from pandas.compat._optional import import_optional_dependency @@ -27,6 +23,11 @@ from pandas.io.common import urlopen if TYPE_CHECKING: + from pandas._typing import ( + FilePath, + ReadPickleBuffer, + ) + from pandas import ( DataFrame, Series, diff --git a/pandas/_testing/_random.py b/pandas/_testing/_random.py index 7cfd92efb5d5f..7abef0f1f48cd 100644 --- a/pandas/_testing/_random.py +++ b/pandas/_testing/_random.py @@ -1,9 +1,10 @@ import string +from typing import TYPE_CHECKING import numpy as np -from pandas._typing import NpDtype - +if TYPE_CHECKING: + from pandas._typing import NpDtype RANDS_CHARS = np.array(list(string.ascii_letters + string.digits), dtype=(np.str_, 1)) diff --git a/pandas/_testing/compat.py b/pandas/_testing/compat.py index bb3bb99a4c6e4..e5a7f99edaf9e 100644 --- a/pandas/_testing/compat.py +++ b/pandas/_testing/compat.py @@ -1,10 +1,13 @@ """ Helpers for sharing tests between DataFrame/Series """ -from pandas._typing import DtypeObj +from typing import TYPE_CHECKING from pandas import DataFrame +if TYPE_CHECKING: + from pandas._typing import DtypeObj + def get_dtype(obj) -> DtypeObj: if isinstance(obj, DataFrame): diff --git a/pandas/_testing/contexts.py b/pandas/_testing/contexts.py index bf625a086b9ad..eb1e39ebd9c4d 100644 --- a/pandas/_testing/contexts.py +++ b/pandas/_testing/contexts.py @@ -6,16 +6,12 @@ import tempfile from typing import ( IO, + TYPE_CHECKING, Any, Generator, ) import uuid -from pandas._typing import ( - BaseBuffer, - CompressionOptions, - FilePath, -) from pandas.compat import PYPY from pandas.errors import ChainedAssignmentError @@ -23,6 +19,13 @@ from pandas.io.common import get_handle +if TYPE_CHECKING: + from pandas._typing import ( + BaseBuffer, + CompressionOptions, + FilePath, + ) + @contextmanager def decompress_file( diff --git a/pandas/_typing.py b/pandas/_typing.py index 6059bced4a7d4..ba524e0ff3892 100644 --- a/pandas/_typing.py +++ b/pandas/_typing.py @@ -1,11 +1,5 @@ from __future__ import annotations -from datetime import ( - datetime, - timedelta, - tzinfo, -) -from os import PathLike from typing import ( TYPE_CHECKING, Any, @@ -25,12 +19,18 @@ Union, ) -import numpy as np - # To prevent import cycles place any internal imports in the branch below # and use a string literal forward reference to it in subsequent types # https://mypy.readthedocs.io/en/latest/common_issues.html#import-cycles if TYPE_CHECKING: + from datetime import ( + datetime, + timedelta, + tzinfo, + ) + from os import PathLike + + import numpy as np import numpy.typing as npt from pandas._libs import ( diff --git a/pandas/compat/__init__.py b/pandas/compat/__init__.py index 60a9b3d4fd30e..656d5861912b4 100644 --- a/pandas/compat/__init__.py +++ b/pandas/compat/__init__.py @@ -12,8 +12,8 @@ import os import platform import sys +from typing import TYPE_CHECKING -from pandas._typing import F from pandas.compat._constants import ( IS64, PY39, @@ -33,6 +33,9 @@ pa_version_under11p0, ) +if TYPE_CHECKING: + from pandas._typing import F + def set_function_name(f: F, name: str, cls) -> F: """ diff --git a/pandas/compat/_optional.py b/pandas/compat/_optional.py index 01ac462eeb659..bcfd4ea790e64 100644 --- a/pandas/compat/_optional.py +++ b/pandas/compat/_optional.py @@ -2,13 +2,16 @@ import importlib import sys -import types +from typing import TYPE_CHECKING import warnings from pandas.util._exceptions import find_stack_level from pandas.util.version import Version +if TYPE_CHECKING: + import types + # Update install.rst & setup.cfg when updating versions! VERSIONS = { diff --git a/pandas/compat/numpy/function.py b/pandas/compat/numpy/function.py index 2c71990d74cb1..ce4f59b41f9b9 100644 --- a/pandas/compat/numpy/function.py +++ b/pandas/compat/numpy/function.py @@ -18,6 +18,7 @@ from __future__ import annotations from typing import ( + TYPE_CHECKING, Any, TypeVar, cast, @@ -30,10 +31,6 @@ is_bool, is_integer, ) -from pandas._typing import ( - Axis, - AxisInt, -) from pandas.errors import UnsupportedFunctionCall from pandas.util._validators import ( validate_args, @@ -41,6 +38,12 @@ validate_kwargs, ) +if TYPE_CHECKING: + from pandas._typing import ( + Axis, + AxisInt, + ) + AxisNoneT = TypeVar("AxisNoneT", Axis, None) diff --git a/pandas/core/_numba/executor.py b/pandas/core/_numba/executor.py index 13d8b52bae39c..891772602c442 100644 --- a/pandas/core/_numba/executor.py +++ b/pandas/core/_numba/executor.py @@ -6,9 +6,11 @@ Callable, ) +if TYPE_CHECKING: + from pandas._typing import Scalar + import numpy as np -from pandas._typing import Scalar from pandas.compat._optional import import_optional_dependency diff --git a/pandas/core/_numba/kernels/shared.py b/pandas/core/_numba/kernels/shared.py index 6e6bcef590d06..c52372fe6b08f 100644 --- a/pandas/core/_numba/kernels/shared.py +++ b/pandas/core/_numba/kernels/shared.py @@ -1,7 +1,11 @@ from __future__ import annotations +from typing import TYPE_CHECKING + import numba -import numpy as np + +if TYPE_CHECKING: + import numpy as np @numba.jit( diff --git a/pandas/core/computation/expressions.py b/pandas/core/computation/expressions.py index 2b34258982ab1..10b0670a78d6f 100644 --- a/pandas/core/computation/expressions.py +++ b/pandas/core/computation/expressions.py @@ -8,13 +8,13 @@ from __future__ import annotations import operator +from typing import TYPE_CHECKING import warnings import numpy as np from pandas._config import get_option -from pandas._typing import FuncType from pandas.util._exceptions import find_stack_level from pandas.core.computation.check import NUMEXPR_INSTALLED @@ -23,6 +23,9 @@ if NUMEXPR_INSTALLED: import numexpr as ne +if TYPE_CHECKING: + from pandas._typing import FuncType + _TEST_MODE: bool | None = None _TEST_RESULT: list[bool] = [] USE_NUMEXPR = NUMEXPR_INSTALLED diff --git a/pandas/core/computation/pytables.py b/pandas/core/computation/pytables.py index 5c8602c0291da..98ed86e8a4dec 100644 --- a/pandas/core/computation/pytables.py +++ b/pandas/core/computation/pytables.py @@ -3,7 +3,10 @@ import ast from functools import partial -from typing import Any +from typing import ( + TYPE_CHECKING, + Any, +) import numpy as np @@ -11,7 +14,6 @@ Timedelta, Timestamp, ) -from pandas._typing import npt from pandas.errors import UndefinedVariableError from pandas.core.dtypes.common import is_list_like @@ -33,6 +35,9 @@ pprint_thing_encoded, ) +if TYPE_CHECKING: + from pandas._typing import npt + class PyTablesScope(_scope.Scope): __slots__ = ("queryables",) diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 4c5bc659897d1..e710e9d03f589 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -17,10 +17,6 @@ from pandas._libs.indexing import NDFrameIndexerBase from pandas._libs.lib import item_from_zerodim -from pandas._typing import ( - Axis, - AxisInt, -) from pandas.compat import PYPY from pandas.errors import ( AbstractMethodError, @@ -79,6 +75,11 @@ ) if TYPE_CHECKING: + from pandas._typing import ( + Axis, + AxisInt, + ) + from pandas import ( DataFrame, Series, diff --git a/pandas/core/interchange/utils.py b/pandas/core/interchange/utils.py index aa717d05aecb5..7faef09d11239 100644 --- a/pandas/core/interchange/utils.py +++ b/pandas/core/interchange/utils.py @@ -9,11 +9,12 @@ import numpy as np -from pandas._typing import DtypeObj - import pandas as pd from pandas.api.types import is_datetime64_dtype +if typing.TYPE_CHECKING: + from pandas._typing import DtypeObj + class ArrowCTypes: """ diff --git a/pandas/core/sample.py b/pandas/core/sample.py index a9b236b58a9ba..eebbed3512c4e 100644 --- a/pandas/core/sample.py +++ b/pandas/core/sample.py @@ -8,7 +8,6 @@ import numpy as np from pandas._libs import lib -from pandas._typing import AxisInt from pandas.core.dtypes.generic import ( ABCDataFrame, @@ -16,6 +15,8 @@ ) if TYPE_CHECKING: + from pandas._typing import AxisInt + from pandas.core.generic import NDFrame diff --git a/pyproject.toml b/pyproject.toml index baffbd18329ff..c8c84f8c794ec 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -218,6 +218,8 @@ select = [ "TID", # implicit string concatenation "ISC", + # type-checking imports + "TCH", ] ignore = [ @@ -282,6 +284,40 @@ exclude = [ [tool.ruff.per-file-ignores] # relative imports allowed for asv_bench "asv_bench/*" = ["TID"] +# TCH to be enabled gradually +"pandas/core/arrays/*" = ["TCH"] +"pandas/core/io/*" = ["TCH"] +"pandas/core/indexers/*" = ["TCH"] +"pandas/core/indexes/*" = ["TCH"] +"pandas/core/internals/*" = ["TCH"] +"pandas/core/groupby/*" = ["TCH"] +"pandas/core/methods/*" = ["TCH"] +"pandas/core/array_algos/*" = ["TCH"] +"pandas/core/dtypes/*" = ["TCH"] +"pandas/core/generic.py" = ["TCH"] +"pandas/core/frame.py" = ["TCH"] +"pandas/core/series.py" = ["TCH"] +"pandas/core/resample.py" = ["TCH"] +"pandas/core/nanops.py" = ["TCH"] +"pandas/core/apply.py" = ["TCH"] +"pandas/core/base.py" = ["TCH"] +"pandas/core/algorithms.py" = ["TCH"] +"pandas/core/ops/*" = ["TCH"] +"pandas/core/sorting.py" = ["TCH"] +"pandas/core/construction.py" = ["TCH"] +"pandas/core/common.py" = ["TCH"] +"pandas/core/missing.py" = ["TCH"] +"pandas/core/util/*" = ["TCH"] +"pandas/core/reshape/*" = ["TCH"] +"pandas/core/strings/*" = ["TCH"] +"pandas/core/tools/*" = ["TCH"] +"pandas/core/window/*" = ["TCH"] +"pandas/io/*" = ["TCH"] +"pandas/tseries/*" = ["TCH"] +"pandas/tests/*" = ["TCH"] +"pandas/plotting/*" = ["TCH"] +"pandas/util/*" = ["TCH"] +"pandas/_libs/*" = ["TCH"] [tool.pylint.messages_control] max-line-length = 88 diff --git a/typings/numba.pyi b/typings/numba.pyi index 36cccb894049b..0d9184af19a0f 100644 --- a/typings/numba.pyi +++ b/typings/numba.pyi @@ -1,14 +1,16 @@ # pyright: reportIncompleteStub = false from typing import ( + TYPE_CHECKING, Any, Callable, Literal, overload, ) -import numba +if TYPE_CHECKING: + import numba -from pandas._typing import F + from pandas._typing import F def __getattr__(name: str) -> Any: ... # incomplete @overload From d4a84c1c6bc271656a24904e96803d16aea21f91 Mon Sep 17 00:00:00 2001 From: MarcoGorelli <> Date: Tue, 28 Feb 2023 10:36:07 +0000 Subject: [PATCH 2/3] fixup --- pandas/_config/config.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pandas/_config/config.py b/pandas/_config/config.py index 961da3db0ac31..a5b6fc198c4ac 100644 --- a/pandas/_config/config.py +++ b/pandas/_config/config.py @@ -67,13 +67,11 @@ ) import warnings +from pandas._typing import T # noqa: TCH001 from pandas.util._exceptions import find_stack_level if TYPE_CHECKING: - from pandas._typing import ( - F, - T, - ) + from pandas._typing import F class DeprecatedOption(NamedTuple): From c3154ad30d5ee44f2c5d3c0a817ae9c972599efd Mon Sep 17 00:00:00 2001 From: MarcoGorelli <> Date: Tue, 28 Feb 2023 10:42:05 +0000 Subject: [PATCH 3/3] fixup --- pandas/_config/config.py | 5 +---- pandas/_testing/_random.py | 2 ++ pandas/_testing/compat.py | 2 ++ pandas/_typing.py | 16 ++++++++-------- pandas/compat/numpy/function.py | 2 +- pyproject.toml | 2 ++ 6 files changed, 16 insertions(+), 13 deletions(-) diff --git a/pandas/_config/config.py b/pandas/_config/config.py index a5b6fc198c4ac..0149ea545a4c5 100644 --- a/pandas/_config/config.py +++ b/pandas/_config/config.py @@ -56,7 +56,6 @@ ) import re from typing import ( - TYPE_CHECKING, Any, Callable, Generator, @@ -67,12 +66,10 @@ ) import warnings +from pandas._typing import F # noqa: TCH001 from pandas._typing import T # noqa: TCH001 from pandas.util._exceptions import find_stack_level -if TYPE_CHECKING: - from pandas._typing import F - class DeprecatedOption(NamedTuple): key: str diff --git a/pandas/_testing/_random.py b/pandas/_testing/_random.py index 7abef0f1f48cd..f0a0437a5bfc6 100644 --- a/pandas/_testing/_random.py +++ b/pandas/_testing/_random.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import string from typing import TYPE_CHECKING diff --git a/pandas/_testing/compat.py b/pandas/_testing/compat.py index e5a7f99edaf9e..cc352ba7b8f2f 100644 --- a/pandas/_testing/compat.py +++ b/pandas/_testing/compat.py @@ -1,6 +1,8 @@ """ Helpers for sharing tests between DataFrame/Series """ +from __future__ import annotations + from typing import TYPE_CHECKING from pandas import DataFrame diff --git a/pandas/_typing.py b/pandas/_typing.py index ba524e0ff3892..6059bced4a7d4 100644 --- a/pandas/_typing.py +++ b/pandas/_typing.py @@ -1,5 +1,11 @@ from __future__ import annotations +from datetime import ( + datetime, + timedelta, + tzinfo, +) +from os import PathLike from typing import ( TYPE_CHECKING, Any, @@ -19,18 +25,12 @@ Union, ) +import numpy as np + # To prevent import cycles place any internal imports in the branch below # and use a string literal forward reference to it in subsequent types # https://mypy.readthedocs.io/en/latest/common_issues.html#import-cycles if TYPE_CHECKING: - from datetime import ( - datetime, - timedelta, - tzinfo, - ) - from os import PathLike - - import numpy as np import numpy.typing as npt from pandas._libs import ( diff --git a/pandas/compat/numpy/function.py b/pandas/compat/numpy/function.py index ce4f59b41f9b9..bdd26b315ed83 100644 --- a/pandas/compat/numpy/function.py +++ b/pandas/compat/numpy/function.py @@ -44,7 +44,7 @@ AxisInt, ) -AxisNoneT = TypeVar("AxisNoneT", Axis, None) + AxisNoneT = TypeVar("AxisNoneT", Axis, None) class CompatValidator: diff --git a/pyproject.toml b/pyproject.toml index c8c84f8c794ec..6457db4524d22 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -318,6 +318,8 @@ exclude = [ "pandas/plotting/*" = ["TCH"] "pandas/util/*" = ["TCH"] "pandas/_libs/*" = ["TCH"] +# Keep this one enabled +"pandas/_typing.py" = ["TCH"] [tool.pylint.messages_control] max-line-length = 88