from collections.abc import Callable, Sequence
from typing import Any, Literal, overload

from numpy.typing import NDArray
from typing_extensions import TypeAlias

# This file mirrors all the definitions made in the polars-python Rust API.

__version__: str
__build__: Any
_ir_nodes: Any
_allocator: Any
_debug: bool

CompatLevel: TypeAlias = int | bool
BufferInfo: TypeAlias = tuple[int, int, int]
UnicodeForm: TypeAlias = Literal["NFC", "NFKC", "NFD", "NFKD"]
KeyValueMetadata: TypeAlias = Sequence[tuple[str, str]] | Any
TimeZone: TypeAlias = str | None
UpcastOrForbid: TypeAlias = Literal["upcast", "forbid"]
ExtraColumnsPolicy: TypeAlias = Literal["ignore", "raise"]
MissingColumnsPolicy: TypeAlias = Literal["insert", "raise"]
MissingColumnsPolicyOrExpr: TypeAlias = Literal["insert", "raise"] | Any
ColumnMapping: TypeAlias = Any
DeletionFilesList: TypeAlias = Any
DefaultFieldValues: TypeAlias = Any
Path: TypeAlias = str | Any
Schema: TypeAlias = Any
NullValues: TypeAlias = Any
DataType: TypeAlias = Any
SyncOnCloseType: TypeAlias = Literal["none", "data", "all"]
SinkOptions: TypeAlias = dict[str, Any]
SinkTarget: TypeAlias = str | Any | PyPartitioning
AsofStrategy: TypeAlias = Literal["backward", "forward", "nearest"]
InterpolationMethod: TypeAlias = Literal["linear", "nearest"]
AvroCompression: TypeAlias = Literal["uncompressed", "snappy", "deflate"]
CategoricalOrdering: TypeAlias = Literal["physical", "lexical"]
StartBy: TypeAlias = Literal[
    "window",
    "datapoint",
    "monday",
    "tuesday",
    "wednesday",
    "thursday",
    "friday",
    "saturday",
    "sunday",
]
ClosedWindow: TypeAlias = Literal["left", "right", "both", "none"]
RoundMode: TypeAlias = Literal["half_to_even", "half_away_from_zero"]
CsvEncoding: TypeAlias = Literal["utf8", "utf8-lossy"]
IpcCompression: TypeAlias = Literal["uncompressed", "lz4", "zstd"]
JoinType: TypeAlias = Literal["inner", "left", "right", "full", "semi", "anti", "cross"]
Label: TypeAlias = Literal["left", "right", "datapoint"]
ListToStructWidthStrategy: TypeAlias = Literal["first_non_null", "max_width"]
NonExistent: TypeAlias = Literal["null", "raise"]
NullBehavior: TypeAlias = Literal["drop", "ignore"]
NullStrategy: TypeAlias = Literal["ignore", "propagate"]
ParallelStrategy: TypeAlias = Literal[
    "auto", "columns", "row_groups", "prefiltered", "none"
]
IndexOrder: TypeAlias = Literal["fortran", "c"]
QuantileMethod: TypeAlias = Literal[
    "lower", "higher", "nearest", "linear", "midpoint", "equiprobable"
]
RankMethod: TypeAlias = Literal["min", "max", "average", "dense", "ordinal", "random"]
Roll: TypeAlias = Literal["raise", "forward", "backward"]
TimeUnit: TypeAlias = Literal["ns", "us", "ms"]
UniqueKeepStrategy: TypeAlias = Literal["first", "last", "any", "none"]
SearchSortedSide: TypeAlias = Literal["any", "left", "right"]
ClosedInterval: TypeAlias = Literal["both", "left", "right", "none"]
WindowMapping: TypeAlias = Literal["group_to_rows", "join", "explode"]
JoinValidation: TypeAlias = Literal["m:m", "m:1", "1:m", "1:1"]
MaintainOrderJoin: TypeAlias = Literal[
    "none", "left", "right", "left_right", "right_left"
]
QuoteStyle: TypeAlias = Literal["always", "necessary", "non_numeric", "never"]
SetOperation: TypeAlias = Literal[
    "union", "difference", "intersection", "symmetric_difference"
]
FloatFmt: TypeAlias = Literal["full", "mixed"]
NDArray1D: TypeAlias = NDArray[Any]
ParquetFieldOverwrites: Any
StatisticsOptions: Any
EngineType: TypeAlias = Literal["auto", "in-memory", "streaming", "gpu"]
PyScanOptions: TypeAlias = Any

# exceptions
class PolarsError(Exception): ...
class ColumnNotFoundError(PolarsError): ...
class ComputeError(PolarsError): ...
class DuplicateError(PolarsError): ...
class InvalidOperationError(PolarsError): ...
class NoDataError(PolarsError): ...
class OutOfBoundsError(PolarsError): ...
class SQLInterfaceError(PolarsError): ...
class SQLSyntaxError(PolarsError): ...
class SchemaError(PolarsError): ...
class SchemaFieldNotFoundError(PolarsError): ...
class ShapeError(PolarsError): ...
class StringCacheMismatchError(PolarsError): ...
class StructFieldNotFoundError(PolarsError): ...
class PolarsWarning(Warning): ...
class PerformanceWarning(PolarsWarning): ...
class CategoricalRemappingWarning(PerformanceWarning): ...
class MapWithoutReturnDtypeWarning(PolarsWarning): ...
class PanicException(PolarsError): ...

