Repository: pandas-dev/pandas
File: pandas/_typing.py (Python)

Code before:
    # Name "npt._ArrayLikeInt_co" is not defined  [name-defined]
    NumpySorter: TypeAlias = npt._ArrayLikeInt_co | None  # type: ignore[name-defined]

    from typing import (
        ParamSpec,
        SupportsIndex,
    )
    from typing import Concatenate  # pyright: ignore[reportUnusedImport]
    from typing import TypeGuard  # pyright: ignore[reportUnusedImport]

    P = ParamSpec("P")
else:
    ParamSpec: Any = None
    TypeGuard: Any = None
    Concatenate: Any = None

HashableT = TypeVar("HashableT", bound=Hashable)
HashableT2 = TypeVar("HashableT2", bound=Hashable)
MutableMappingT = TypeVar("MutableMappingT", bound=MutableMapping)

# array-like

ArrayLike: TypeAlias = Union["ExtensionArray", np.ndarray]
ArrayLikeT = TypeVar("ArrayLikeT", "ExtensionArray", np.ndarray)
AnyArrayLike: TypeAlias = Union[ArrayLike, "Index", "Series"]
TimeArrayLike: TypeAlias = Union["DatetimeArray", "TimedeltaArray"]

# list-like

# from https://github.com/hauntsaninja/useful_types
# includes Sequence-like objects but excludes str and bytes
_T_co = TypeVar("_T_co", covariant=True)


class SequenceNotStr(Protocol[_T_co]):
    @overload
    def __getitem__(self, index: SupportsIndex, /) -> _T_co: ...

    @overload
    def __getitem__(self, index: slice, /) -> Sequence[_T_co]: ...

    def __contains__(self, value: object, /) -> bool: ...

    def __len__(self) -> int: ...

    def __iter__(self) -> Iterator[_T_co]: ...

    def index(self, value: Any, start: int = ..., stop: int = ..., /) -> int: ...

    def count(self, value: Any, /) -> int: ...


Review comment (suggestion):
Should test always importing `Self` and `Unpack` from `typing` whether or not we are doing `TYPE_CHECKING` and then other modules that import those symbols from `_typing` will have access to them, as they should work at runtime.

I don't think it's a good idea to change `Self` and `Unpack` to `Any` at runtime.

Code after:
    # numpy compatible types
    NumpyValueArrayLike: TypeAlias = ScalarLike_co | npt.ArrayLike
    # Name "npt._ArrayLikeInt_co" is not defined  [name-defined]
    NumpySorter: TypeAlias = npt._ArrayLikeInt_co | None  # type: ignore[name-defined]


P = ParamSpec("P")

HashableT = TypeVar("HashableT", bound=Hashable)
HashableT2 = TypeVar("HashableT2", bound=Hashable)
MutableMappingT = TypeVar("MutableMappingT", bound=MutableMapping)

# array-like

ArrayLike: TypeAlias = Union["ExtensionArray", np.ndarray]
ArrayLikeT = TypeVar("ArrayLikeT", "ExtensionArray", np.ndarray)
AnyArrayLike: TypeAlias = Union[ArrayLike, "Index", "Series"]
TimeArrayLike: TypeAlias = Union["DatetimeArray", "TimedeltaArray"]

# list-like

# from https://github.com/hauntsaninja/useful_types
# includes Sequence-like objects but excludes str and bytes
_T_co = TypeVar("_T_co", covariant=True)


class SequenceNotStr(Protocol[_T_co]):
    @overload
    def __getitem__(self, index: SupportsIndex, /) -> _T_co: ...

    @overload
    def __getitem__(self, index: slice, /) -> Sequence[_T_co]: ...

    def __contains__(self, value: object, /) -> bool: ...

    def __len__(self) -> int: ...

    def __iter__(self) -> Iterator[_T_co]: ...

    def index(self, value: Any, start: int = ..., stop: int = ..., /) -> int: ...

    def count(self, value: Any, /) -> int: ...

    def __reversed__(self) -> Iterator[_T_co]: ...


ListLike: TypeAlias = AnyArrayLike | SequenceNotStr | range

# scalars

PythonScalar: TypeAlias = str | float | bool