pydiverse-common 0.3.2__py2.py3-none-any.whl → 0.3.3__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,24 +12,33 @@ class Dtype:
12
12
  """Base class for all data types."""
13
13
 
14
14
  def __eq__(self, rhs):
15
+ """Return ``True`` if this dtype is equal to `rhs`."""
15
16
  return isinstance(rhs, Dtype) and type(self) is type(rhs)
16
17
 
17
18
  def __hash__(self):
19
+ """Return a hash for this dtype."""
18
20
  return hash(type(self))
19
21
 
20
22
  def __repr__(self):
23
+ """Return a string representation of this dtype."""
21
24
  return self.__class__.__name__
22
25
 
23
26
  @classmethod
24
27
  def is_int(cls):
28
+ """Return ``True`` if this dtype is an integer type."""
25
29
  return False
26
30
 
27
31
  @classmethod
28
32
  def is_float(cls):
33
+ """Return ``True`` if this dtype is a float type."""
29
34
  return False
30
35
 
31
36
  @classmethod
32
37
  def is_subtype(cls, rhs):
38
+ """Return ``True`` if this dtype is a subtype of `rhs`.
39
+
40
+ For example, ``Int8.is_subtype(Int())`` is ``True``.
41
+ """
33
42
  rhs_cls = type(rhs)
34
43
  return (
35
44
  (cls is rhs_cls)
@@ -39,6 +48,7 @@ class Dtype:
39
48
 
40
49
  @staticmethod
41
50
  def from_sql(sql_type) -> "Dtype":
51
+ """Convert a SQL type to a Dtype."""
42
52
  import sqlalchemy as sqa
43
53
 
44
54
  if isinstance(sql_type, sqa.SmallInteger):
@@ -73,14 +83,15 @@ class Dtype:
73
83
  if isinstance(sql_type, sqa.Interval):
74
84
  return Duration()
75
85
  if isinstance(sql_type, sqa.ARRAY):
76
- return List(Dtype.from_sql(sql_type.item_type.from_sql))
77
- if isinstance(sql_type, sqa.Null):
86
+ return List(Dtype.from_sql(sql_type.item_type))
87
+ if isinstance(sql_type, sqa.types.NullType):
78
88
  return NullType()
79
89
 
80
90
  raise TypeError
81
91
 
82
92
  @staticmethod
83
93
  def from_pandas(pandas_type) -> "Dtype":
94
+ """Convert a pandas type to a Dtype."""
84
95
  import numpy as np
85
96
  import pandas as pd
86
97
 
@@ -127,13 +138,14 @@ class Dtype:
127
138
  return Datetime()
128
139
  if pd.api.types.is_timedelta64_dtype(pandas_type):
129
140
  return Duration()
130
- # we don't know any decimal/time dtypes in pandas if column is not
141
+ # we don't know any decimal/time/null dtypes in pandas if column is not
131
142
  # arrow backed
132
143
 
133
144
  raise TypeError
134
145
 
135
146
  @staticmethod
136
147
  def from_arrow(arrow_type) -> "Dtype":
148
+ """Convert a PyArrow type to a Dtype."""
137
149
  import pyarrow as pa
138
150
 
139
151
  if pa.types.is_signed_integer(arrow_type):
@@ -179,10 +191,15 @@ class Dtype:
179
191
  return Time()
180
192
  if pa.types.is_duration(arrow_type):
181
193
  return Duration()
194
+ if pa.types.is_null(arrow_type):
195
+ return NullType()
196
+ if pa.types.is_list(arrow_type):
197
+ return List(Dtype.from_arrow(arrow_type.value_type))
182
198
  raise TypeError
183
199
 
184
200
  @staticmethod
185
201
  def from_polars(polars_type) -> "Dtype":
202
+ """Convert a Polars type to a Dtype."""
186
203
  import polars as pl
187
204
 
188
205
  if isinstance(polars_type, pl.List):
@@ -211,6 +228,7 @@ class Dtype:
211
228
  }[polars_type.base_type()]
212
229
 
213
230
  def to_sql(self):
231
+ """Convert this Dtype to a SQL type."""
214
232
  import sqlalchemy as sqa
215
233
 
216
234
  return {
@@ -237,6 +255,7 @@ class Dtype:
237
255
  }[self]
238
256
 
239
257
  def to_pandas(self, backend: PandasBackend = PandasBackend.ARROW):
258
+ """Convert this Dtype to a pandas type."""
240
259
  import pandas as pd
241
260
 
242
261
  if backend == PandasBackend.NUMPY:
@@ -247,12 +266,32 @@ class Dtype:
247
266
  return pd.ArrowDtype(self.to_arrow())
248
267
 
249
268
  def to_pandas_nullable(self, backend: PandasBackend = PandasBackend.ARROW):
269
+ """Convert this Dtype to a pandas nullable type.
270
+
271
+ Nullable can be either pandas extension types like StringDtype or ArrowDtype.
272
+
273
+ Parameters
274
+ ----------
275
+ backend : PandasBackend, optional
276
+ The pandas backend to use. Defaults to ``PandasBackend.ARROW``.
277
+ If ``PandasBackend.NUMPY`` is selected, this method will attempt
278
+ to return a NumPy-backed nullable pandas dtype. Note that
279
+ Time, NullType, and List will raise a TypeError for the
280
+ NUMPY backend as pandas doesn't have corresponding native
281
+ nullable dtypes for these.
282
+ """
250
283
  import pandas as pd
251
284
 