class PySeries:
    # map
    def map_elements(
        self, function: Any, return_dtype: Any | None, skip_nulls: bool
    ) -> PySeries: ...

    # general
    def struct_unnest(self) -> PyDataFrame: ...
    def struct_fields(self) -> list[str]: ...
    def is_sorted_ascending_flag(self) -> bool: ...
    def is_sorted_descending_flag(self) -> bool: ...
    def can_fast_explode_flag(self) -> bool: ...
    def cat_uses_lexical_ordering(self) -> bool: ...
    def cat_is_local(self) -> bool: ...
    def cat_to_local(self) -> PySeries: ...
    def estimated_size(self) -> int: ...
    def get_object(self, index: int) -> Any: ...
    def reshape(self, dims: Sequence[int]) -> PySeries: ...
    def get_fmt(self, index: int, str_len_limit: int) -> str: ...
    def rechunk(self, in_place: bool) -> PySeries | None: ...
    def get_index(self, index: int) -> Any: ...
    def get_index_signed(self, index: int) -> Any: ...
    def bitand(self, other: PySeries) -> PySeries: ...
    def bitor(self, other: PySeries) -> PySeries: ...
    def bitxor(self, other: PySeries) -> PySeries: ...
    def chunk_lengths(self) -> list[int]: ...
    def name(self) -> str: ...
    def rename(self, name: str) -> None: ...
    def dtype(self) -> Any: ...
    def set_sorted_flag(self, descending: bool) -> PySeries: ...
    def n_chunks(self) -> int: ...
    def append(self, other: PySeries) -> None: ...
    def extend(self, other: PySeries) -> None: ...
    def new_from_index(self, index: int, length: int) -> PySeries: ...
    def filter(self, filter: PySeries) -> PySeries: ...
    def sort(
        self, descending: bool, nulls_last: bool, multithreaded: bool
    ) -> PySeries: ...
    def gather_with_series(self, indices: PySeries) -> PySeries: ...
    def null_count(self) -> int: ...
    def has_nulls(self) -> bool: ...
    def equals(
        self, other: PySeries, check_dtypes: bool, check_names: bool, null_equal: bool
    ) -> bool: ...
    def as_str(self) -> str: ...
    def len(self) -> int: ...
    def as_single_ptr(self) -> int: ...
    def clone(self) -> PySeries: ...
    def zip_with(self, mask: PySeries, other: PySeries) -> PySeries: ...
    def to_dummies(
        self, separator: str | None, drop_first: bool, drop_nulls: bool
    ) -> PyDataFrame: ...
    def get_list(self, index: int) -> PySeries | None: ...
    def n_unique(self) -> int: ...
    def floor(self) -> PySeries: ...
    def shrink_to_fit(self) -> None: ...
    def dot(self, other: PySeries) -> Any: ...
    def __getstate__(self) -> bytes: ...
    def __setstate__(self, state: bytes) -> None: ...
    def skew(self, bias: bool) -> float | None: ...
    def kurtosis(self, fisher: bool, bias: bool) -> float | None: ...
    def cast(self, dtype: Any, strict: bool, wrap_numerical: bool) -> PySeries: ...
    def get_chunks(self) -> list[Any]: ...
    def is_sorted(self, descending: bool, nulls_last: bool) -> bool: ...
    def clear(self) -> PySeries: ...
    def head(self, n: int) -> PySeries: ...
    def tail(self, n: int) -> PySeries: ...
    def value_counts(
        self, sort: bool, parallel: bool, name: str, normalize: bool
    ) -> PyDataFrame: ...
    def slice(self, offset: int, length: int | None) -> PySeries: ...
    def not_(self) -> PySeries: ...
    def shrink_dtype(self) -> PySeries: ...
    def str_to_datetime_infer(
        self,
        time_unit: TimeUnit | None,
        strict: bool,
        exact: bool,
        ambiguous: PySeries,
    ) -> PySeries: ...
    def str_to_decimal_infer(self, inference_length: int) -> PySeries: ...
    def list_to_struct(
        self, width_strat: ListToStructWidthStrategy, name_gen: Any | None
    ) -> PySeries: ...
    def str_json_decode(self, infer_schema_length: int | None) -> PySeries: ...

    # aggregations
    def any(self, ignore_nulls: bool) -> bool | None: ...
    def all(self, ignore_nulls: bool) -> bool | None: ...
    def arg_max(self) -> int | None: ...
    def arg_min(self) -> int | None: ...
    def min(self) -> Any: ...
    def max(self) -> Any: ...
    def mean(self) -> Any: ...
    def median(self) -> Any: ...
    def product(self) -> Any: ...
    def quantile(self, quantile: float, interpolation: QuantileMethod) -> Any: ...
    def std(self, ddof: int) -> Any: ...
    def var(self, ddof: int) -> Any: ...
    def sum(self) -> Any: ...
    def first(self) -> Any: ...
    def last(self) -> Any: ...
    def approx_n_unique(self) -> int: ...
    def bitwise_and(self) -> Any: ...
    def bitwise_or(self) -> Any: ...
    def bitwise_xor(self) -> Any: ...

    # arithmetic
    # Operations with another PySeries
    def add(self, other: PySeries) -> PySeries: ...
    def sub(self, other: PySeries) -> PySeries: ...
    def mul(self, other: PySeries) -> PySeries: ...
    def div(self, other: PySeries) -> PySeries: ...
    def rem(self, other: PySeries) -> PySeries: ...

    # Operations with integer/float/datetime/duration scalars
    def add_u8(self, other: int) -> PySeries: ...
    def add_u16(self, other: int) -> PySeries: ...
    def add_u32(self, other: int) -> PySeries: ...
    def add_u64(self, other: int) -> PySeries: ...
    def add_i8(self, other: int) -> PySeries: ...
    def add_i16(self, other: int) -> PySeries: ...
    def add_i32(self, other: int) -> PySeries: ...
    def add_i64(self, other: int) -> PySeries: ...
    def add_datetime(self, other: int) -> PySeries: ...
    def add_duration(self, other: int) -> PySeries: ...
    def add_f32(self, other: float) -> PySeries: ...
    def add_f64(self, other: float) -> PySeries: ...
    def sub_u8(self, other: int) -> PySeries: ...
    def sub_u16(self, other: int) -> PySeries: ...
    def sub_u32(self, other: int) -> PySeries: ...
    def sub_u64(self, other: int) -> PySeries: ...
    def sub_i8(self, other: int) -> PySeries: ...
    def sub_i16(self, other: int) -> PySeries: ...
    def sub_i32(self, other: int) -> PySeries: ...
    def sub_i64(self, other: int) -> PySeries: ...
    def sub_datetime(self, other: int) -> PySeries: ...
    def sub_duration(self, other: int) -> PySeries: ...
    def sub_f32(self, other: float) -> PySeries: ...
    def sub_f64(self, other: float) -> PySeries: ...
    def div_u8(self, other: int) -> PySeries: ...
    def div_u16(self, other: int) -> PySeries: ...
    def div_u32(self, other: int) -> PySeries: ...
    def div_u64(self, other: int) -> PySeries: ...
    def div_i8(self, other: int) -> PySeries: ...
    def div_i16(self, other: int) -> PySeries: ...
    def div_i32(self, other: int) -> PySeries: ...
    def div_i64(self, other: int) -> PySeries: ...
    def div_f32(self, other: float) -> PySeries: ...
    def div_f64(self, other: float) -> PySeries: ...
    def mul_u8(self, other: int) -> PySeries: ...
    def mul_u16(self, other: int) -> PySeries: ...
    def mul_u32(self, other: int) -> PySeries: ...
    def mul_u64(self, other: int) -> PySeries: ...
    def mul_i8(self, other: int) -> PySeries: ...
    def mul_i16(self, other: int) -> PySeries: ...
    def mul_i32(self, other: int) -> PySeries: ...
    def mul_i64(self, other: int) -> PySeries: ...
    def mul_f32(self, other: float) -> PySeries: ...
    def mul_f64(self, other: float) -> PySeries: ...
    def rem_u8(self, other: int) -> PySeries: ...
    def rem_u16(self, other: int) -> PySeries: ...
    def rem_u32(self, other: int) -> PySeries: ...
    def rem_u64(self, other: int) -> PySeries: ...
    def rem_i8(self, other: int) -> PySeries: ...
    def rem_i16(self, other: int) -> PySeries: ...
    def rem_i32(self, other: int) -> PySeries: ...
    def rem_i64(self, other: int) -> PySeries: ...
    def rem_f32(self, other: float) -> PySeries: ...
    def rem_f64(self, other: float) -> PySeries: ...

    # Reverse operations (rhs)
    def add_u8_rhs(self, other: int) -> PySeries: ...
    def add_u16_rhs(self, other: int) -> PySeries: ...
    def add_u32_rhs(self, other: int) -> PySeries: ...
    def add_u64_rhs(self, other: int) -> PySeries: ...
    def add_i8_rhs(self, other: int) -> PySeries: ...
    def add_i16_rhs(self, other: int) -> PySeries: ...
    def add_i32_rhs(self, other: int) -> PySeries: ...
    def add_i64_rhs(self, other: int) -> PySeries: ...
    def add_f32_rhs(self, other: float) -> PySeries: ...
    def add_f64_rhs(self, other: float) -> PySeries: ...
    def sub_u8_rhs(self, other: int) -> PySeries: ...
    def sub_u16_rhs(self, other: int) -> PySeries: ...
    def sub_u32_rhs(self, other: int) -> PySeries: ...
    def sub_u64_rhs(self, other: int) -> PySeries: ...
    def sub_i8_rhs(self, other: int) -> PySeries: ...
    def sub_i16_rhs(self, other: int) -> PySeries: ...
    def sub_i32_rhs(self, other: int) -> PySeries: ...
    def sub_i64_rhs(self, other: int) -> PySeries: ...
    def sub_f32_rhs(self, other: float) -> PySeries: ...
    def sub_f64_rhs(self, other: float) -> PySeries: ...
    def div_u8_rhs(self, other: int) -> PySeries: ...
    def div_u16_rhs(self, other: int) -> PySeries: ...
    def div_u32_rhs(self, other: int) -> PySeries: ...
    def div_u64_rhs(self, other: int) -> PySeries: ...
    def div_i8_rhs(self, other: int) -> PySeries: ...
    def div_i16_rhs(self, other: int) -> PySeries: ...
    def div_i32_rhs(self, other: int) -> PySeries: ...
    def div_i64_rhs(self, other: int) -> PySeries: ...
    def div_f32_rhs(self, other: float) -> PySeries: ...
    def div_f64_rhs(self, other: float) -> PySeries: ...
    def mul_u8_rhs(self, other: int) -> PySeries: ...
    def mul_u16_rhs(self, other: int) -> PySeries: ...
    def mul_u32_rhs(self, other: int) -> PySeries: ...
    def mul_u64_rhs(self, other: int) -> PySeries: ...
    def mul_i8_rhs(self, other: int) -> PySeries: ...
    def mul_i16_rhs(self, other: int) -> PySeries: ...
    def mul_i32_rhs(self, other: int) -> PySeries: ...
    def mul_i64_rhs(self, other: int) -> PySeries: ...
    def mul_f32_rhs(self, other: float) -> PySeries: ...
    def mul_f64_rhs(self, other: float) -> PySeries: ...
    def rem_u8_rhs(self, other: int) -> PySeries: ...
    def rem_u16_rhs(self, other: int) -> PySeries: ...
    def rem_u32_rhs(self, other: int) -> PySeries: ...
    def rem_u64_rhs(self, other: int) -> PySeries: ...
    def rem_i8_rhs(self, other: int) -> PySeries: ...
    def rem_i16_rhs(self, other: int) -> PySeries: ...
    def rem_i32_rhs(self, other: int) -> PySeries: ...
    def rem_i64_rhs(self, other: int) -> PySeries: ...
    def rem_f32_rhs(self, other: float) -> PySeries: ...
    def rem_f64_rhs(self, other: float) -> PySeries: ...

    # buffers
    @staticmethod
    def _from_buffers(
        dtype: Any,
        data: Sequence[PySeries],
        validity: PySeries | None,
    ) -> PySeries: ...
    @staticmethod
    def _from_buffer(
        dtype: DataType,
        buffer_info: BufferInfo,
        owner: Any,
    ) -> PySeries: ...
    def _get_buffer_info(self) -> BufferInfo: ...
    def _get_buffers(self) -> tuple[PySeries, PySeries | None, PySeries | None]: ...

    # c_interface
    @staticmethod
    def _import_arrow_from_c(
        name: str, chunks: Sequence[tuple[int, int]]
    ) -> PySeries: ...
    def _export_arrow_to_c(self, out_ptr: int, out_schema_ptr: int) -> None: ...

    # comparison
    # Comparison with another PySeries
    def eq(self, rhs: PySeries) -> PySeries: ...
    def neq(self, rhs: PySeries) -> PySeries: ...
    def gt(self, rhs: PySeries) -> PySeries: ...
    def gt_eq(self, rhs: PySeries) -> PySeries: ...
    def lt(self, rhs: PySeries) -> PySeries: ...
    def lt_eq(self, rhs: PySeries) -> PySeries: ...

    # Comparison with scalar values
    def eq_u8(self, rhs: int) -> PySeries: ...
    def eq_u16(self, rhs: int) -> PySeries: ...
    def eq_u32(self, rhs: int) -> PySeries: ...
    def eq_u64(self, rhs: int) -> PySeries: ...
    def eq_i8(self, rhs: int) -> PySeries: ...
    def eq_i16(self, rhs: int) -> PySeries: ...
    def eq_i32(self, rhs: int) -> PySeries: ...
    def eq_i64(self, rhs: int) -> PySeries: ...
    def eq_i128(self, rhs: int) -> PySeries: ...
    def eq_f32(self, rhs: float) -> PySeries: ...
    def eq_f64(self, rhs: float) -> PySeries: ...
    def eq_str(self, rhs: str) -> PySeries: ...
    def eq_decimal(self, rhs: Any) -> PySeries: ...
    def neq_u8(self, rhs: int) -> PySeries: ...
    def neq_u16(self, rhs: int) -> PySeries: ...
    def neq_u32(self, rhs: int) -> PySeries: ...
    def neq_u64(self, rhs: int) -> PySeries: ...
    def neq_i8(self, rhs: int) -> PySeries: ...
    def neq_i16(self, rhs: int) -> PySeries: ...
    def neq_i32(self, rhs: int) -> PySeries: ...
    def neq_i64(self, rhs: int) -> PySeries: ...
    def neq_i128(self, rhs: int) -> PySeries: ...
    def neq_f32(self, rhs: float) -> PySeries: ...
    def neq_f64(self, rhs: float) -> PySeries: ...
    def neq_str(self, rhs: str) -> PySeries: ...
    def neq_decimal(self, rhs: Any) -> PySeries: ...
    def gt_u8(self, rhs: int) -> PySeries: ...
    def gt_u16(self, rhs: int) -> PySeries: ...
    def gt_u32(self, rhs: int) -> PySeries: ...
    def gt_u64(self, rhs: int) -> PySeries: ...
    def gt_i8(self, rhs: int) -> PySeries: ...
    def gt_i16(self, rhs: int) -> PySeries: ...
    def gt_i32(self, rhs: int) -> PySeries: ...
    def gt_i64(self, rhs: int) -> PySeries: ...
    def gt_i128(self, rhs: int) -> PySeries: ...
    def gt_f32(self, rhs: float) -> PySeries: ...
    def gt_f64(self, rhs: float) -> PySeries: ...
    def gt_str(self, rhs: str) -> PySeries: ...
    def gt_decimal(self, rhs: Any) -> PySeries: ...
    def gt_eq_u8(self, rhs: int) -> PySeries: ...
    def gt_eq_u16(self, rhs: int) -> PySeries: ...
    def gt_eq_u32(self, rhs: int) -> PySeries: ...
    def gt_eq_u64(self, rhs: int) -> PySeries: ...
    def gt_eq_i8(self, rhs: int) -> PySeries: ...
    def gt_eq_i16(self, rhs: int) -> PySeries: ...
    def gt_eq_i32(self, rhs: int) -> PySeries: ...
    def gt_eq_i64(self, rhs: int) -> PySeries: ...
    def gt_eq_i128(self, rhs: int) -> PySeries: ...
    def gt_eq_f32(self, rhs: float) -> PySeries: ...
    def gt_eq_f64(self, rhs: float) -> PySeries: ...
    def gt_eq_str(self, rhs: str) -> PySeries: ...
    def gt_eq_decimal(self, rhs: Any) -> PySeries: ...
    def lt_u8(self, rhs: int) -> PySeries: ...
    def lt_u16(self, rhs: int) -> PySeries: ...
    def lt_u32(self, rhs: int) -> PySeries: ...
    def lt_u64(self, rhs: int) -> PySeries: ...
    def lt_i8(self, rhs: int) -> PySeries: ...
    def lt_i16(self, rhs: int) -> PySeries: ...
    def lt_i32(self, rhs: int) -> PySeries: ...
    def lt_i64(self, rhs: int) -> PySeries: ...
    def lt_i128(self, rhs: int) -> PySeries: ...
    def lt_f32(self, rhs: float) -> PySeries: ...
    def lt_f64(self, rhs: float) -> PySeries: ...
    def lt_str(self, rhs: str) -> PySeries: ...
    def lt_decimal(self, rhs: Any) -> PySeries: ...
    def lt_eq_u8(self, rhs: int) -> PySeries: ...
    def lt_eq_u16(self, rhs: int) -> PySeries: ...
    def lt_eq_u32(self, rhs: int) -> PySeries: ...
    def lt_eq_u64(self, rhs: int) -> PySeries: ...
    def lt_eq_i8(self, rhs: int) -> PySeries: ...
    def lt_eq_i16(self, rhs: int) -> PySeries: ...
    def lt_eq_i32(self, rhs: int) -> PySeries: ...
    def lt_eq_i64(self, rhs: int) -> PySeries: ...
    def lt_eq_i128(self, rhs: int) -> PySeries: ...
    def lt_eq_f32(self, rhs: float) -> PySeries: ...
    def lt_eq_f64(self, rhs: float) -> PySeries: ...
    def lt_eq_str(self, rhs: str) -> PySeries: ...
    def lt_eq_decimal(self, rhs: Any) -> PySeries: ...

    # construction
    @staticmethod
    def new_i8(name: str, array: NDArray1D, _strict: bool) -> PySeries: ...
    @staticmethod
    def new_i16(name: str, array: NDArray1D, _strict: bool) -> PySeries: ...
    @staticmethod
    def new_i32(name: str, array: NDArray1D, _strict: bool) -> PySeries: ...
    @staticmethod
    def new_i64(name: str, array: NDArray1D, _strict: bool) -> PySeries: ...
    @staticmethod
    def new_u8(name: str, array: NDArray1D, _strict: bool) -> PySeries: ...
    @staticmethod
    def new_u16(name: str, array: NDArray1D, _strict: bool) -> PySeries: ...
    @staticmethod
    def new_u32(name: str, array: NDArray1D, _strict: bool) -> PySeries: ...
    @staticmethod
    def new_u64(name: str, array: NDArray1D, _strict: bool) -> PySeries: ...
    @staticmethod
    def new_bool(name: str, array: NDArray1D, _strict: bool) -> PySeries: ...
    @staticmethod
    def new_f32(name: str, array: NDArray1D, nan_is_null: bool) -> PySeries: ...
    @staticmethod
    def new_f64(name: str, array: NDArray1D, nan_is_null: bool) -> PySeries: ...
    @staticmethod
    def new_opt_bool(name: str, values: Any, _strict: bool) -> PySeries: ...
    @staticmethod
    def new_opt_u8(name: str, obj: Any, strict: bool) -> PySeries: ...
    @staticmethod
    def new_opt_u16(name: str, obj: Any, strict: bool) -> PySeries: ...
    @staticmethod
    def new_opt_u32(name: str, obj: Any, strict: bool) -> PySeries: ...
    @staticmethod
    def new_opt_u64(name: str, obj: Any, strict: bool) -> PySeries: ...
    @staticmethod
    def new_opt_i8(name: str, obj: Any, strict: bool) -> PySeries: ...
    @staticmethod
    def new_opt_i16(name: str, obj: Any, strict: bool) -> PySeries: ...
    @staticmethod
    def new_opt_i32(name: str, obj: Any, strict: bool) -> PySeries: ...
    @staticmethod
    def new_opt_i64(name: str, obj: Any, strict: bool) -> PySeries: ...
    @staticmethod
    def new_opt_i128(name: str, obj: Any, strict: bool) -> PySeries: ...
    @staticmethod
    def new_opt_f32(name: str, obj: Any, strict: bool) -> PySeries: ...
    @staticmethod
    def new_opt_f64(name: str, obj: Any, strict: bool) -> PySeries: ...
    @staticmethod
    def new_from_any_values(name: str, values: Any, strict: bool) -> PySeries: ...
    @staticmethod
    def new_from_any_values_and_dtype(
        name: str, values: Any, dtype: DataType, strict: bool
    ) -> PySeries: ...
    @staticmethod
    def new_str(name: str, values: Any, _strict: bool) -> PySeries: ...
    @staticmethod
    def new_binary(name: str, values: Any, _strict: bool) -> PySeries: ...
    @staticmethod
    def new_decimal(name: str, values: Any, strict: bool) -> PySeries: ...
    @staticmethod
    def new_series_list(
        name: str, values: Sequence[PySeries | None], _strict: bool
    ) -> PySeries: ...
    @staticmethod
    def new_array(
        name: str, values: Any, strict: bool, dtype: DataType
    ) -> PySeries: ...
    @staticmethod
    def new_object(name: str, values: Sequence[Any], _strict: bool) -> PySeries: ...
    @staticmethod
    def new_null(name: str, values: Any, _strict: bool) -> PySeries: ...
    @staticmethod
    def from_arrow(name: str, array: Any) -> PySeries: ...

    # export
    def to_list(self) -> list[Any]: ...
    def to_arrow(self, compat_level: Any) -> Any: ...
    def __arrow_c_stream__(self, requested_schema: Any | None) -> Any: ...
    def _export(self, location: int) -> None: ...

    # import
    @classmethod
    def from_arrow_c_array(cls, ob: Any) -> PySeries: ...
    @classmethod
    def from_arrow_c_stream(cls, ob: Any) -> PySeries: ...
    @classmethod
    def _import(cls, location: int) -> PySeries: ...

    # numpy ufunc
    def apply_ufunc_f32(self, lambda_func: Any, allocate_out: bool) -> PySeries: ...
    def apply_ufunc_f64(self, lambda_func: Any, allocate_out: bool) -> PySeries: ...
    def apply_ufunc_u8(self, lambda_func: Any, allocate_out: bool) -> PySeries: ...
    def apply_ufunc_u16(self, lambda_func: Any, allocate_out: bool) -> PySeries: ...
    def apply_ufunc_u32(self, lambda_func: Any, allocate_out: bool) -> PySeries: ...
    def apply_ufunc_u64(self, lambda_func: Any, allocate_out: bool) -> PySeries: ...
    def apply_ufunc_i8(self, lambda_func: Any, allocate_out: bool) -> PySeries: ...
    def apply_ufunc_i16(self, lambda_func: Any, allocate_out: bool) -> PySeries: ...
    def apply_ufunc_i32(self, lambda_func: Any, allocate_out: bool) -> PySeries: ...
    def apply_ufunc_i64(self, lambda_func: Any, allocate_out: bool) -> PySeries: ...

    # scatter
    def scatter(self, idx: PySeries, values: PySeries) -> None: ...

    # interop
    def to_numpy(self, writable: bool, allow_copy: bool) -> Any: ...
    def to_numpy_view(self) -> Any | None: ...

