from typing import (
    Generic,
    Literal,
)

import numpy as np
from pandas import Index
from pandas.core.accessor import DirNamesMixin
from pandas.core.arraylike import OpsMixin
from pandas.core.arrays import ExtensionArray
from pandas.core.arrays.categorical import Categorical

from pandas._typing import (
    NaPosition,
    NDFrameT,
    Scalar,
    SeriesAxisType,
    npt,
)

class PandasObject(DirNamesMixin):
    def __sizeof__(self) -> int: ...

class NoNewAttributesMixin:
    def __setattr__(self, key, value) -> None: ...

class SelectionMixin(Generic[NDFrameT]):
    def ndim(self) -> int: ...
    def __getitem__(self, key): ...

class IndexOpsMixin(OpsMixin):
    __array_priority__: int = ...
    def transpose(self, *args, **kwargs) -> IndexOpsMixin: ...
    @property
    def T(self) -> IndexOpsMixin: ...
    @property
    def shape(self) -> tuple: ...
    @property
    def ndim(self) -> int: ...
    def item(self): ...
    @property
    def nbytes(self) -> int: ...
    @property
    def size(self) -> int: ...
    @property
    def array(self) -> ExtensionArray: ...
    def to_numpy(
        self,
        dtype: npt.DTypeLike | None = ...,
        copy: bool = ...,
        na_value: Scalar = ...,
        **kwargs,
    ) -> np.ndarray: ...
    @property
    def empty(self) -> bool: ...
    def max(self, axis=..., skipna: bool = ..., **kwargs): ...
    def min(self, axis=..., skipna: bool = ..., **kwargs): ...
    def argmax(
        self, axis: SeriesAxisType | None = ..., skipna: bool = ..., *args, **kwargs
    ) -> np.ndarray: ...
    def argmin(
        self, axis: SeriesAxisType | None = ..., skipna: bool = ..., *args, **kwargs
    ) -> np.ndarray: ...
    def tolist(self) -> list: ...
    def to_list(self) -> list: ...
    def __iter__(self): ...
    @property
    def hasnans(self) -> bool: ...
    def value_counts(
        self,
        normalize: bool = ...,
        sort: bool = ...,
        ascending: bool = ...,
        bins=...,
        dropna: bool = ...,
    ): ...
    def nunique(self, dropna: bool = ...) -> int: ...
    @property
    def is_unique(self) -> bool: ...
    @property
    def is_monotonic_decreasing(self) -> bool: ...
    @property
    def is_monotonic_increasing(self) -> bool: ...
    def factorize(
        self, sort: bool = ...
    ) -> tuple[np.ndarray, np.ndarray | Index | Categorical]: ...
    def searchsorted(
        self, value, side: Literal["left", "right"] = ..., sorter=...
    ) -> int | list[int]: ...
    def drop_duplicates(
        self, *, keep: NaPosition | Literal[False] = ...
    ) -> IndexOpsMixin: ...