252
- if self == Time():
253
- if backend == PandasBackend.ARROW:
254
- return pd.ArrowDtype(self.to_arrow())
285
+ if backend == PandasBackend.ARROW:
286
+ return pd.ArrowDtype(self.to_arrow())
287
+
288
+ # we don't want to produce object columns
289
+ if isinstance(self, Time):
255
290
  raise TypeError("pandas doesn't have a native time dtype")
291
+ if isinstance(self, NullType):
292
+ raise TypeError("pandas doesn't have a native null dtype")
293
+ if isinstance(self, List):
294
+ raise TypeError("pandas doesn't have a native list dtype")
256
295
 
257
296
  return {
258
297
  Int(): pd.Int64Dtype(), # we default to 64 bit
@@ -277,6 +316,7 @@ class Dtype:
277
316
  }[self]
278
317
 
279
318
  def to_arrow(self):
319
+ """Convert this Dtype to a PyArrow type."""
280
320
  import pyarrow as pa
281
321
 
282
322
  return {
@@ -299,9 +339,11 @@ class Dtype:
299
339
  Time(): pa.time64("us"),
300
340
  Datetime(): pa.timestamp("us"),
301
341
  Duration(): pa.duration("us"),
342
+ NullType(): pa.null(),
302
343
  }[self]
303
344
 
304
345
  def to_polars(self: "Dtype"):
346
+ """Convert this Dtype to a Polars type."""
305
347
  import polars as pl
306
348
 
307
349
  return {
@@ -416,3 +458,8 @@ class List(Dtype):
416
458
  import polars as pl
417
459
 
418
460
  return pl.List(self.inner.to_polars())
461
+
462
+ def to_arrow(self):
463
+ import pyarrow as pa
464
+
465
+ return pa.list_(self.inner.to_arrow())
@@ -0,0 +1,14 @@
1
+ # Copyright (c) QuantCo and pydiverse contributors 2025-2025
2
+ # SPDX-License-Identifier: BSD-3-Clause
3
+
4
+ import inspect
5
+
6
+ import pydiverse.common.dtypes as dtypes
7
+
8
+ ALL_TYPES = [
9
+ getattr(dtypes, c)
10
+ for c in dir(dtypes)
11
+ if inspect.isclass(getattr(dtypes, c))
12
+ and issubclass(getattr(dtypes, c), dtypes.Dtype)
13
+ and c != "Dtype"
14
+ ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pydiverse-common
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Summary: Common functionality shared between pydiverse libraries
5
5
  Author: QuantCo, Inc.
6
6
  Author-email: Martin Trautmann <windiana@users.sf.net>, Finn Rudolph <finn.rudolph@t-online.de>
@@ -1,5 +1,6 @@
1
1
  pydiverse/common/__init__.py,sha256=eK3Wji6868cvXeq6e9YPRxi20vU6i9Lql4IzG6iB4B4,784
2
- pydiverse/common/dtypes.py,sha256=OtxOLnA5HIX9OandrrSgKS8bzERnntLRvQF-hSzvlbU,12509
2
+ pydiverse/common/dtypes.py,sha256=1ADpaWJbdNIFEE2DFjdIy2RRsp5Wg3UVnSM1ZN8XVdw,14555
3
+ pydiverse/common/testing.py,sha256=FcivI5wn0X3gzJhwnysKvCOgjSTTXaN6FtSFJ72jfSg,341
3
4
  pydiverse/common/version.py,sha256=1IU_m4r76_Qq0u-Tyo2_bERZFOkh0ZFueVzDqcCfLO0,336
4
5
  pydiverse/common/errors/__init__.py,sha256=FNeEfVbUa23b9sHkFsmxHYhY6sRgjaZysPQmlovpJrI,262
5
6
  pydiverse/common/util/__init__.py,sha256=fGdKZtLaTVBW7NfCpX7rZhKHwUzmBnsuY2akDOnAnjc,315
@@ -10,7 +11,7 @@ pydiverse/common/util/disposable.py,sha256=4XoGz70YRWA9TAqnUBvRCTAdsOGBviFN0gzxU
10
11
  pydiverse/common/util/hashing.py,sha256=6x77BKg-w61u59fuTe9di0BtU-kEKH6UTRcKsRoYJ84,1196
11
12
  pydiverse/common/util/import_.py,sha256=K7dSgz4YyrqEvqhoOzbwgD7D8HScMoO5XoSWtjbaoUs,4056
12
13
  pydiverse/common/util/structlog.py,sha256=g0d8yaXBzAxmGNGZYMnMP9dsSQ__jN44GAY8Mb0ABeI,3487
13
- pydiverse_common-0.3.2.dist-info/METADATA,sha256=fwld0ZxdHloPOoeRj-X9WLZPwrNpQ4QuYeD1BZJ7qPo,3333
14
- pydiverse_common-0.3.2.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
15
- pydiverse_common-0.3.2.dist-info/licenses/LICENSE,sha256=AcE6SDVuAq6v9ZLE_8eOCe_NvSE0rAPR3NR7lSowYh4,1517
16
- pydiverse_common-0.3.2.dist-info/RECORD,,
14
+ pydiverse_common-0.3.3.dist-info/METADATA,sha256=YWmuuq0eJwf20_-rHFz9XsRS8gu3T7NEeOEvyV6QWHE,3333
15
+ pydiverse_common-0.3.3.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
16
+ pydiverse_common-0.3.3.dist-info/licenses/LICENSE,sha256=AcE6SDVuAq6v9ZLE_8eOCe_NvSE0rAPR3NR7lSowYh4,1517
17
+ pydiverse_common-0.3.3.dist-info/RECORD,,