class PyDataFrame:
    # general
    @overload
    def __init__(self, columns: Sequence[PySeries]) -> None: ...
    @overload
    def __init__(self, data: Any, columns: Any, orient: Any) -> None: ...
    @overload
    def __init__(self, schema: dict[str, Any]) -> None: ...
    def estimated_size(self) -> int: ...
    def dtype_strings(self) -> list[str]: ...
    def add(self, s: PySeries) -> PyDataFrame: ...
    def sub(self, s: PySeries) -> PyDataFrame: ...
    def mul(self, s: PySeries) -> PyDataFrame: ...
    def div(self, s: PySeries) -> PyDataFrame: ...
    def rem(self, s: PySeries) -> PyDataFrame: ...
    def add_df(self, s: PyDataFrame) -> PyDataFrame: ...
    def sub_df(self, s: PyDataFrame) -> PyDataFrame: ...
    def mul_df(self, s: PyDataFrame) -> PyDataFrame: ...
    def div_df(self, s: PyDataFrame) -> PyDataFrame: ...
    def rem_df(self, s: PyDataFrame) -> PyDataFrame: ...
    def sample_n(
        self, n: PySeries, with_replacement: bool, shuffle: bool, seed: int | None
    ) -> PyDataFrame: ...
    def sample_frac(
        self,
        frac: PySeries,
        with_replacement: bool,
        shuffle: bool,
        seed: int | None,
    ) -> PyDataFrame: ...
    def rechunk(self) -> PyDataFrame: ...
    def as_str(self) -> str: ...
    def get_columns(self) -> list[PySeries]: ...
    def columns(self) -> list[str]: ...
    def set_column_names(self, names: Sequence[str]) -> None: ...
    def dtypes(self) -> list[Any]: ...
    def n_chunks(self) -> int: ...
    def shape(self) -> tuple[int, int]: ...
    def height(self) -> int: ...
    def width(self) -> int: ...
    def is_empty(self) -> bool: ...
    def hstack(self, columns: Sequence[PySeries]) -> PyDataFrame: ...
    def hstack_mut(self, columns: Sequence[PySeries]) -> None: ...
    def vstack(self, other: PyDataFrame) -> PyDataFrame: ...
    def vstack_mut(self, other: PyDataFrame) -> None: ...
    def extend(self, other: PyDataFrame) -> None: ...
    def drop_in_place(self, name: str) -> PySeries: ...
    def to_series(self, index: int) -> PySeries: ...
    def get_column_index(self, name: str) -> int: ...
    def get_column(self, name: str) -> PySeries: ...
    def select(self, columns: Sequence[str]) -> PyDataFrame: ...
    def gather(self, indices: Sequence[int]) -> PyDataFrame: ...
    def gather_with_series(self, indices: PySeries) -> PyDataFrame: ...
    def replace(self, column: str, new_col: PySeries) -> None: ...
    def replace_column(self, index: int, new_column: PySeries) -> None: ...
    def insert_column(self, index: int, column: PySeries) -> None: ...
    def slice(self, offset: int, length: int | None) -> PyDataFrame: ...
    def head(self, n: int) -> PyDataFrame: ...
    def tail(self, n: int) -> PyDataFrame: ...
    def is_unique(self) -> PySeries: ...
    def is_duplicated(self) -> PySeries: ...
    def equals(self, other: PyDataFrame, null_equal: bool) -> bool: ...
    def with_row_index(self, name: str, offset: int | None) -> PyDataFrame: ...
    def _to_metadata(self) -> PyDataFrame: ...
    def group_by_map_groups(
        self, by: Sequence[str], lambda_func: Any, maintain_order: bool
    ) -> PyDataFrame: ...
    def clone(self) -> PyDataFrame: ...
    def unpivot(
        self,
        on: Sequence[str],
        index: Sequence[str],
        value_name: str | None,
        variable_name: str | None,
    ) -> PyDataFrame: ...
    def pivot_expr(
        self,
        on: Sequence[str],
        index: Sequence[str] | None,
        values: Sequence[str] | None,
        maintain_order: bool,
        sort_columns: bool,
        aggregate_expr: Any | None,
        separator: str | None,
    ) -> PyDataFrame: ...
    def partition_by(
        self, by: Sequence[str], maintain_order: bool, include_key: bool
    ) -> list[PyDataFrame]: ...
    def lazy(self) -> PyLazyFrame: ...
    def to_dummies(
        self,
        columns: Sequence[str] | None,
        separator: str | None,
        drop_first: bool,
        drop_nulls: bool,
    ) -> PyDataFrame: ...
    def null_count(self) -> PyDataFrame: ...
    def map_rows(
        self,
        lambda_func: Any,
        output_type: Any | None,
        inference_size: int,
    ) -> tuple[Any, bool]: ...
    def shrink_to_fit(self) -> None: ...
    def hash_rows(self, k0: int, k1: int, k2: int, k3: int) -> PySeries: ...
    def transpose(
        self, keep_names_as: str | None, column_names: None | str | Sequence[str]
    ) -> PyDataFrame: ...
    def upsample(
        self,
        by: Sequence[str],
        index_column: str,
        every: str,
        stable: bool,
    ) -> PyDataFrame: ...
    def to_struct(self, name: str, invalid_indices: Sequence[int]) -> PySeries: ...
    def clear(self) -> PyDataFrame: ...
    def _export_columns(self, location: int) -> None: ...
    @classmethod
    def _import_columns(cls, location: int, width: int) -> PyDataFrame: ...
    def _row_encode(self, opts: Sequence[tuple[bool, bool, bool]]) -> PySeries: ...

    # construction
    @staticmethod
    def from_rows(
        data: Sequence[PySeries],
        schema: Any | None,
        infer_schema_length: int | None,
    ) -> PyDataFrame: ...
    @staticmethod
    def from_dicts(
        data: Any,
        schema: Any | None,
        schema_overrides: Any | None,
        strict: bool,
        infer_schema_length: int | None,
    ) -> PyDataFrame: ...
    @staticmethod
    def from_arrow_record_batches(
        rb: Sequence[Any],
        schema: Any,
    ) -> PyDataFrame: ...

    # export
    def row_tuple(self, idx: int) -> tuple[Any, ...]: ...
    def row_tuples(self) -> list[tuple[Any, ...]]: ...
    def to_arrow(self, compat_level: Any) -> list[Any]: ...
    def to_pandas(self) -> list[Any]: ...
    def __arrow_c_stream__(self, requested_schema: Any | None) -> Any: ...

    # io
    @staticmethod
    def read_csv(
        py_f: Any,
        infer_schema_length: int | None,
        chunk_size: int,
        has_header: bool,
        ignore_errors: bool,
        n_rows: int | None,
        skip_rows: int,
        skip_lines: int,
        projection: Sequence[int] | None,
        separator: str,
        rechunk: bool,
        columns: Sequence[str] | None,
        encoding: Any,
        n_threads: int | None,
        path: str | None,
        overwrite_dtype: Sequence[tuple[str, DataType]] | None,
        overwrite_dtype_slice: Sequence[DataType] | None,
        low_memory: bool,
        comment_prefix: str | None,
        quote_char: str | None,
        null_values: Any | None,
        missing_utf8_is_empty_string: bool,
        try_parse_dates: bool,
        skip_rows_after_header: int,
        row_index: tuple[str, int] | None,
        eol_char: str,
        raise_if_empty: bool,
        truncate_ragged_lines: bool,
        decimal_comma: bool,
        schema: Any | None,
    ) -> PyDataFrame: ...
    @staticmethod
    def read_json(
        py_f: Any,
        infer_schema_length: int | None,
        schema: Any | None,
        schema_overrides: Any | None,
    ) -> PyDataFrame: ...
    @staticmethod
    def read_ipc(
        py_f: Any,
        columns: Sequence[str] | None,
        projection: Sequence[int] | None,
        n_rows: int | None,
        row_index: tuple[str, int] | None,
        memory_map: bool,
    ) -> PyDataFrame: ...
    @staticmethod
    def read_ipc_stream(
        py_f: Any,
        columns: Sequence[str] | None,
        projection: Sequence[int] | None,
        n_rows: int | None,
        row_index: tuple[str, int] | None,
        rechunk: bool,
    ) -> PyDataFrame: ...
    @staticmethod
    def read_avro(
        py_f: Any,
        columns: Sequence[str] | None,
        projection: Sequence[int] | None,
        n_rows: int | None,
    ) -> PyDataFrame: ...
    def write_json(self, py_f: Any) -> None: ...
    def write_ipc_stream(
        self, py_f: Any, compression: Any, compat_level: Any
    ) -> None: ...
    def write_avro(self, py_f: Any, compression: Any, name: str) -> None: ...

    # serde
    def serialize_binary(self, py_f: Any) -> None: ...
    @staticmethod
    def deserialize_binary(py_f: Any) -> PyDataFrame: ...
    def serialize_json(self, py_f: Any) -> None: ...
    @staticmethod
    def deserialize_json(py_f: Any) -> PyDataFrame: ...

    # interop
    def to_numpy(
        self,
        order: IndexOrder,
        writable: bool,
        allow_copy: bool,
    ) -> Any: ...

