Skip to content

Commit feb02af

Browse files
perf: Add __slots__ to all DTypes (#3194)
Co-authored-by: Francesco Bruzzesi <[email protected]> Co-authored-by: FBruzzesi <[email protected]>
1 parent 3ce5e29 commit feb02af

File tree

13 files changed

+264
-90
lines changed

13 files changed

+264
-90
lines changed

.pre-commit-config.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ repos:
5252
pass_filenames: false
5353
entry: python -m utils.sort_api_reference
5454
language: python
55+
- id: check-slotted-classes
56+
name: check-slotted-classes
57+
pass_filenames: false
58+
entry: python -m utils.check_slotted_classes
59+
language: python
5560
- id: imports-are-banned
5661
name: import are banned (use `get_pandas` instead of `import pandas`)
5762
entry: python utils/import_check.py

narwhals/dtypes.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ def _validate_into_dtype(dtype: Any) -> None:
6060

6161

6262
class DType:
63+
__slots__ = ()
64+
6365
def __repr__(self) -> str: # pragma: no cover
6466
return self.__class__.__qualname__
6567

@@ -152,30 +154,44 @@ def __hash__(self) -> int:
152154
class NumericType(DType):
153155
"""Base class for numeric data types."""
154156

157+
__slots__ = ()
158+
155159

156160
class IntegerType(NumericType):
157161
"""Base class for integer data types."""
158162

163+
__slots__ = ()
164+
159165

160166
class SignedIntegerType(IntegerType):
161167
"""Base class for signed integer data types."""
162168

169+
__slots__ = ()
170+
163171

164172
class UnsignedIntegerType(IntegerType):
165173
"""Base class for unsigned integer data types."""
166174

175+
__slots__ = ()
176+
167177

168178
class FloatType(NumericType):
169179
"""Base class for float data types."""
170180

181+
__slots__ = ()
182+
171183

172184
class TemporalType(DType):
173185
"""Base class for temporal data types."""
174186

187+
__slots__ = ()
188+
175189

176190
class NestedType(DType):
177191
"""Base class for nested data types."""
178192

193+
__slots__ = ()
194+
179195

180196
class Decimal(NumericType):
181197
"""Decimal type.
@@ -188,6 +204,8 @@ class Decimal(NumericType):
188204
Decimal
189205
"""
190206

207+
__slots__ = ()
208+
191209

192210
class Int128(SignedIntegerType):
193211
"""128-bit signed integer type.
@@ -208,6 +226,8 @@ class Int128(SignedIntegerType):
208226
Int128
209227
"""
210228

229+
__slots__ = ()
230+
211231

212232
class Int64(SignedIntegerType):
213233
"""64-bit signed integer type.
@@ -221,6 +241,8 @@ class Int64(SignedIntegerType):
221241
Int64
222242
"""
223243

244+
__slots__ = ()
245+
224246

225247
class Int32(SignedIntegerType):
226248
"""32-bit signed integer type.
@@ -234,6 +256,8 @@ class Int32(SignedIntegerType):
234256
Int32
235257
"""
236258

259+
__slots__ = ()
260+
237261

238262
class Int16(SignedIntegerType):
239263
"""16-bit signed integer type.
@@ -247,6 +271,8 @@ class Int16(SignedIntegerType):
247271
Int16
248272
"""
249273

274+
__slots__ = ()
275+
250276

251277
class Int8(SignedIntegerType):
252278
"""8-bit signed integer type.
@@ -260,6 +286,8 @@ class Int8(SignedIntegerType):
260286
Int8
261287
"""
262288

289+
__slots__ = ()
290+
263291

264292
class UInt128(UnsignedIntegerType):
265293
"""128-bit unsigned integer type.
@@ -274,6 +302,8 @@ class UInt128(UnsignedIntegerType):
274302
UInt128
275303
"""
276304

305+
__slots__ = ()
306+
277307

278308
class UInt64(UnsignedIntegerType):
279309
"""64-bit unsigned integer type.
@@ -287,6 +317,8 @@ class UInt64(UnsignedIntegerType):
287317
UInt64
288318
"""
289319

320+
__slots__ = ()
321+
290322

291323
class UInt32(UnsignedIntegerType):
292324
"""32-bit unsigned integer type.
@@ -300,6 +332,8 @@ class UInt32(UnsignedIntegerType):
300332
UInt32
301333
"""
302334

335+
__slots__ = ()
336+
303337

304338
class UInt16(UnsignedIntegerType):
305339
"""16-bit unsigned integer type.
@@ -313,6 +347,8 @@ class UInt16(UnsignedIntegerType):
313347
UInt16
314348
"""
315349

350+
__slots__ = ()
351+
316352

317353
class UInt8(UnsignedIntegerType):
318354
"""8-bit unsigned integer type.
@@ -326,6 +362,8 @@ class UInt8(UnsignedIntegerType):
326362
UInt8
327363
"""
328364

365+
__slots__ = ()
366+
329367

330368
class Float64(FloatType):
331369
"""64-bit floating point type.
@@ -339,6 +377,8 @@ class Float64(FloatType):
339377
Float64
340378
"""
341379

380+
__slots__ = ()
381+
342382

343383
class Float32(FloatType):
344384
"""32-bit floating point type.
@@ -352,6 +392,8 @@ class Float32(FloatType):
352392
Float32
353393
"""
354394

395+
__slots__ = ()
396+
355397

356398
class String(DType):
357399
"""UTF-8 encoded string type.
@@ -364,6 +406,8 @@ class String(DType):
364406
String
365407
"""
366408

409+
__slots__ = ()
410+
367411

368412
class Boolean(DType):
369413
"""Boolean type.
@@ -376,6 +420,8 @@ class Boolean(DType):
376420
Boolean
377421
"""
378422

423+
__slots__ = ()
424+
379425

380426
class Object(DType):
381427
"""Data type for wrapping arbitrary Python objects.
@@ -389,6 +435,8 @@ class Object(DType):
389435
Object
390436
"""
391437

438+
__slots__ = ()
439+
392440

393441
class Unknown(DType):
394442
"""Type representing DataType values that could not be determined statically.
@@ -401,6 +449,8 @@ class Unknown(DType):
401449
Unknown
402450
"""
403451

452+
__slots__ = ()
453+
404454

405455
class _DatetimeMeta(type):
406456
@property
@@ -438,6 +488,8 @@ class Datetime(TemporalType, metaclass=_DatetimeMeta):
438488
Datetime(time_unit='ms', time_zone='Africa/Accra')
439489
"""
440490

491+
__slots__ = ("time_unit", "time_zone")
492+
441493
def __init__(
442494
self, time_unit: TimeUnit = "us", time_zone: str | timezone | None = None
443495
) -> None:
@@ -521,6 +573,8 @@ class Duration(TemporalType, metaclass=_DurationMeta):
521573
Duration(time_unit='ms')
522574
"""
523575

576+
__slots__ = ("time_unit",)
577+
524578
def __init__(self, time_unit: TimeUnit = "us") -> None:
525579
if time_unit not in {"s", "ms", "us", "ns"}:
526580
msg = (
@@ -573,6 +627,8 @@ class Categorical(DType):
573627
Categorical
574628
"""
575629

630+
__slots__ = ()
631+
576632

577633
class Enum(DType):
578634
"""A fixed categorical encoding of a unique set of strings.
@@ -586,6 +642,8 @@ class Enum(DType):
586642
Enum(categories=['beluga', 'narwhal', 'orca'])
587643
"""
588644

645+
__slots__ = ("_cached_categories", "_delayed_categories")
646+
589647
def __init__(self, categories: Iterable[str] | type[enum.Enum]) -> None:
590648
self._delayed_categories: _DeferredIterable[str] | None = None
591649
self._cached_categories: tuple[str, ...] | None = None
@@ -655,6 +713,7 @@ class Field:
655713
[Field('a', Int64), Field('b', List(String))]
656714
"""
657715

716+
__slots__ = ("dtype", "name")
658717
name: str
659718
"""The name of the field within its parent `Struct`."""
660719
dtype: IntoDType
@@ -713,6 +772,7 @@ class Struct(NestedType):
713772
Struct({'a': Int64, 'b': List(String)})
714773
"""
715774

775+
__slots__ = ("fields",)
716776
fields: list[Field]
717777
"""The fields that make up the struct."""
718778

@@ -782,6 +842,7 @@ class List(NestedType):
782842
List(String)
783843
"""
784844

845+
__slots__ = ("inner",)
785846
inner: IntoDType
786847
"""The DType of the values within each list."""
787848

@@ -832,6 +893,7 @@ class Array(NestedType):
832893
Array(Int32, shape=(2,))
833894
"""
834895

896+
__slots__ = ("inner", "shape", "size")
835897
inner: IntoDType
836898
"""The DType of the values within each array."""
837899
size: int
@@ -910,6 +972,8 @@ class Date(TemporalType):
910972
Date
911973
"""
912974

975+
__slots__ = ()
976+
913977

914978
class Time(TemporalType):
915979
"""Data type representing the time of day.
@@ -935,6 +999,8 @@ class Time(TemporalType):
935999
Time
9361000
"""
9371001

1002+
__slots__ = ()
1003+
9381004

9391005
class Binary(DType):
9401006
"""Binary type.
@@ -958,3 +1024,5 @@ class Binary(DType):
9581024
>>> nw.from_native(rel).collect_schema()["t"]
9591025
Binary
9601026
"""
1027+
1028+
__slots__ = ()

narwhals/stable/v1/_dtypes.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848

4949

5050
class Datetime(NwDatetime):
51+
__slots__ = NwDatetime.__slots__
52+
5153
@inherit_doc(NwDatetime)
5254
def __init__(
5355
self, time_unit: TimeUnit = "us", time_zone: str | timezone | None = None
@@ -59,6 +61,8 @@ def __hash__(self) -> int:
5961

6062

6163
class Duration(NwDuration):
64+
__slots__ = NwDuration.__slots__
65+
6266
@inherit_doc(NwDuration)
6367
def __init__(self, time_unit: TimeUnit = "us") -> None:
6468
super().__init__(time_unit)
@@ -81,6 +85,8 @@ class Enum(NwEnum):
8185
Enum
8286
"""
8387

88+
__slots__ = ()
89+
8490
def __init__(self) -> None:
8591
super(NwEnum, self).__init__()
8692

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,8 @@ extend-ignore-names = [
210210
"PLR0916", # too-many-boolean-expressions
211211
]
212212
"tpch/tests/*" = ["S101"]
213-
"utils/*" = ["S311"]
214-
"utils/bump_version.py" = ["S603", "S607", "T201"]
213+
"utils/*" = ["S311", "T201"]
214+
"utils/bump_version.py" = ["S603", "S607"]
215215
"tpch/execute/*" = ["T201"]
216216
"tpch/notebooks/*" = [
217217
"ANN001",

0 commit comments

Comments
 (0)