diff --git a/py-polars/polars/api.py b/py-polars/polars/api.py index 97c45350d336..f1020b50bc09 100644 --- a/py-polars/polars/api.py +++ b/py-polars/polars/api.py @@ -43,7 +43,6 @@ def __get__(self, instance: NS | None, cls: type[NS]) -> NS | type[NS]: return self._ns ns_instance = self._ns(instance) # type: ignore[call-arg] - setattr(instance, self._accessor, ns_instance) return ns_instance diff --git a/py-polars/polars/dataframe/frame.py b/py-polars/polars/dataframe/frame.py index 85337cf64d1d..dfe346d27710 100644 --- a/py-polars/polars/dataframe/frame.py +++ b/py-polars/polars/dataframe/frame.py @@ -347,6 +347,8 @@ class DataFrame: False """ + __slots__ = ("_df",) + _df: PyDataFrame _accessors: ClassVar[set[str]] = {"plot"} def __init__( diff --git a/py-polars/polars/datatypes/classes.py b/py-polars/polars/datatypes/classes.py index d9e2fde8614c..9c22af7f0ad2 100644 --- a/py-polars/polars/datatypes/classes.py +++ b/py-polars/polars/datatypes/classes.py @@ -90,6 +90,8 @@ def is_nested(self) -> bool: # noqa: D102 class DataType(metaclass=DataTypeClass): """Base class for all Polars data types.""" + __slots__ = () + def __reduce__(self) -> Any: return (_custom_reconstruct, (type(self), object, None), self.__dict__) @@ -235,6 +237,7 @@ def _custom_reconstruct( class DataTypeGroup(frozenset): # type: ignore[type-arg] """Group of data types.""" + __slots__ = ("_match_base_type",) _match_base_type: bool def __new__( @@ -267,70 +270,104 @@ def __contains__(self, item: Any) -> bool: class NumericType(DataType): """Base class for numeric data types.""" + __slots__ = () + class IntegerType(NumericType): """Base class for integer data types.""" + __slots__ = () + class SignedIntegerType(IntegerType): """Base class for signed integer data types.""" + __slots__ = () + class UnsignedIntegerType(IntegerType): """Base class for unsigned integer data types.""" + __slots__ = () + class FloatType(NumericType): """Base class for float data types.""" + __slots__ = () + class TemporalType(DataType): """Base class for temporal data types.""" + __slots__ = () + class NestedType(DataType): """Base class for nested data types.""" + __slots__ = () + class Int8(SignedIntegerType): """8-bit signed integer type.""" + __slots__ = () + class Int16(SignedIntegerType): """16-bit signed integer type.""" + __slots__ = () + class Int32(SignedIntegerType): """32-bit signed integer type.""" + __slots__ = () + class Int64(SignedIntegerType): """64-bit signed integer type.""" + __slots__ = () + class UInt8(UnsignedIntegerType): """8-bit unsigned integer type.""" + __slots__ = () + class UInt16(UnsignedIntegerType): """16-bit unsigned integer type.""" + __slots__ = () + class UInt32(UnsignedIntegerType): """32-bit unsigned integer type.""" + __slots__ = () + class UInt64(UnsignedIntegerType): """64-bit unsigned integer type.""" + __slots__ = () + class Float32(FloatType): """32-bit floating point type.""" + __slots__ = () + class Float64(FloatType): """64-bit floating point type.""" + __slots__ = () + class Decimal(NumericType): """ @@ -342,6 +379,7 @@ class Decimal(NumericType): It may be changed at any point without it being considered a breaking change. """ + __slots__ = ("precision", "scale") precision: int | None scale: int @@ -383,10 +421,14 @@ def __hash__(self) -> int: class Boolean(DataType): """Boolean type.""" + __slots__ = () + class String(DataType): """UTF-8 encoded string type.""" + __slots__ = () + # Allow Utf8 as an alias for String Utf8 = String @@ -395,14 +437,20 @@ class String(DataType): class Binary(DataType): """Binary type.""" + __slots__ = () + class Date(TemporalType): """Calendar date type.""" + __slots__ = () + class Time(TemporalType): """Time of day type.""" + __slots__ = () + class Datetime(TemporalType): """Calendar date and time type.""" @@ -510,6 +558,7 @@ class Categorical(DataType): or string value (lexical). """ + __slots__ = ("ordering",) ordering: CategoricalOrdering | None def __init__( @@ -544,6 +593,7 @@ class Enum(DataType): It may be changed at any point without it being considered a breaking change. """ + __slots__ = ("categories",) categories: Series def __init__(self, categories: Series | Iterable[str]): @@ -606,14 +656,20 @@ def __repr__(self) -> str: class Object(DataType): """Type for wrapping arbitrary Python objects.""" + __slots__ = () + class Null(DataType): """Type representing Null / None values.""" + __slots__ = () + class Unknown(DataType): """Type representing Datatype values that could not be determined statically.""" + __slots__ = () + class List(NestedType): """Variable length list type.""" @@ -738,6 +794,10 @@ def __repr__(self) -> str: class Field: """Definition of a single field within a `Struct` DataType.""" + __slots__ = ("name", "dtype") + name: str + dtype: PolarsDataType + def __init__(self, name: str, dtype: PolarsDataType): """ Definition of a single field within a `Struct` DataType. @@ -766,6 +826,7 @@ def __repr__(self) -> str: class Struct(NestedType): """Struct composite type.""" + __slots__ = ("fields",) fields: list[Field] def __init__(self, fields: Sequence[Field] | SchemaDict): diff --git a/py-polars/polars/expr/expr.py b/py-polars/polars/expr/expr.py index d870bc8ca528..0e038427f8db 100644 --- a/py-polars/polars/expr/expr.py +++ b/py-polars/polars/expr/expr.py @@ -109,7 +109,8 @@ class Expr: """Expressions that can be used in various contexts.""" - _pyexpr: PyExpr = None + __slots__ = ("_pyexpr",) + _pyexpr: PyExpr _accessors: ClassVar[set[str]] = { "arr", "cat", diff --git a/py-polars/polars/expr/whenthen.py b/py-polars/polars/expr/whenthen.py index f357289fec46..ced5df6d68fe 100644 --- a/py-polars/polars/expr/whenthen.py +++ b/py-polars/polars/expr/whenthen.py @@ -24,6 +24,8 @@ class When: In this state, `then` must be called to continue to finish the expression. """ + __slots__ = ("_when",) + def __init__(self, when: Any): self._when = when @@ -49,6 +51,8 @@ class Then(Expr): Represents the state of the expression after `pl.when(...).then(...)` is called. """ + __slots__ = ("_then",) + def __init__(self, then: Any): self._then = then @@ -106,6 +110,8 @@ class ChainedWhen(Expr): In this state, `then` must be called to continue to finish the expression. """ + __slots__ = ("_chained_when",) + def __init__(self, chained_when: Any): self._chained_when = chained_when @@ -131,6 +137,8 @@ class ChainedThen(Expr): Represents the state of the expression after an additional `then` is called. """ + __slots__ = ("_chained_then",) + def __init__(self, chained_then: Any): self._chained_then = chained_then diff --git a/py-polars/polars/lazyframe/frame.py b/py-polars/polars/lazyframe/frame.py index db79335f290f..7827ba8de667 100644 --- a/py-polars/polars/lazyframe/frame.py +++ b/py-polars/polars/lazyframe/frame.py @@ -286,6 +286,7 @@ class LazyFrame: └─────┴─────┴─────┘ """ + __slots__ = ("_ldf",) _ldf: PyLazyFrame _accessors: ClassVar[set[str]] = set() diff --git a/py-polars/polars/selectors.py b/py-polars/polars/selectors.py index 0793f5b9ee57..846dd4472bd6 100644 --- a/py-polars/polars/selectors.py +++ b/py-polars/polars/selectors.py @@ -242,6 +242,7 @@ def _combine_as_selector( class _selector_proxy_(Expr): """Base column selector expression/proxy.""" + __slots__ = ("_attrs", "_repr_override") _attrs: dict[str, Any] _repr_override: str diff --git a/py-polars/polars/series/series.py b/py-polars/polars/series/series.py index 50c65d252255..4f6ba67f94ae 100644 --- a/py-polars/polars/series/series.py +++ b/py-polars/polars/series/series.py @@ -237,7 +237,8 @@ class Series: ] """ - _s: PySeries = None + __slots__ = ("_s",) + _s: PySeries _accessors: ClassVar[set[str]] = { "arr", "cat",