class PyLazyFrame:
    @staticmethod
    def new_from_ndjson(
        source: Any | None,
        sources: Any,
        infer_schema_length: int | None,
        schema: Any | None,
        schema_overrides: Any | None,
        batch_size: int | None,
        n_rows: int | None,
        low_memory: bool,
        rechunk: bool,
        row_index: tuple[str, int] | None,
        ignore_errors: bool,
        include_file_paths: str | None,
        cloud_options: dict[str, Any] | None,
        credential_provider: Any | None,
        retries: int,
        file_cache_ttl: int | None,
    ) -> PyLazyFrame: ...
    @staticmethod
    def new_from_csv(
        source: Any | None,
        sources: Any,
        separator: str,
        has_header: bool,
        ignore_errors: bool,
        skip_rows: int,
        skip_lines: int,
        n_rows: int | None,
        cache: bool,
        overwrite_dtype: Sequence[tuple[str, Any]] | None,
        low_memory: bool,
        comment_prefix: str | None,
        quote_char: str | None,
        null_values: Any | None,
        missing_utf8_is_empty_string: bool,
        infer_schema_length: int | None,
        with_schema_modify: Any | None,
        rechunk: bool,
        skip_rows_after_header: int,
        encoding: Any,
        row_index: tuple[str, int] | None,
        try_parse_dates: bool,
        eol_char: str,
        raise_if_empty: bool,
        truncate_ragged_lines: bool,
        decimal_comma: bool,
        glob: bool,
        schema: Any | None,
        cloud_options: dict[str, Any] | None,
        credential_provider: Any | None,
        retries: int,
        file_cache_ttl: int | None,
        include_file_paths: str | None,
    ) -> PyLazyFrame: ...
    @staticmethod
    def new_from_parquet(
        sources: Any,
        schema: Any | None,
        scan_options: PyScanOptions,
        parallel: Any,
        low_memory: bool,
        use_statistics: bool,
    ) -> PyLazyFrame: ...
    @staticmethod
    def new_from_ipc(
        source: Any | None,
        sources: Any,
        n_rows: int | None,
        cache: bool,
        rechunk: bool,
        row_index: tuple[str, int] | None,
        cloud_options: dict[str, Any] | None,
        credential_provider: Any | None,
        hive_partitioning: bool | None,
        hive_schema: Any | None,
        try_parse_hive_dates: bool,
        retries: int,
        file_cache_ttl: int | None,
        include_file_paths: str | None,
    ) -> PyLazyFrame: ...
    @staticmethod
    def new_from_dataset_object(dataset_object: Any) -> PyLazyFrame: ...
    @staticmethod
    def scan_from_python_function_arrow_schema(
        schema: Any, scan_fn: Any, pyarrow: bool, validate_schema: bool, is_pure: bool
    ) -> PyLazyFrame: ...
    @staticmethod
    def scan_from_python_function_pl_schema(
        schema: Sequence[tuple[str, Any]],
        scan_fn: Any,
        pyarrow: bool,
        validate_schema: bool,
        is_pure: bool,
    ) -> PyLazyFrame: ...
    @staticmethod
    def scan_from_python_function_schema_function(
        schema_fn: Any, scan_fn: Any, validate_schema: bool, is_pure: bool
    ) -> PyLazyFrame: ...
    def pipe_with_schema(
        self, callback: Callable[[tuple[PyLazyFrame, Schema]], PyLazyFrame]
    ) -> PyLazyFrame: ...
    def describe_plan(self) -> str: ...
    def describe_optimized_plan(self) -> str: ...
    def describe_plan_tree(self) -> str: ...
    def describe_optimized_plan_tree(self) -> str: ...
    def to_dot(self, optimized: bool) -> str: ...
    def to_dot_streaming_phys(self, optimized: bool) -> str: ...
    def optimization_toggle(
        self,
        type_coercion: bool,
        type_check: bool,
        predicate_pushdown: bool,
        projection_pushdown: bool,
        simplify_expression: bool,
        slice_pushdown: bool,
        comm_subplan_elim: bool,
        comm_subexpr_elim: bool,
        cluster_with_columns: bool,
        collapse_joins: bool,
        _eager: bool,
        _check_order: bool,
        new_streaming: bool,
    ) -> PyLazyFrame: ...
    def sort(
        self,
        by_column: str,
        descending: bool,
        nulls_last: bool,
        maintain_order: bool,
        multithreaded: bool,
    ) -> PyLazyFrame: ...
    def sort_by_exprs(
        self,
        by: Sequence[PyExpr],
        descending: Sequence[bool],
        nulls_last: Sequence[bool],
        maintain_order: bool,
        multithreaded: bool,
    ) -> PyLazyFrame: ...
    def top_k(
        self, k: int, by: Sequence[PyExpr], reverse: Sequence[bool]
    ) -> PyLazyFrame: ...
    def bottom_k(
        self, k: int, by: Sequence[PyExpr], reverse: Sequence[bool]
    ) -> PyLazyFrame: ...
    def cache(self) -> PyLazyFrame: ...
    def with_optimizations(self, optflags: PyOptFlags) -> PyLazyFrame: ...
    def profile(
        self, lambda_post_opt: Any | None
    ) -> tuple[PyDataFrame, PyDataFrame]: ...
    def collect(self, engine: Any, lambda_post_opt: Any | None) -> PyDataFrame: ...
    def collect_with_callback(self, engine: Any, lambda_func: Any) -> None: ...
    def sink_parquet(
        self,
        target: SinkTarget,
        compression: str,
        compression_level: int | None,
        statistics: StatisticsOptions,
        row_group_size: int | None,
        data_page_size: int | None,
        cloud_options: dict[str, Any] | None,
        credential_provider: Any | None,
        retries: int,
        sink_options: Any,
        metadata: KeyValueMetadata | None,
        field_overwrites: Sequence[ParquetFieldOverwrites],
    ) -> PyLazyFrame: ...
    def sink_ipc(
        self,
        target: SinkTarget,
        compression: IpcCompression | None,
        compat_level: CompatLevel,
        cloud_options: dict[str, Any] | None,
        credential_provider: Any | None,
        retries: int,
        sink_options: Any,
    ) -> PyLazyFrame: ...
    def sink_csv(
        self,
        target: SinkTarget,
        include_bom: bool,
        include_header: bool,
        separator: int,
        line_terminator: str,
        quote_char: int,
        batch_size: int,
        datetime_format: str | None,
        date_format: str | None,
        time_format: str | None,
        float_scientific: bool | None,
        float_precision: int | None,
        decimal_comma: bool,
        null_value: str | None,
        quote_style: QuoteStyle | None,
        cloud_options: dict[str, Any] | None,
        credential_provider: Any | None,
        retries: int,
        sink_options: Any,
    ) -> PyLazyFrame: ...
    def sink_json(
        self,
        target: SinkTarget,
        cloud_options: dict[str, Any] | None,
        credential_provider: Any | None,
        retries: int,
        sink_options: Any,
    ) -> PyLazyFrame: ...
    def filter(self, predicate: PyExpr) -> PyLazyFrame: ...
    def remove(self, predicate: PyExpr) -> PyLazyFrame: ...
    def select(self, exprs: Sequence[PyExpr]) -> PyLazyFrame: ...
    def select_seq(self, exprs: Sequence[PyExpr]) -> PyLazyFrame: ...
    def group_by(self, by: Sequence[PyExpr], maintain_order: bool) -> PyLazyGroupBy: ...
    def rolling(
        self,
        index_column: PyExpr,
        period: str,
        offset: str,
        closed: ClosedWindow,
        by: Sequence[PyExpr],
    ) -> PyLazyGroupBy: ...
    def group_by_dynamic(
        self,
        index_column: PyExpr,
        every: str,
        period: str,
        offset: str,
        label: Label,
        include_boundaries: bool,
        closed: ClosedWindow,
        group_by: Sequence[PyExpr],
        start_by: StartBy,
    ) -> PyLazyGroupBy: ...
    def with_context(self, contexts: Sequence[PyLazyFrame]) -> PyLazyFrame: ...
    def join_asof(
        self,
        other: PyLazyFrame,
        left_on: PyExpr,
        right_on: PyExpr,
        left_by: Sequence[str] | None,
        right_by: Sequence[str] | None,
        allow_parallel: bool,
        force_parallel: bool,
        suffix: str,
        strategy: AsofStrategy,
        tolerance: Any | None,
        tolerance_str: str | None,
        coalesce: bool,
        allow_eq: bool,
        check_sortedness: bool,
    ) -> PyLazyFrame: ...
    def join(
        self,
        other: PyLazyFrame,
        left_on: Sequence[PyExpr],
        right_on: Sequence[PyExpr],
        allow_parallel: bool,
        force_parallel: bool,
        nulls_equal: bool,
        how: JoinType,
        suffix: str,
        validate: JoinValidation,
        maintain_order: MaintainOrderJoin,
        coalesce: bool | None,
    ) -> PyLazyFrame: ...
    def join_where(
        self, other: PyLazyFrame, predicates: Sequence[PyExpr], suffix: str
    ) -> PyLazyFrame: ...
    def with_columns(self, exprs: Sequence[PyExpr]) -> PyLazyFrame: ...
    def with_columns_seq(self, exprs: Sequence[PyExpr]) -> PyLazyFrame: ...
    def match_to_schema(
        self,
        schema: Schema,
        missing_columns: Any,
        missing_struct_fields: Any,
        extra_columns: ExtraColumnsPolicy,
        extra_struct_fields: Any,
        integer_cast: Any,
        float_cast: Any,
    ) -> PyLazyFrame: ...
    def rename(
        self, existing: Sequence[str], new: Sequence[str], strict: bool
    ) -> PyLazyFrame: ...
    def reverse(self) -> PyLazyFrame: ...
    def shift(self, n: PyExpr, fill_value: PyExpr | None) -> PyLazyFrame: ...
    def fill_nan(self, fill_value: PyExpr) -> PyLazyFrame: ...
    def min(self) -> PyLazyFrame: ...
    def max(self) -> PyLazyFrame: ...
    def sum(self) -> PyLazyFrame: ...
    def mean(self) -> PyLazyFrame: ...
    def std(self, ddof: int) -> PyLazyFrame: ...
    def var(self, ddof: int) -> PyLazyFrame: ...
    def median(self) -> PyLazyFrame: ...
    def quantile(
        self, quantile: PyExpr, interpolation: QuantileMethod
    ) -> PyLazyFrame: ...
    def explode(self, subset: PySelector) -> PyLazyFrame: ...
    def null_count(self) -> PyLazyFrame: ...
    def unique(
        self,
        maintain_order: bool,
        subset: PySelector | None,
        keep: UniqueKeepStrategy,
    ) -> PyLazyFrame: ...
    def drop_nans(self, subset: PySelector | None) -> PyLazyFrame: ...
    def drop_nulls(self, subset: PySelector | None) -> PyLazyFrame: ...
    def slice(self, offset: int, len: int | None) -> PyLazyFrame: ...
    def tail(self, n: int) -> PyLazyFrame: ...
    def unpivot(
        self,
        on: PySelector,
        index: PySelector,
        value_name: str | None,
        variable_name: str | None,
    ) -> PyLazyFrame: ...
    def with_row_index(self, name: str, offset: int | None = None) -> PyLazyFrame: ...
    def map_batches(
        self,
        function: Any,
        predicate_pushdown: bool,
        projection_pushdown: bool,
        slice_pushdown: bool,
        streamable: bool,
        schema: Schema | None,
        validate_output: bool,
    ) -> PyLazyFrame: ...
    def drop(self, columns: PySelector) -> PyLazyFrame: ...
    def cast(self, dtypes: dict[str, DataType], strict: bool) -> PyLazyFrame: ...
    def cast_all(self, dtype: PyDataTypeExpr, strict: bool) -> PyLazyFrame: ...
    def clone(self) -> PyLazyFrame: ...
    def collect_schema(self) -> dict[str, Any]: ...
    def unnest(self, columns: PySelector) -> PyLazyFrame: ...
    def count(self) -> PyLazyFrame: ...
    def merge_sorted(self, other: PyLazyFrame, key: str) -> PyLazyFrame: ...

    # exitable
    def collect_concurrently(self) -> PyInProcessQuery: ...

    # serde
    def serialize_binary(self, py_f: Any) -> None: ...
    def serialize_json(self, py_f: Any) -> None: ...
    @staticmethod
    def deserialize_binary(py_f: Any) -> PyLazyFrame: ...
    @staticmethod
    def deserialize_json(py_f: Any) -> PyLazyFrame: ...

    # visit
    def visit(self) -> NodeTraverser: ...

class PyInProcessQuery:
    def cancel(self) -> None: ...
    def fetch(self) -> PyDataFrame | None: ...
    def fetch_blocking(self) -> PyDataFrame: ...

class PyExpr:
    def __init__(self, inner: Any) -> None: ...
    def __richcmp__(self, other: PyExpr, op: Any) -> PyExpr: ...
    def __add__(self, rhs: PyExpr) -> PyExpr: ...
    def __sub__(self, rhs: PyExpr) -> PyExpr: ...
    def __mul__(self, rhs: PyExpr) -> PyExpr: ...
    def __truediv__(self, rhs: PyExpr) -> PyExpr: ...
    def __mod__(self, rhs: PyExpr) -> PyExpr: ...
    def __floordiv__(self, rhs: PyExpr) -> PyExpr: ...
    def __neg__(self) -> PyExpr: ...
    def to_str(self) -> str: ...
    def eq(self, other: PyExpr) -> PyExpr: ...
    def eq_missing(self, other: PyExpr) -> PyExpr: ...
    def neq(self, other: PyExpr) -> PyExpr: ...
    def neq_missing(self, other: PyExpr) -> PyExpr: ...
    def gt(self, other: PyExpr) -> PyExpr: ...
    def gt_eq(self, other: PyExpr) -> PyExpr: ...
    def lt_eq(self, other: PyExpr) -> PyExpr: ...
    def lt(self, other: PyExpr) -> PyExpr: ...
    def alias(self, name: str) -> PyExpr: ...
    def not_(self) -> PyExpr: ...
    def is_null(self) -> PyExpr: ...
    def is_not_null(self) -> PyExpr: ...
    def is_infinite(self) -> PyExpr: ...
    def is_finite(self) -> PyExpr: ...
    def is_nan(self) -> PyExpr: ...
    def is_not_nan(self) -> PyExpr: ...
    def min(self) -> PyExpr: ...
    def max(self) -> PyExpr: ...
    def nan_max(self) -> PyExpr: ...
    def nan_min(self) -> PyExpr: ...
    def mean(self) -> PyExpr: ...
    def median(self) -> PyExpr: ...
    def sum(self) -> PyExpr: ...
    def n_unique(self) -> PyExpr: ...
    def arg_unique(self) -> PyExpr: ...
    def unique(self) -> PyExpr: ...
    def unique_stable(self) -> PyExpr: ...
    def first(self) -> PyExpr: ...
    def last(self) -> PyExpr: ...
    def implode(self) -> PyExpr: ...
    def quantile(self, quantile: PyExpr, interpolation: Any) -> PyExpr: ...
    def cut(
        self,
        breaks: Sequence[float],
        labels: Sequence[str] | None,
        left_closed: bool,
        include_breaks: bool,
    ) -> PyExpr: ...
    def qcut(
        self,
        probs: Sequence[float],
        labels: Sequence[str] | None,
        left_closed: bool,
        allow_duplicates: bool,
        include_breaks: bool,
    ) -> PyExpr: ...
    def qcut_uniform(
        self,
        n_bins: int,
        labels: Sequence[str] | None,
        left_closed: bool,
        allow_duplicates: bool,
        include_breaks: bool,
    ) -> PyExpr: ...
    def rle(self) -> PyExpr: ...
    def rle_id(self) -> PyExpr: ...
    def agg_groups(self) -> PyExpr: ...
    def count(self) -> PyExpr: ...
    def len(self) -> PyExpr: ...
    def value_counts(
        self, sort: bool, parallel: bool, name: str, normalize: bool
    ) -> PyExpr: ...
    def unique_counts(self) -> PyExpr: ...
    def null_count(self) -> PyExpr: ...
    def cast(
        self, dtype: PyDataTypeExpr, strict: bool, wrap_numerical: bool
    ) -> PyExpr: ...
    def sort_with(self, descending: bool, nulls_last: bool) -> PyExpr: ...
    def arg_sort(self, descending: bool, nulls_last: bool) -> PyExpr: ...
    def top_k(self, k: PyExpr) -> PyExpr: ...
    def top_k_by(
        self, by: Sequence[PyExpr], k: PyExpr, reverse: Sequence[bool]
    ) -> PyExpr: ...
    def bottom_k(self, k: PyExpr) -> PyExpr: ...
    def bottom_k_by(
        self, by: Sequence[PyExpr], k: PyExpr, reverse: Sequence[bool]
    ) -> PyExpr: ...
    def peak_min(self) -> PyExpr: ...
    def peak_max(self) -> PyExpr: ...
    def arg_max(self) -> PyExpr: ...
    def arg_min(self) -> PyExpr: ...
    def index_of(self, element: PyExpr) -> PyExpr: ...
    def search_sorted(self, element: PyExpr, side: Any, descending: bool) -> PyExpr: ...
    def gather(self, idx: PyExpr) -> PyExpr: ...
    def get(self, idx: PyExpr) -> PyExpr: ...
    def sort_by(
        self,
        by: Sequence[PyExpr],
        descending: Sequence[bool],
        nulls_last: Sequence[bool],
        multithreaded: bool,
        maintain_order: bool,
    ) -> PyExpr: ...
    def shift(self, n: PyExpr, fill_value: PyExpr | None) -> PyExpr: ...
    def fill_null(self, expr: PyExpr) -> PyExpr: ...
    def fill_null_with_strategy(self, strategy: str, limit: Any) -> PyExpr: ...
    def fill_nan(self, expr: PyExpr) -> PyExpr: ...
    def drop_nulls(self) -> PyExpr: ...
    def drop_nans(self) -> PyExpr: ...
    def filter(self, predicate: PyExpr) -> PyExpr: ...
    def reverse(self) -> PyExpr: ...
    def std(self, ddof: int) -> PyExpr: ...
    def var(self, ddof: int) -> PyExpr: ...
    def is_unique(self) -> PyExpr: ...
    def is_between(self, lower: PyExpr, upper: PyExpr, closed: Any) -> PyExpr: ...
    def is_close(
        self, other: PyExpr, abs_tol: float, rel_tol: float, nans_equal: bool
    ) -> PyExpr: ...
    def approx_n_unique(self) -> PyExpr: ...
    def is_first_distinct(self) -> PyExpr: ...
    def is_last_distinct(self) -> PyExpr: ...
    def explode(self) -> PyExpr: ...
    def gather_every(self, n: int, offset: int) -> PyExpr: ...
    def slice(self, offset: PyExpr, length: PyExpr) -> PyExpr: ...
    def append(self, other: PyExpr, upcast: bool) -> PyExpr: ...
    def rechunk(self) -> PyExpr: ...
    def round(self, decimals: int, mode: Any) -> PyExpr: ...
    def round_sig_figs(self, digits: int) -> PyExpr: ...
    def floor(self) -> PyExpr: ...
    def ceil(self) -> PyExpr: ...
    def clip(self, min: PyExpr | None, max: PyExpr | None) -> PyExpr: ...
    def abs(self) -> PyExpr: ...
    def sin(self) -> PyExpr: ...
    def cos(self) -> PyExpr: ...
    def tan(self) -> PyExpr: ...
    def cot(self) -> PyExpr: ...
    def arcsin(self) -> PyExpr: ...
    def arccos(self) -> PyExpr: ...
    def arctan(self) -> PyExpr: ...
    def arctan2(self, y: PyExpr) -> PyExpr: ...
    def sinh(self) -> PyExpr: ...
    def cosh(self) -> PyExpr: ...
    def tanh(self) -> PyExpr: ...
    def arcsinh(self) -> PyExpr: ...
    def arccosh(self) -> PyExpr: ...
    def arctanh(self) -> PyExpr: ...
    def degrees(self) -> PyExpr: ...
    def radians(self) -> PyExpr: ...
    def sign(self) -> PyExpr: ...
    def is_duplicated(self) -> PyExpr: ...
    def over(
        self,
        partition_by: Sequence[PyExpr] | None,
        order_by: Sequence[PyExpr] | None,
        order_by_descending: bool,
        order_by_nulls_last: bool,
        mapping_strategy: Any,
    ) -> PyExpr: ...
    def rolling(
        self, index_column: str, period: str, offset: str, closed: Any
    ) -> PyExpr: ...
    def and_(self, expr: PyExpr) -> PyExpr: ...
    def or_(self, expr: PyExpr) -> PyExpr: ...
    def xor_(self, expr: PyExpr) -> PyExpr: ...
    def is_in(self, expr: PyExpr, nulls_equal: bool) -> PyExpr: ...
    def repeat_by(self, by: PyExpr) -> PyExpr: ...
    def pow(self, exponent: PyExpr) -> PyExpr: ...
    def sqrt(self) -> PyExpr: ...
    def cbrt(self) -> PyExpr: ...
    def cum_sum(self, reverse: bool) -> PyExpr: ...
    def cum_max(self, reverse: bool) -> PyExpr: ...
    def cum_min(self, reverse: bool) -> PyExpr: ...
    def cum_prod(self, reverse: bool) -> PyExpr: ...
    def cum_count(self, reverse: bool) -> PyExpr: ...
    def cumulative_eval(self, expr: PyExpr, min_samples: int) -> PyExpr: ...
    def product(self) -> PyExpr: ...
    def shrink_dtype(self) -> PyExpr: ...
    def dot(self, other: PyExpr) -> PyExpr: ...
    def reinterpret(self, signed: bool) -> PyExpr: ...
    def mode(self) -> PyExpr: ...
    def interpolate(self, method: Any) -> PyExpr: ...
    def interpolate_by(self, by: PyExpr) -> PyExpr: ...
    def lower_bound(self) -> PyExpr: ...
    def upper_bound(self) -> PyExpr: ...
    def rank(self, method: Any, descending: bool, seed: int | None) -> PyExpr: ...
    def diff(self, n: PyExpr, null_behavior: Any) -> PyExpr: ...
    def pct_change(self, n: PyExpr) -> PyExpr: ...
    def skew(self, bias: bool) -> PyExpr: ...
    def kurtosis(self, fisher: bool, bias: bool) -> PyExpr: ...
    def reshape(self, dims: Sequence[int]) -> PyExpr: ...
    def to_physical(self) -> PyExpr: ...
    def shuffle(self, seed: int | None) -> PyExpr: ...
    def sample_n(
        self, n: PyExpr, with_replacement: bool, shuffle: bool, seed: int | None
    ) -> PyExpr: ...
    def sample_frac(
        self, frac: PyExpr, with_replacement: bool, shuffle: bool, seed: int | None
    ) -> PyExpr: ...
    def ewm_mean(
        self, alpha: float, adjust: bool, min_periods: int, ignore_nulls: bool
    ) -> PyExpr: ...
    def ewm_mean_by(self, times: PyExpr, half_life: str) -> PyExpr: ...
    def ewm_std(
        self,
        alpha: float,
        adjust: bool,
        bias: bool,
        min_periods: int,
        ignore_nulls: bool,
    ) -> PyExpr: ...
    def ewm_var(
        self,
        alpha: float,
        adjust: bool,
        bias: bool,
        min_periods: int,
        ignore_nulls: bool,
    ) -> PyExpr: ...
    def extend_constant(self, value: PyExpr, n: PyExpr) -> PyExpr: ...
    def any(self, ignore_nulls: bool) -> PyExpr: ...
    def all(self, ignore_nulls: bool) -> PyExpr: ...
    def log(self, base: PyExpr) -> PyExpr: ...
    def log1p(self) -> PyExpr: ...
    def exp(self) -> PyExpr: ...
    def entropy(self, base: float, normalize: bool) -> PyExpr: ...
    def hash(self, seed: int, seed_1: int, seed_2: int, seed_3: int) -> PyExpr: ...
    def set_sorted_flag(self, descending: bool) -> PyExpr: ...
    def replace(self, old: PyExpr, new: PyExpr) -> PyExpr: ...
    def replace_strict(
        self,
        old: PyExpr,
        new: PyExpr,
        default: PyExpr | None,
        return_dtype: PyDataTypeExpr | None,
    ) -> PyExpr: ...
    def hist(
        self,
        bins: PyExpr | None,
        bin_count: int | None,
        include_category: bool,
        include_breakpoint: bool,
    ) -> PyExpr: ...
    def skip_batch_predicate(self, schema: Any) -> PyExpr | None: ...
    @staticmethod
    def row_encode_unordered(exprs: Sequence[PyExpr]) -> PyExpr: ...
    @staticmethod
    def row_encode_ordered(
        exprs: Sequence[PyExpr],
        descending: Sequence[bool] | None,
        nulls_last: Sequence[bool] | None,
    ) -> PyExpr: ...
    def row_decode_unordered(
        self, names: Sequence[str], datatypes: Sequence[PyDataTypeExpr]
    ) -> PyExpr: ...
    def row_decode_ordered(
        self,
        names: Sequence[str],
        datatypes: Sequence[PyDataTypeExpr],
        descending: Sequence[bool] | None,
        nulls_last: Sequence[bool] | None,
    ) -> PyExpr: ...
    def into_selector(self) -> Any: ...
    @staticmethod
    def new_selector(selector: Any) -> PyExpr: ...

    # array
    def arr_len(self) -> PyExpr: ...
    def arr_max(self) -> PyExpr: ...
    def arr_min(self) -> PyExpr: ...
    def arr_sum(self) -> PyExpr: ...
    def arr_std(self, ddof: int) -> PyExpr: ...
    def arr_var(self, ddof: int) -> PyExpr: ...
    def arr_mean(self) -> PyExpr: ...
    def arr_median(self) -> PyExpr: ...
    def arr_unique(self, maintain_order: bool) -> PyExpr: ...
    def arr_n_unique(self) -> PyExpr: ...
    def arr_to_list(self) -> PyExpr: ...
    def arr_all(self) -> PyExpr: ...
    def arr_any(self) -> PyExpr: ...
    def arr_sort(self, descending: bool, nulls_last: bool) -> PyExpr: ...
    def arr_reverse(self) -> PyExpr: ...
    def arr_arg_min(self) -> PyExpr: ...
    def arr_arg_max(self) -> PyExpr: ...
    def arr_get(self, index: PyExpr, null_on_oob: bool) -> PyExpr: ...
    def arr_join(self, separator: PyExpr, ignore_nulls: bool) -> PyExpr: ...
    def arr_contains(self, other: PyExpr, nulls_equal: bool) -> PyExpr: ...
    def arr_count_matches(self, expr: PyExpr) -> PyExpr: ...
    def arr_to_struct(self, name_gen: Any | None = None) -> PyExpr: ...
    def arr_slice(
        self, offset: PyExpr, length: PyExpr | None = None, as_array: bool = False
    ) -> PyExpr: ...
    def arr_tail(self, n: PyExpr, as_array: bool = False) -> PyExpr: ...
    def arr_shift(self, n: PyExpr) -> PyExpr: ...
    def arr_explode(self) -> PyExpr: ...

    # binary
    def bin_contains(self, lit: PyExpr) -> PyExpr: ...
    def bin_ends_with(self, sub: PyExpr) -> PyExpr: ...
    def bin_starts_with(self, sub: PyExpr) -> PyExpr: ...
    def bin_hex_decode(self, strict: bool) -> PyExpr: ...
    def bin_base64_decode(self, strict: bool) -> PyExpr: ...
    def bin_hex_encode(self) -> PyExpr: ...
    def bin_base64_encode(self) -> PyExpr: ...
    def bin_reinterpret(self, dtype: PyDataTypeExpr, kind: str) -> PyExpr: ...
    def bin_size_bytes(self) -> PyExpr: ...

    # bitwise
    def bitwise_count_ones(self) -> PyExpr: ...
    def bitwise_count_zeros(self) -> PyExpr: ...
    def bitwise_leading_ones(self) -> PyExpr: ...
    def bitwise_leading_zeros(self) -> PyExpr: ...
    def bitwise_trailing_ones(self) -> PyExpr: ...
    def bitwise_trailing_zeros(self) -> PyExpr: ...
    def bitwise_and(self) -> PyExpr: ...
    def bitwise_or(self) -> PyExpr: ...
    def bitwise_xor(self) -> PyExpr: ...

    # categorical
    def cat_get_categories(self) -> PyExpr: ...
    def cat_len_bytes(self) -> PyExpr: ...
    def cat_len_chars(self) -> PyExpr: ...
    def cat_starts_with(self, prefix: str) -> PyExpr: ...
    def cat_ends_with(self, suffix: str) -> PyExpr: ...
    def cat_slice(self, offset: int, length: int | None = None) -> PyExpr: ...

    # datetime
    def dt_add_business_days(
        self, n: PyExpr, week_mask: Sequence[bool], holidays: Sequence[int], roll: Roll
    ) -> PyExpr: ...
    def dt_to_string(self, format: str) -> PyExpr: ...
    def dt_offset_by(self, by: PyExpr) -> PyExpr: ...
    def dt_with_time_unit(self, time_unit: TimeUnit) -> PyExpr: ...
    def dt_convert_time_zone(self, time_zone: str) -> PyExpr: ...
    def dt_cast_time_unit(self, time_unit: TimeUnit) -> PyExpr: ...
    def dt_replace_time_zone(
        self,
        time_zone: str | None,
        ambiguous: PyExpr,
        non_existent: NonExistent,
    ) -> PyExpr: ...
    def dt_truncate(self, every: PyExpr) -> PyExpr: ...
    def dt_month_start(self) -> PyExpr: ...
    def dt_month_end(self) -> PyExpr: ...
    def dt_base_utc_offset(self) -> PyExpr: ...
    def dt_dst_offset(self) -> PyExpr: ...
    def dt_round(self, every: PyExpr) -> PyExpr: ...
    def dt_replace(
        self,
        year: PyExpr,
        month: PyExpr,
        day: PyExpr,
        hour: PyExpr,
        minute: PyExpr,
        second: PyExpr,
        microsecond: PyExpr,
        ambiguous: PyExpr,
    ) -> PyExpr: ...
    def dt_combine(self, time: PyExpr, time_unit: TimeUnit) -> PyExpr: ...
    def dt_millennium(self) -> PyExpr: ...
    def dt_century(self) -> PyExpr: ...
    def dt_year(self) -> PyExpr: ...
    def dt_is_business_day(
        self, week_mask: Sequence[bool], holidays: Sequence[int]
    ) -> PyExpr: ...
    def dt_is_leap_year(self) -> PyExpr: ...
    def dt_iso_year(self) -> PyExpr: ...
    def dt_quarter(self) -> PyExpr: ...
    def dt_month(self) -> PyExpr: ...
    def dt_days_in_month(self) -> PyExpr: ...
    def dt_week(self) -> PyExpr: ...
    def dt_weekday(self) -> PyExpr: ...
    def dt_day(self) -> PyExpr: ...
    def dt_ordinal_day(self) -> PyExpr: ...
    def dt_time(self) -> PyExpr: ...
    def dt_date(self) -> PyExpr: ...
    def dt_datetime(self) -> PyExpr: ...
    def dt_hour(self) -> PyExpr: ...
    def dt_minute(self) -> PyExpr: ...
    def dt_second(self) -> PyExpr: ...
    def dt_millisecond(self) -> PyExpr: ...
    def dt_microsecond(self) -> PyExpr: ...
    def dt_nanosecond(self) -> PyExpr: ...
    def dt_timestamp(self, time_unit: TimeUnit) -> PyExpr: ...
    def dt_total_days(self) -> PyExpr: ...
    def dt_total_hours(self) -> PyExpr: ...
    def dt_total_minutes(self) -> PyExpr: ...
    def dt_total_seconds(self) -> PyExpr: ...
    def dt_total_milliseconds(self) -> PyExpr: ...
    def dt_total_microseconds(self) -> PyExpr: ...
    def dt_total_nanoseconds(self) -> PyExpr: ...

    # list
    def list_all(self) -> PyExpr: ...
    def list_any(self) -> PyExpr: ...
    def list_arg_max(self) -> PyExpr: ...
    def list_arg_min(self) -> PyExpr: ...
    def list_contains(self, other: PyExpr, nulls_equal: bool) -> PyExpr: ...
    def list_count_matches(self, expr: PyExpr) -> PyExpr: ...
    def list_diff(self, n: int, null_behavior: NullBehavior) -> PyExpr: ...
    def list_eval(self, expr: PyExpr, _parallel: bool) -> PyExpr: ...
    def list_filter(self, predicate: PyExpr) -> PyExpr: ...
    def list_get(self, index: PyExpr, null_on_oob: bool) -> PyExpr: ...
    def list_join(self, separator: PyExpr, ignore_nulls: bool) -> PyExpr: ...
    def list_len(self) -> PyExpr: ...
    def list_max(self) -> PyExpr: ...
    def list_mean(self) -> PyExpr: ...
    def list_median(self) -> PyExpr: ...
    def list_std(self, ddof: int) -> PyExpr: ...
    def list_var(self, ddof: int) -> PyExpr: ...
    def list_min(self) -> PyExpr: ...
    def list_reverse(self) -> PyExpr: ...
    def list_shift(self, periods: PyExpr) -> PyExpr: ...
    def list_slice(self, offset: PyExpr, length: PyExpr | None = None) -> PyExpr: ...
    def list_tail(self, n: PyExpr) -> PyExpr: ...
    def list_sort(self, descending: bool, nulls_last: bool) -> PyExpr: ...
    def list_sum(self) -> PyExpr: ...
    def list_drop_nulls(self) -> PyExpr: ...
    def list_sample_n(
        self, n: PyExpr, with_replacement: bool, shuffle: bool, seed: int | None = None
    ) -> PyExpr: ...
    def list_sample_fraction(
        self,
        fraction: PyExpr,
        with_replacement: bool,
        shuffle: bool,
        seed: int | None = None,
    ) -> PyExpr: ...
    def list_gather(self, index: PyExpr, null_on_oob: bool) -> PyExpr: ...
    def list_gather_every(self, n: PyExpr, offset: PyExpr) -> PyExpr: ...
    def list_to_array(self, width: int) -> PyExpr: ...
    def list_to_struct(self, names: Sequence[str]) -> PyExpr: ...
    def list_to_struct_fixed_width(self, names: Sequence[str]) -> PyExpr: ...
    def list_n_unique(self) -> PyExpr: ...
    def list_unique(self, maintain_order: bool) -> PyExpr: ...
    def list_set_operation(self, other: PyExpr, operation: SetOperation) -> PyExpr: ...

    # meta
    def meta_eq(self, other: PyExpr) -> bool: ...
    def meta_pop(self, schema: Schema | None = None) -> list[PyExpr]: ...
    def meta_root_names(self) -> list[str]: ...
    def meta_output_name(self) -> str: ...
    def meta_undo_aliases(self) -> PyExpr: ...
    def meta_has_multiple_outputs(self) -> bool: ...
    def meta_is_column(self) -> bool: ...
    def meta_is_regex_projection(self) -> bool: ...
    def meta_is_column_selection(self, allow_aliasing: bool) -> bool: ...
    def meta_is_literal(self, allow_aliasing: bool) -> bool: ...
    def compute_tree_format(
        self, display_as_dot: bool, schema: Schema | None
    ) -> str: ...
    def meta_tree_format(self, schema: Schema | None = None) -> str: ...
    def meta_show_graph(self, schema: Schema | None = None) -> str: ...

    # name
    def name_keep(self) -> PyExpr: ...
    def name_map(self, lambda_function: Any) -> PyExpr: ...
    def name_prefix(self, prefix: str) -> PyExpr: ...
    def name_suffix(self, suffix: str) -> PyExpr: ...
    def name_to_lowercase(self) -> PyExpr: ...
    def name_to_uppercase(self) -> PyExpr: ...
    def name_map_fields(self, name_mapper: Any) -> PyExpr: ...
    def name_prefix_fields(self, prefix: str) -> PyExpr: ...
    def name_suffix_fields(self, suffix: str) -> PyExpr: ...

    # rolling
    def rolling_sum(
        self,
        window_size: int,
        weights: Sequence[float] | None = None,
        min_periods: int | None = None,
        center: bool = False,
    ) -> PyExpr: ...
    def rolling_sum_by(
        self,
        by: PyExpr,
        window_size: str,
        min_periods: int,
        closed: ClosedWindow,
    ) -> PyExpr: ...
    def rolling_min(
        self,
        window_size: int,
        weights: Sequence[float] | None = None,
        min_periods: int | None = None,
        center: bool = False,
    ) -> PyExpr: ...
    def rolling_min_by(
        self,
        by: PyExpr,
        window_size: str,
        min_periods: int,
        closed: ClosedWindow,
    ) -> PyExpr: ...
    def rolling_max(
        self,
        window_size: int,
        weights: Sequence[float] | None = None,
        min_periods: int | None = None,
        center: bool = False,
    ) -> PyExpr: ...
    def rolling_max_by(
        self,
        by: PyExpr,
        window_size: str,
        min_periods: int,
        closed: ClosedWindow,
    ) -> PyExpr: ...
    def rolling_mean(
        self,
        window_size: int,
        weights: Sequence[float] | None = None,
        min_periods: int | None = None,
        center: bool = False,
    ) -> PyExpr: ...
    def rolling_mean_by(
        self,
        by: PyExpr,
        window_size: str,
        min_periods: int,
        closed: ClosedWindow,
    ) -> PyExpr: ...
    def rolling_std(
        self,
        window_size: int,
        weights: Sequence[float] | None = None,
        min_periods: int | None = None,
        center: bool = False,
        ddof: int = 1,
    ) -> PyExpr: ...
    def rolling_std_by(
        self,
        by: PyExpr,
        window_size: str,
        min_periods: int,
        closed: ClosedWindow,
        ddof: int = 1,
    ) -> PyExpr: ...
    def rolling_var(
        self,
        window_size: int,
        weights: Sequence[float] | None = None,
        min_periods: int | None = None,
        center: bool = False,
        ddof: int = 1,
    ) -> PyExpr: ...
    def rolling_var_by(
        self,
        by: PyExpr,
        window_size: str,
        min_periods: int,
        closed: ClosedWindow,
        ddof: int = 1,
    ) -> PyExpr: ...
    def rolling_median(
        self,
        window_size: int,
        weights: Sequence[float] | None = None,
        min_periods: int | None = None,
        center: bool = False,
    ) -> PyExpr: ...
    def rolling_median_by(
        self,
        by: PyExpr,
        window_size: str,
        min_periods: int,
        closed: ClosedWindow,
    ) -> PyExpr: ...
    def rolling_quantile(
        self,
        quantile: float,
        interpolation: QuantileMethod,
        window_size: int,
        weights: Sequence[float] | None = None,
        min_periods: int | None = None,
        center: bool = False,
    ) -> PyExpr: ...
    def rolling_quantile_by(
        self,
        by: PyExpr,
        quantile: float,
        interpolation: QuantileMethod,
        window_size: str,
        min_periods: int,
        closed: ClosedWindow,
    ) -> PyExpr: ...
    def rolling_skew(
        self,
        window_size: int,
        bias: bool,
        min_periods: int | None = None,
        center: bool = False,
    ) -> PyExpr: ...
    def rolling_kurtosis(
        self,
        window_size: int,
        fisher: bool,
        bias: bool,
        min_periods: int | None = None,
        center: bool = False,
    ) -> PyExpr: ...
    def rolling_map(
        self,
        lambda_function: Any,
        window_size: int,
        weights: Sequence[float] | None = None,
        min_periods: int | None = None,
        center: bool = False,
    ) -> PyExpr: ...

    # serde
    def __getstate__(self) -> bytes: ...
    def __setstate__(self, state: Any) -> None: ...
    def serialize_binary(self, py_f: Any) -> None: ...
    def serialize_json(self, py_f: Any) -> None: ...
    @staticmethod
    def deserialize_binary(py_f: Any) -> PyExpr: ...
    @staticmethod
    def deserialize_json(py_f: Any) -> PyExpr: ...

    # string
    def str_join(self, delimiter: str, ignore_nulls: bool) -> PyExpr: ...
    def str_to_date(
        self,
        format: str | None = None,
        strict: bool = True,
        exact: bool = True,
        cache: bool = True,
    ) -> PyExpr: ...
    def str_to_datetime(
        self,
        format: str | None,
        time_unit: TimeUnit | None,
        time_zone: TimeZone | None,
        strict: bool,
        exact: bool,
        cache: bool,
        ambiguous: PyExpr,
    ) -> PyExpr: ...
    def str_to_time(
        self,
        format: str | None = None,
        strict: bool = True,
        cache: bool = True,
    ) -> PyExpr: ...
    def str_strip_chars(self, matches: PyExpr) -> PyExpr: ...
    def str_strip_chars_start(self, matches: PyExpr) -> PyExpr: ...
    def str_strip_chars_end(self, matches: PyExpr) -> PyExpr: ...
    def str_strip_prefix(self, prefix: PyExpr) -> PyExpr: ...
    def str_strip_suffix(self, suffix: PyExpr) -> PyExpr: ...
    def str_slice(self, offset: PyExpr, length: PyExpr) -> PyExpr: ...
    def str_head(self, n: PyExpr) -> PyExpr: ...
    def str_tail(self, n: PyExpr) -> PyExpr: ...
    def str_to_uppercase(self) -> PyExpr: ...
    def str_to_lowercase(self) -> PyExpr: ...
    def str_to_titlecase(self) -> PyExpr: ...
    def str_len_bytes(self) -> PyExpr: ...
    def str_len_chars(self) -> PyExpr: ...
    def str_replace_n(
        self, pat: PyExpr, val: PyExpr, literal: bool, n: int
    ) -> PyExpr: ...
    def str_replace_all(self, pat: PyExpr, val: PyExpr, literal: bool) -> PyExpr: ...
    def str_normalize(self, form: UnicodeForm) -> PyExpr: ...
    def str_reverse(self) -> PyExpr: ...
    def str_pad_start(self, length: PyExpr, fill_char: str) -> PyExpr: ...
    def str_pad_end(self, length: PyExpr, fill_char: str) -> PyExpr: ...
    def str_zfill(self, length: PyExpr) -> PyExpr: ...
    def str_contains(
        self, pat: PyExpr, literal: bool | None = None, strict: bool = True
    ) -> PyExpr: ...
    def str_find(
        self, pat: PyExpr, literal: bool | None = None, strict: bool = True
    ) -> PyExpr: ...
    def str_ends_with(self, sub: PyExpr) -> PyExpr: ...
    def str_starts_with(self, sub: PyExpr) -> PyExpr: ...
    def str_hex_encode(self) -> PyExpr: ...
    def str_hex_decode(self, strict: bool) -> PyExpr: ...
    def str_base64_encode(self) -> PyExpr: ...
    def str_base64_decode(self, strict: bool) -> PyExpr: ...
    def str_to_integer(
        self, base: PyExpr, dtype: Any | None = None, strict: bool = True
    ) -> PyExpr: ...
    def str_json_decode(
        self, dtype: PyDataTypeExpr | None = None, infer_schema_len: int | None = None
    ) -> PyExpr: ...
    def str_json_path_match(self, pat: PyExpr) -> PyExpr: ...
    def str_extract(self, pat: PyExpr, group_index: int) -> PyExpr: ...
    def str_extract_all(self, pat: PyExpr) -> PyExpr: ...
    def str_extract_groups(self, pat: str) -> PyExpr: ...
    def str_count_matches(self, pat: PyExpr, literal: bool) -> PyExpr: ...
    def str_split(self, by: PyExpr) -> PyExpr: ...
    def str_split_inclusive(self, by: PyExpr) -> PyExpr: ...
    def str_split_exact(self, by: PyExpr, n: int) -> PyExpr: ...
    def str_split_exact_inclusive(self, by: PyExpr, n: int) -> PyExpr: ...
    def str_splitn(self, by: PyExpr, n: int) -> PyExpr: ...
    def str_to_decimal(self, scale: int) -> PyExpr: ...
    def str_contains_any(
        self, patterns: PyExpr, ascii_case_insensitive: bool
    ) -> PyExpr: ...
    def str_replace_many(
        self, patterns: PyExpr, replace_with: PyExpr, ascii_case_insensitive: bool
    ) -> PyExpr: ...
    def str_extract_many(
        self, patterns: PyExpr, ascii_case_insensitive: bool, overlapping: bool
    ) -> PyExpr: ...
    def str_find_many(
        self, patterns: PyExpr, ascii_case_insensitive: bool, overlapping: bool
    ) -> PyExpr: ...
    def str_escape_regex(self) -> PyExpr: ...

    # struct
    def struct_field_by_index(self, index: int) -> PyExpr: ...
    def struct_field_by_name(self, name: str) -> PyExpr: ...
    def struct_multiple_fields(self, names: Sequence[str]) -> PyExpr: ...
    def struct_rename_fields(self, names: Sequence[str]) -> PyExpr: ...
    def struct_json_encode(self) -> PyExpr: ...
    def struct_with_fields(self, fields: Sequence[PyExpr]) -> PyExpr: ...

class PyDataTypeExpr:
    def __init__(self, inner: Any) -> None: ...
    @staticmethod
    def from_dtype(datatype: Any) -> PyDataTypeExpr: ...
    @staticmethod
    def of_expr(expr: PyExpr) -> PyDataTypeExpr: ...
    @staticmethod
    def self_dtype() -> PyDataTypeExpr: ...
    def collect_dtype(self, schema: Any) -> Any: ...
    def inner_dtype(self) -> PyDataTypeExpr: ...
    def equals(self, other: PyDataTypeExpr) -> PyExpr: ...
    def display(self) -> PyExpr: ...
    def matches(self, selector: Any) -> PyExpr: ...
    @staticmethod
    def struct_with_fields(
        fields: Sequence[tuple[str, PyDataTypeExpr]],
    ) -> PyDataTypeExpr: ...
    def wrap_in_list(self) -> PyDataTypeExpr: ...
    def wrap_in_array(self, width: int) -> PyDataTypeExpr: ...
    def to_unsigned_integer(self) -> PyDataTypeExpr: ...
    def to_signed_integer(self) -> PyDataTypeExpr: ...
    def default_value(
        self, n: int, numeric_to_one: bool, num_list_values: int
    ) -> PyExpr: ...

    # list
    def list_inner_dtype(self) -> PyDataTypeExpr: ...

    # array
    def arr_inner_dtype(self) -> PyDataTypeExpr: ...
    def arr_width(self) -> PyExpr: ...
    def arr_shape(self) -> PyExpr: ...

    # struct
    def struct_field_dtype_by_index(self, index: int) -> PyDataTypeExpr: ...
    def struct_field_dtype_by_name(self, name: str) -> PyDataTypeExpr: ...
    def struct_field_names(self) -> PyExpr: ...

class PySelector:
    def __init__(self, inner: Any) -> None: ...
    def union(self, other: PySelector) -> PySelector: ...
    def difference(self, other: PySelector) -> PySelector: ...
    def exclusive_or(self, other: PySelector) -> PySelector: ...
    def intersect(self, other: PySelector) -> PySelector: ...
    @staticmethod
    def by_dtype(dtypes: Sequence[Any]) -> PySelector: ...
    @staticmethod
    def by_name(names: Sequence[str], strict: bool) -> PySelector: ...
    @staticmethod
    def by_index(indices: Sequence[int], strict: bool) -> PySelector: ...
    @staticmethod
    def first(strict: bool) -> PySelector: ...
    @staticmethod
    def last(strict: bool) -> PySelector: ...
    @staticmethod
    def matches(pattern: str) -> PySelector: ...
    @staticmethod
    def enum_() -> PySelector: ...
    @staticmethod
    def categorical() -> PySelector: ...
    @staticmethod
    def nested() -> PySelector: ...
    @staticmethod
    def list(inner_dst: PySelector | None) -> PySelector: ...
    @staticmethod
    def array(inner_dst: PySelector | None, width: int | None) -> PySelector: ...
    @staticmethod
    def struct_() -> PySelector: ...
    @staticmethod
    def integer() -> PySelector: ...
    @staticmethod
    def signed_integer() -> PySelector: ...
    @staticmethod
    def unsigned_integer() -> PySelector: ...
    @staticmethod
    def float() -> PySelector: ...
    @staticmethod
    def decimal() -> PySelector: ...
    @staticmethod
    def numeric() -> PySelector: ...
    @staticmethod
    def temporal() -> PySelector: ...
    @staticmethod
    def datetime(tu: Sequence[Any], tz: Sequence[Any]) -> PySelector: ...
    @staticmethod
    def duration(tu: Sequence[Any]) -> PySelector: ...
    @staticmethod
    def object() -> PySelector: ...
    @staticmethod
    def empty() -> PySelector: ...
    @staticmethod
    def all() -> PySelector: ...
    def hash(self) -> int: ...

class PyOptFlags:
    def __init__(self) -> None: ...
    @staticmethod
    def empty() -> PyOptFlags: ...
    @staticmethod
    def default() -> PyOptFlags: ...
    def no_optimizations(self) -> None: ...
    def copy(self) -> PyOptFlags: ...
    @property
    def type_coercion(self) -> bool: ...
    @type_coercion.setter
    def type_coercion(self, value: bool) -> None: ...
    @property
    def type_check(self) -> bool: ...
    @type_check.setter
    def type_check(self, value: bool) -> None: ...
    @property
    def projection_pushdown(self) -> bool: ...
    @projection_pushdown.setter
    def projection_pushdown(self, value: bool) -> None: ...
    @property
    def predicate_pushdown(self) -> bool: ...
    @predicate_pushdown.setter
    def predicate_pushdown(self, value: bool) -> None: ...
    @property
    def cluster_with_columns(self) -> bool: ...
    @cluster_with_columns.setter
    def cluster_with_columns(self, value: bool) -> None: ...
    @property
    def simplify_expression(self) -> bool: ...
    @simplify_expression.setter
    def simplify_expression(self, value: bool) -> None: ...
    @property
    def slice_pushdown(self) -> bool: ...
    @slice_pushdown.setter
    def slice_pushdown(self, value: bool) -> None: ...
    @property
    def comm_subplan_elim(self) -> bool: ...
    @comm_subplan_elim.setter
    def comm_subplan_elim(self, value: bool) -> None: ...
    @property
    def comm_subexpr_elim(self) -> bool: ...
    @comm_subexpr_elim.setter
    def comm_subexpr_elim(self, value: bool) -> None: ...
    @property
    def collapse_joins(self) -> bool: ...
    @collapse_joins.setter
    def collapse_joins(self, value: bool) -> None: ...
    @property
    def check_order_observe(self) -> bool: ...
    @check_order_observe.setter
    def check_order_observe(self, value: bool) -> None: ...
    @property
    def fast_projection(self) -> bool: ...
    @fast_projection.setter
    def fast_projection(self, value: bool) -> None: ...
    @property
    def eager(self) -> bool: ...
    @eager.setter
    def eager(self, value: bool) -> None: ...
    @property
    def streaming(self) -> bool: ...
    @streaming.setter
    def streaming(self, value: bool) -> None: ...

class PyPartitioning:
    def __init__(self) -> None: ...
    base_path: Any

    @staticmethod
    def new_max_size(
        base_path: Any,
        file_path_cb: Any | None,
        max_size: int,
        per_partition_sort_by: Sequence[PyExpr] | None,
        finish_callback: Any | None,
    ) -> PyPartitioning: ...
    @staticmethod
    def new_by_key(
        base_path: Any,
        file_path_cb: Any | None,
        by: Sequence[PyExpr],
        include_key: bool,
        per_partition_sort_by: Sequence[PyExpr] | None,
        finish_callback: Any | None,
    ) -> PyPartitioning: ...
    @staticmethod
    def new_parted(
        base_path: Any,
        file_path_cb: Any | None,
        by: Sequence[PyExpr],
        include_key: bool,
        per_partition_sort_by: Sequence[PyExpr] | None,
        finish_callback: Any | None,
    ) -> PyPartitioning: ...

# functions.lazy
def rolling_corr(
    x: PyExpr, y: PyExpr, window_size: int, min_periods: int, ddof: int
) -> PyExpr: ...
def rolling_cov(
    x: PyExpr, y: PyExpr, window_size: int, min_periods: int, ddof: int
) -> PyExpr: ...
def arg_sort_by(
    by: Sequence[PyExpr],
    descending: Sequence[bool],
    nulls_last: Sequence[bool],
    multithreaded: bool,
    maintain_order: bool,
) -> PyExpr: ...
def arg_where(condition: PyExpr) -> PyExpr: ...
def as_struct(exprs: Sequence[PyExpr]) -> PyExpr: ...
def field(names: Sequence[str]) -> PyExpr: ...
def coalesce(exprs: Sequence[PyExpr]) -> PyExpr: ...
def col(name: str) -> PyExpr: ...
def collect_all(
    lfs: Sequence[PyLazyFrame], engine: Any, optflags: PyOptFlags
) -> list[PyDataFrame]: ...
def explain_all(lfs: Sequence[PyLazyFrame], optflags: PyOptFlags) -> str: ...
def collect_all_with_callback(
    lfs: Sequence[PyLazyFrame], engine: Any, optflags: PyOptFlags, lambda_func: Any
) -> None: ...
def concat_lf(
    seq: Any, rechunk: bool, parallel: bool, to_supertypes: bool
) -> PyLazyFrame: ...
def concat_list(s: Sequence[PyExpr]) -> PyExpr: ...
def concat_arr(s: Sequence[PyExpr]) -> PyExpr: ...
def concat_str(s: Sequence[PyExpr], separator: str, ignore_nulls: bool) -> PyExpr: ...
def len() -> PyExpr: ...
def cov(a: PyExpr, b: PyExpr, ddof: int) -> PyExpr: ...
def arctan2(y: PyExpr, x: PyExpr) -> PyExpr: ...
def cum_fold(
    acc: PyExpr,
    lambda_func: Any,
    exprs: Sequence[PyExpr],
    returns_scalar: bool,
    return_dtype: PyDataTypeExpr | None,
    include_init: bool,
) -> PyExpr: ...
def cum_reduce(
    lambda_func: Any,
    exprs: Sequence[PyExpr],
    returns_scalar: bool,
    return_dtype: PyDataTypeExpr | None,
) -> PyExpr: ...
def datetime(
    year: PyExpr,
    month: PyExpr,
    day: PyExpr,
    hour: PyExpr | None,
    minute: PyExpr | None,
    second: PyExpr | None,
    microsecond: PyExpr | None,
    time_unit: TimeUnit,  # Default set by Rust code
    time_zone: TimeZone | None,  # Default set by Rust code
    ambiguous: PyExpr,  # Default set by Rust code
) -> PyExpr: ...
def concat_lf_diagonal(
    lfs: Any, rechunk: bool, parallel: bool, to_supertypes: bool
) -> PyLazyFrame: ...
def concat_lf_horizontal(lfs: Any, parallel: bool) -> PyLazyFrame: ...
def concat_expr(e: Sequence[PyExpr], rechunk: bool) -> PyExpr: ...
def duration(
    weeks: PyExpr | None,
    days: PyExpr | None,
    hours: PyExpr | None,
    minutes: PyExpr | None,
    seconds: PyExpr | None,
    milliseconds: PyExpr | None,
    microseconds: PyExpr | None,
    nanoseconds: PyExpr | None,
    time_unit: TimeUnit,  # Default set by Rust code
) -> PyExpr: ...
def fold(
    acc: PyExpr,
    lambda_func: Any,
    exprs: Sequence[PyExpr],
    returns_scalar: bool,
    return_dtype: PyDataTypeExpr | None,
) -> PyExpr: ...
def lit(value: Any, allow_object: bool, is_scalar: bool) -> PyExpr: ...
def map_expr(
    pyexpr: Sequence[PyExpr],
    lambda_func: Any,
    output_type: PyDataTypeExpr | None,
    is_elementwise: bool,
    returns_scalar: bool,
) -> PyExpr: ...
def pearson_corr(a: PyExpr, b: PyExpr) -> PyExpr: ...
def reduce(
    lambda_func: Any,
    exprs: Sequence[PyExpr],
    returns_scalar: bool,
    return_dtype: PyDataTypeExpr | None,
) -> PyExpr: ...
def repeat(value: PyExpr, n: PyExpr, dtype: Any | None = None) -> PyExpr: ...
def spearman_rank_corr(a: PyExpr, b: PyExpr, propagate_nans: bool) -> PyExpr: ...
def sql_expr(sql: str) -> PyExpr: ...

# functions.aggregations
def all_horizontal(exprs: Sequence[PyExpr]) -> PyExpr: ...
def any_horizontal(exprs: Sequence[PyExpr]) -> PyExpr: ...
def max_horizontal(exprs: Sequence[PyExpr]) -> PyExpr: ...
def min_horizontal(exprs: Sequence[PyExpr]) -> PyExpr: ...
def sum_horizontal(exprs: Sequence[PyExpr], ignore_nulls: bool) -> PyExpr: ...
def mean_horizontal(exprs: Sequence[PyExpr], ignore_nulls: bool) -> PyExpr: ...

# functions.business
def business_day_count(
    start: PyExpr,
    end: PyExpr,
    week_mask: Sequence[bool],
    holidays: Sequence[int],
) -> PyExpr: ...

# functions.eager
def concat_df(dfs: Any) -> PyDataFrame: ...
def concat_series(series: Any) -> PySeries: ...
def concat_df_diagonal(dfs: Any) -> PyDataFrame: ...
def concat_df_horizontal(dfs: Any) -> PyDataFrame: ...

# functions.io
def read_ipc_schema(py_f: Any) -> dict[str, Any]: ...
def read_parquet_metadata(py_f: Any) -> dict[str, str]: ...
def read_clipboard_string() -> str: ...
def write_clipboard_string(s: str) -> None: ...

# functions.meta
def get_index_type() -> Any: ...
def thread_pool_size() -> int: ...
def set_float_fmt(fmt: FloatFmt) -> None: ...
def get_float_fmt() -> str: ...
def set_float_precision(precision: int | None) -> None: ...
def get_float_precision() -> int | None: ...
def set_thousands_separator(sep: str | None) -> None: ...
def get_thousands_separator() -> str | None: ...
def set_decimal_separator(sep: str | None) -> None: ...
def get_decimal_separator() -> str | None: ...
def set_trim_decimal_zeros(trim: bool | None) -> None: ...
def get_trim_decimal_zeros() -> bool | None: ...

# functions.misc
def dtype_str_repr(dtype: Any) -> str: ...
def register_plugin_function(
    plugin_path: str,
    function_name: str,
    args: Sequence[PyExpr],
    kwargs: Sequence[int],
    is_elementwise: bool,
    input_wildcard_expansion: bool,
    returns_scalar: bool,
    cast_to_supertype: bool,
    pass_name_to_apply: bool,
    changes_length: bool,
) -> PyExpr: ...
def __register_startup_deps() -> None: ...

# functions.random
def set_random_seed(seed: int) -> None: ...

# functions.range
def int_range(
    start: PyExpr, end: PyExpr, step: int, dtype: PyDataTypeExpr
) -> PyExpr: ...
def eager_int_range(
    lower: Any, upper: Any, step: Any, dtype: PyDataTypeExpr
) -> PySeries: ...
def int_ranges(
    start: PyExpr, end: PyExpr, step: PyExpr, dtype: PyDataTypeExpr
) -> PyExpr: ...
def date_range(
    start: PyExpr, end: PyExpr, interval: str, closed: ClosedWindow
) -> PyExpr: ...
def date_ranges(
    start: PyExpr, end: PyExpr, interval: str, closed: ClosedWindow
) -> PyExpr: ...
def datetime_range(
    start: PyExpr,
    end: PyExpr,
    every: str,
    closed: ClosedWindow,
    time_unit: TimeUnit | None,
    time_zone: TimeZone | None,
) -> PyExpr: ...
def datetime_ranges(
    start: PyExpr,
    end: PyExpr,
    every: str,
    closed: ClosedWindow,
    time_unit: TimeUnit | None,
    time_zone: TimeZone | None,
) -> PyExpr: ...
def time_range(
    start: PyExpr, end: PyExpr, every: str, closed: ClosedWindow
) -> PyExpr: ...
def time_ranges(
    start: PyExpr, end: PyExpr, every: str, closed: ClosedWindow
) -> PyExpr: ...
def linear_space(
    start: PyExpr, end: PyExpr, num_samples: PyExpr, closed: ClosedInterval
) -> PyExpr: ...
def linear_spaces(
    start: PyExpr,
    end: PyExpr,
    num_samples: PyExpr,
    closed: ClosedInterval,
    as_array: bool,
) -> PyExpr: ...

# functions.string_cache
class PyStringCacheHolder: ...

def enable_string_cache() -> None: ...
def disable_string_cache() -> None: ...
def using_string_cache() -> bool: ...

# functions.strings
def escape_regex(s: str) -> str: ...

# functions.strings
def check_length(check: bool) -> None: ...
def get_engine_affinity() -> EngineType: ...

# functions.when
class PyWhen:
    def then(self, statement: PyExpr) -> PyThen: ...

class PyThen:
    def when(self, condition: PyExpr) -> PyChainedWhen: ...
    def otherwise(self, statement: PyExpr) -> PyExpr: ...

class PyChainedWhen:
    def then(self, statement: PyExpr) -> PyChainedThen: ...

class PyChainedThen:
    def when(self, condition: PyExpr) -> PyChainedWhen: ...
    def otherwise(self, statement: PyExpr) -> PyExpr: ...

def when(condition: PyExpr) -> PyWhen: ...

class PyLazyGroupBy:
    def agg(self, aggs: list[PyExpr]) -> PyLazyFrame: ...
    def head(self, n: int) -> PyLazyFrame: ...
    def tail(self, n: int) -> PyLazyFrame: ...
    def map_groups(
        self, lambda_function: Any, schema: Schema | None
    ) -> PyLazyFrame: ...

# categorical
class PyCategories:
    def __init__(self, name: str, namespace: str, physical: str) -> None: ...
    @staticmethod
    def global_categories() -> PyCategories: ...
    @staticmethod
    def random(namespace: str, physical: str) -> PyCategories: ...
    def __eq__(self, other: PyCategories) -> bool: ...  # type: ignore[override]
    def __hash__(self) -> int: ...
    def name(self) -> str: ...
    def namespace(self) -> str: ...
    def physical(self) -> str: ...
    def get_cat(self, s: str) -> int | None: ...
    def cat_to_str(self, cat: int) -> str | None: ...
    def is_global(self) -> bool: ...

class PyBatchedCsv:
    @staticmethod
    def new(
        infer_schema_length: int | None,
        chunk_size: int,
        has_header: bool,
        ignore_errors: bool,
        n_rows: int | None,
        skip_rows: int,
        skip_lines: int,
        projection: Sequence[int] | None,
        separator: str,
        rechunk: bool,
        columns: Sequence[str] | None,
        encoding: CsvEncoding,
        n_threads: int | None,
        path: Any,
        schema_overrides: Sequence[tuple[str, DataType]] | None,
        overwrite_dtype_slice: Sequence[DataType] | None,
        low_memory: bool,
        comment_prefix: str | None,
        quote_char: str | None,
        null_values: NullValues | None,
        missing_utf8_is_empty_string: bool,
        try_parse_dates: bool,
        skip_rows_after_header: int,
        row_index: tuple[str, int] | None,
        eol_char: str,
        raise_if_empty: bool,
        truncate_ragged_lines: bool,
        decimal_comma: bool,
    ) -> PyBatchedCsv: ...
    def next_batches(self, n: int) -> list[PyDataFrame] | None: ...

# catalog
class PyCatalogClient:
    @staticmethod
    def new(workspace_url: str, bearer_token: str | None) -> PyCatalogClient: ...
    def list_catalogs(self) -> list[Any]: ...
    def list_namespaces(self, catalog_name: str) -> list[Any]: ...
    def list_tables(self, catalog_name: str, namespace: str) -> list[Any]: ...
    def get_table_info(
        self, table_name: str, catalog_name: str, namespace: str
    ) -> Any: ...
    def get_table_credentials(
        self, table_id: str, write: bool
    ) -> tuple[Any, Any, Any]: ...
    def scan_table(
        self,
        catalog_name: str,
        namespace: str,
        table_name: str,
        cloud_options: dict[str, str] | None,
        credential_provider: Any | None,
        retries: int,
    ) -> PyLazyFrame: ...
    def create_catalog(
        self, catalog_name: str, comment: str | None, storage_root: str | None
    ) -> Any: ...
    def delete_catalog(self, catalog_name: str, force: bool) -> None: ...
    def create_namespace(
        self,
        catalog_name: str,
        namespace: str,
        comment: str | None,
        storage_root: str | None,
    ) -> Any: ...
    def delete_namespace(
        self, catalog_name: str, namespace: str, force: bool
    ) -> None: ...
    def create_table(
        self,
        catalog_name: str,
        namespace: str,
        table_name: str,
        schema: Any | None,
        table_type: str,
        data_source_format: str | None,
        comment: str | None,
        storage_root: str | None,
        properties: Sequence[tuple[str, str]],
    ) -> Any: ...
    def delete_table(
        self, catalog_name: str, namespace: str, table_name: str
    ) -> None: ...
    @staticmethod
    def type_json_to_polars_type(type_json: str) -> Any: ...
    @staticmethod
    def init_classes(
        catalog_info_cls: Any,
        namespace_info_cls: Any,
        table_info_cls: Any,
        column_info_cls: Any,
    ) -> None: ...

# sql
class PySQLContext:
    @staticmethod
    def new() -> PySQLContext: ...
    def execute(self, query: str) -> PyLazyFrame: ...
    def get_tables(self) -> list[str]: ...
    def register(self, name: str, lf: PyLazyFrame) -> None: ...
    def unregister(self, name: str) -> None: ...

# testing
def assert_series_equal_py(
    left: PySeries,
    right: PySeries,
    *,
    check_dtypes: bool,
    check_names: bool,
    check_order: bool,
    check_exact: bool,
    rel_tol: float,
    abs_tol: float,
    categorical_as_str: bool,
) -> None: ...
def assert_dataframe_equal_py(
    left: PyDataFrame,
    right: PyDataFrame,
    *,
    check_row_order: bool,
    check_column_order: bool,
    check_dtypes: bool,
    check_exact: bool,
    rel_tol: float,
    abs_tol: float,
    categorical_as_str: bool,
) -> None: ...

# datatypes
def _get_dtype_max(dt: DataType) -> PyExpr: ...
def _get_dtype_min(dt: DataType) -> PyExpr: ...
def _known_timezones() -> list[str]: ...

# cloud_client
def prepare_cloud_plan(lf: PyLazyFrame) -> bytes: ...

# cloud_server
def _execute_ir_plan_with_gpu(ir_plan_ser: Sequence[int]) -> PyDataFrame: ...

# visit
class PyExprIR:
    node: int
    output_name: str

class NodeTraverser:
    def get_exprs(self) -> list[PyExprIR]: ...
    def get_inputs(self) -> list[int]: ...
    def version(self) -> tuple[int, int]: ...
    def get_schema(self) -> dict[str, DataType]: ...
    def get_dtype(self, expr_node: int) -> DataType: ...
    def set_node(self, node: int) -> None: ...
    def get_node(self) -> int: ...
    def set_udf(self, function: Any, is_pure: bool = False) -> None: ...
    def view_current_node(self) -> Any: ...
    def view_expression(self, node: int) -> Any: ...
    def add_expressions(self, expressions: list[PyExpr]) -> tuple[list[int], int]: ...
    def set_expr_mapping(self, mapping: list[int]) -> None: ...
    def unset_expr_mapping(self) -> None: ...
