pydiverse-common 0.3.2__tar.gz → 0.3.4__tar.gz

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.
Files changed (45) hide show
  1. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/PKG-INFO +3 -1
  2. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/docs/source/changelog.md +7 -0
  3. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/docs/source/reference/api.rst +23 -0
  4. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/pixi.lock +80 -60
  5. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/pixi.toml +0 -1
  6. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/pyproject.toml +5 -4
  7. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/src/pydiverse/common/dtypes.py +53 -6
  8. pydiverse_common-0.3.4/src/pydiverse/common/testing.py +14 -0
  9. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/tests/dtypes/test_dtype_pandas.py +48 -0
  10. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/tests/dtypes/test_dtype_polars.py +22 -4
  11. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/tests/dtypes/test_dtype_pyarrow.py +18 -0
  12. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/tests/dtypes/test_dtype_sqlalchemy.py +29 -0
  13. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/.gitattributes +0 -0
  14. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/.github/CODEOWNERS +0 -0
  15. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  16. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/.github/dependabot.yml +0 -0
  17. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/.github/workflows/release.yml +0 -0
  18. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/.github/workflows/tests.yml +0 -0
  19. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/.github/workflows/update-lockfiles.yml +0 -0
  20. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/.gitignore +0 -0
  21. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/.pre-commit-config.yaml +0 -0
  22. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/.readthedocs.yaml +0 -0
  23. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/LICENSE +0 -0
  24. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/README.md +0 -0
  25. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/docs/Makefile +0 -0
  26. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/docs/make.bat +0 -0
  27. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/docs/package/README.md +0 -0
  28. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/docs/source/conf.py +0 -0
  29. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/docs/source/index.md +0 -0
  30. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/docs/source/license.md +0 -0
  31. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/pytest.ini +0 -0
  32. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/src/pydiverse/common/__init__.py +0 -0
  33. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/src/pydiverse/common/errors/__init__.py +0 -0
  34. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/src/pydiverse/common/util/__init__.py +0 -0
  35. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/src/pydiverse/common/util/computation_tracing.py +0 -0
  36. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/src/pydiverse/common/util/deep_map.py +0 -0
  37. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/src/pydiverse/common/util/deep_merge.py +0 -0
  38. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/src/pydiverse/common/util/disposable.py +0 -0
  39. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/src/pydiverse/common/util/hashing.py +0 -0
  40. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/src/pydiverse/common/util/import_.py +0 -0
  41. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/src/pydiverse/common/util/structlog.py +0 -0
  42. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/src/pydiverse/common/version.py +0 -0
  43. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/tests/conftest.py +0 -0
  44. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/tests/test_util.py +0 -0
  45. {pydiverse_common-0.3.2 → pydiverse_common-0.3.4}/tests/test_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pydiverse-common
3
- Version: 0.3.2
3
+ Version: 0.3.4
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>
@@ -47,6 +47,8 @@ Classifier: Programming Language :: SQL
47
47
  Classifier: Topic :: Database
48
48
  Classifier: Topic :: Scientific/Engineering
49
49
  Classifier: Topic :: Software Development
50
+ Requires-Python: <3.14,>=3.10
51
+ Requires-Dist: python-box<8.0.0,>=7.3.2
50
52
  Description-Content-Type: text/markdown
51
53
 
52
54
  # pydiverse.common
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.4 (2025-06-10)
4
+ - fixed pypi package dependencies
5
+
6
+ ## 0.3.3 (2025-06-08)
7
+ - improved support of None and List type
8
+ - bug fixes in type conversion functions
9
+
3
10
  ## 0.3.2 (2025-06-08)
4
11
  - pydiverse.common.__version__ (implemented via importlib.metadata)
5
12
 
@@ -8,25 +8,48 @@ Public
8
8
  .. py:module:: pydiverse.common
9
9
 
10
10
  .. autoclass:: Dtype
11
+ :members:
11
12
  .. autoclass:: Bool
13
+ :members:
12
14
  .. autoclass:: Date
15
+ :members:
13
16
  .. autoclass:: Datetime
17
+ :members:
14
18
  .. autoclass:: Decimal
19
+ :members:
15
20
  .. autoclass:: Duration
21
+ :members:
16
22
  .. autoclass:: Float
23
+ :members:
17
24
  .. autoclass:: Float32
25
+ :members:
18
26
  .. autoclass:: Float64
27
+ :members:
19
28
  .. autoclass:: Int
29
+ :members:
20
30
  .. autoclass:: Int8
31
+ :members:
21
32
  .. autoclass:: Int16
33
+ :members:
22
34
  .. autoclass:: Int32
35
+ :members:
23
36
  .. autoclass:: Int64
37
+ :members:
24
38
  .. autoclass:: NullType
39
+ :members:
25
40
  .. autoclass:: String
41
+ :members:
26
42
  .. autoclass:: Time
43
+ :members:
27
44
  .. autoclass:: UInt8
45
+ :members:
28
46
  .. autoclass:: UInt16
47
+ :members:
29
48
  .. autoclass:: UInt32
49
+ :members:
30
50
  .. autoclass:: UInt64
51
+ :members:
31
52
  .. autoclass:: List
53
+ :members:
32
54
  .. autoclass:: PandasBackend
55
+ :members:
@@ -6888,8 +6888,6 @@ packages:
6888
6888
  - pycparser
6889
6889
  - python >=3.10,<3.11.0a0
6890
6890
  - python_abi 3.10.* *_cp310
6891
- arch: x86_64
6892
- platform: linux
6893
6891
  license: MIT
6894
6892
  license_family: MIT
6895
6893
  size: 243532
@@ -6932,8 +6930,6 @@ packages:
6932
6930
  - pycparser
6933
6931
  - python >=3.13.0rc1,<3.14.0a0
6934
6932
  - python_abi 3.13.* *_cp313
6935
- arch: x86_64
6936
- platform: linux
6937
6933
  license: MIT
6938
6934
  license_family: MIT
6939
6935
  size: 295514
@@ -6947,8 +6943,6 @@ packages:
6947
6943
  - pycparser
6948
6944
  - python >=3.10,<3.11.0a0
6949
6945
  - python_abi 3.10.* *_cp310
6950
- arch: aarch64
6951
- platform: linux
6952
6946
  license: MIT
6953
6947
  license_family: MIT
6954
6948
  size: 260852
@@ -6988,8 +6982,6 @@ packages:
6988
6982
  - pycparser
6989
6983
  - python >=3.13.0rc1,<3.14.0a0
6990
6984
  - python_abi 3.13.* *_cp313
6991
- arch: aarch64
6992
- platform: linux
6993
6985
  license: MIT
6994
6986
  license_family: MIT
6995
6987
  size: 314846
@@ -7003,8 +6995,6 @@ packages:
7003
6995
  - pycparser
7004
6996
  - python >=3.10,<3.11.0a0
7005
6997
  - python_abi 3.10.* *_cp310
7006
- arch: x86_64
7007
- platform: osx
7008
6998
  license: MIT
7009
6999
  license_family: MIT
7010
7000
  size: 229844
@@ -7044,8 +7034,6 @@ packages:
7044
7034
  - pycparser
7045
7035
  - python >=3.13.0rc1,<3.14.0a0
7046
7036
  - python_abi 3.13.* *_cp313
7047
- arch: x86_64
7048
- platform: osx
7049
7037
  license: MIT
7050
7038
  license_family: MIT
7051
7039
  size: 284540
@@ -7060,8 +7048,6 @@ packages:
7060
7048
  - python >=3.10,<3.11.0a0
7061
7049
  - python >=3.10,<3.11.0a0 *_cpython
7062
7050
  - python_abi 3.10.* *_cp310
7063
- arch: arm64
7064
- platform: osx
7065
7051
  license: MIT
7066
7052
  license_family: MIT
7067
7053
  size: 229224
@@ -7104,8 +7090,6 @@ packages:
7104
7090
  - python >=3.13.0rc1,<3.14.0a0
7105
7091
  - python >=3.13.0rc1,<3.14.0a0 *_cp313
7106
7092
  - python_abi 3.13.* *_cp313
7107
- arch: arm64
7108
- platform: osx
7109
7093
  license: MIT
7110
7094
  license_family: MIT
7111
7095
  size: 282115
@@ -7120,8 +7104,6 @@ packages:
7120
7104
  - ucrt >=10.0.20348.0
7121
7105
  - vc >=14.2,<15
7122
7106
  - vc14_runtime >=14.29.30139
7123
- arch: x86_64
7124
- platform: win
7125
7107
  license: MIT
7126
7108
  license_family: MIT
7127
7109
  size: 238887
@@ -7164,8 +7146,6 @@ packages:
7164
7146
  - ucrt >=10.0.20348.0
7165
7147
  - vc >=14.2,<15
7166
7148
  - vc14_runtime >=14.29.30139
7167
- arch: x86_64
7168
- platform: win
7169
7149
  license: MIT
7170
7150
  license_family: MIT
7171
7151
  size: 291828
@@ -14268,6 +14248,8 @@ packages:
14268
14248
  - tzdata
14269
14249
  constrains:
14270
14250
  - python_abi 3.10.* *_cp310
14251
+ arch: x86_64
14252
+ platform: linux
14271
14253
  license: Python-2.0
14272
14254
  size: 25042108
14273
14255
  timestamp: 1749049293621
@@ -14294,6 +14276,8 @@ packages:
14294
14276
  - tzdata
14295
14277
  constrains:
14296
14278
  - python_abi 3.11.* *_cp311
14279
+ arch: x86_64
14280
+ platform: linux
14297
14281
  license: Python-2.0
14298
14282
  size: 30629559
14299
14283
  timestamp: 1749050021812
@@ -14346,6 +14330,8 @@ packages:
14346
14330
  - tzdata
14347
14331
  constrains:
14348
14332
  - python_abi 3.12.* *_cp312
14333
+ arch: x86_64
14334
+ platform: linux
14349
14335
  license: Python-2.0
14350
14336
  size: 31445023
14351
14337
  timestamp: 1749050216615
@@ -14371,6 +14357,8 @@ packages:
14371
14357
  - readline >=8.2,<9.0a0
14372
14358
  - tk >=8.6.13,<8.7.0a0
14373
14359
  - tzdata
14360
+ arch: x86_64
14361
+ platform: linux
14374
14362
  license: Python-2.0
14375
14363
  size: 33268245
14376
14364
  timestamp: 1744665022734
@@ -14397,6 +14385,8 @@ packages:
14397
14385
  - tzdata
14398
14386
  constrains:
14399
14387
  - python_abi 3.10.* *_cp310
14388
+ arch: aarch64
14389
+ platform: linux
14400
14390
  license: Python-2.0
14401
14391
  size: 13039547
14402
14392
  timestamp: 1749048139656
@@ -14422,6 +14412,8 @@ packages:
14422
14412
  - tzdata
14423
14413
  constrains:
14424
14414
  - python_abi 3.11.* *_cp311
14415
+ arch: aarch64
14416
+ platform: linux
14425
14417
  license: Python-2.0
14426
14418
  size: 15306062
14427
14419
  timestamp: 1749048115706
@@ -14447,6 +14439,8 @@ packages:
14447
14439
  - tzdata
14448
14440
  constrains:
14449
14441
  - python_abi 3.12.* *_cp312
14442
+ arch: aarch64
14443
+ platform: linux
14450
14444
  license: Python-2.0
14451
14445
  size: 13738751
14452
14446
  timestamp: 1749047852768
@@ -14471,6 +14465,8 @@ packages:
14471
14465
  - readline >=8.2,<9.0a0
14472
14466
  - tk >=8.6.13,<8.7.0a0
14473
14467
  - tzdata
14468
+ arch: aarch64
14469
+ platform: linux
14474
14470
  license: Python-2.0
14475
14471
  size: 33727843
14476
14472
  timestamp: 1744663385273
@@ -14493,6 +14489,8 @@ packages:
14493
14489
  - tzdata
14494
14490
  constrains:
14495
14491
  - python_abi 3.10.* *_cp310
14492
+ arch: x86_64
14493
+ platform: osx
14496
14494
  license: Python-2.0
14497
14495
  size: 12921103
14498
14496
  timestamp: 1749048830353
@@ -14514,6 +14512,8 @@ packages:
14514
14512
  - tzdata
14515
14513
  constrains:
14516
14514
  - python_abi 3.11.* *_cp311
14515
+ arch: x86_64
14516
+ platform: osx
14517
14517
  license: Python-2.0
14518
14518
  size: 15423460
14519
14519
  timestamp: 1749049420299
@@ -14556,6 +14556,8 @@ packages:
14556
14556
  - tzdata
14557
14557
  constrains:
14558
14558
  - python_abi 3.12.* *_cp312
14559
+ arch: x86_64
14560
+ platform: osx
14559
14561
  license: Python-2.0
14560
14562
  size: 13571569
14561
14563
  timestamp: 1749049058713
@@ -14578,6 +14580,8 @@ packages:
14578
14580
  - readline >=8.2,<9.0a0
14579
14581
  - tk >=8.6.13,<8.7.0a0
14580
14582
  - tzdata
14583
+ arch: x86_64
14584
+ platform: osx
14581
14585
  license: Python-2.0
14582
14586
  size: 13875464
14583
14587
  timestamp: 1744664784298
@@ -14600,6 +14604,8 @@ packages:
14600
14604
  - tzdata
14601
14605
  constrains:
14602
14606
  - python_abi 3.10.* *_cp310
14607
+ arch: arm64
14608
+ platform: osx
14603
14609
  license: Python-2.0
14604
14610
  size: 12385306
14605
14611
  timestamp: 1749048585934
@@ -14621,6 +14627,8 @@ packages:
14621
14627
  - tzdata
14622
14628
  constrains:
14623
14629
  - python_abi 3.11.* *_cp311
14630
+ arch: arm64
14631
+ platform: osx
14624
14632
  license: Python-2.0
14625
14633
  size: 14573820
14626
14634
  timestamp: 1749048947732
@@ -14642,6 +14650,8 @@ packages:
14642
14650
  - tzdata
14643
14651
  constrains:
14644
14652
  - python_abi 3.12.* *_cp312
14653
+ arch: arm64
14654
+ platform: osx
14645
14655
  license: Python-2.0
14646
14656
  size: 13009234
14647
14657
  timestamp: 1749048134449
@@ -14664,6 +14674,8 @@ packages:
14664
14674
  - readline >=8.2,<9.0a0
14665
14675
  - tk >=8.6.13,<8.7.0a0
14666
14676
  - tzdata
14677
+ arch: arm64
14678
+ platform: osx
14667
14679
  license: Python-2.0
14668
14680
  size: 12136505
14669
14681
  timestamp: 1744663807953
@@ -14686,6 +14698,8 @@ packages:
14686
14698
  - vc14_runtime >=14.29.30139
14687
14699
  constrains:
14688
14700
  - python_abi 3.10.* *_cp310
14701
+ arch: x86_64
14702
+ platform: win
14689
14703
  license: Python-2.0
14690
14704
  size: 15832933
14691
14705
  timestamp: 1749048670944
@@ -14707,6 +14721,8 @@ packages:
14707
14721
  - vc14_runtime >=14.29.30139
14708
14722
  constrains:
14709
14723
  - python_abi 3.11.* *_cp311
14724
+ arch: x86_64
14725
+ platform: win
14710
14726
  license: Python-2.0
14711
14727
  size: 18242669
14712
14728
  timestamp: 1749048351218
@@ -14728,6 +14744,8 @@ packages:
14728
14744
  - vc14_runtime >=14.29.30139
14729
14745
  constrains:
14730
14746
  - python_abi 3.12.* *_cp312
14747
+ arch: x86_64
14748
+ platform: win
14731
14749
  license: Python-2.0
14732
14750
  size: 15829289
14733
14751
  timestamp: 1749047682640
@@ -14750,6 +14768,8 @@ packages:
14750
14768
  - ucrt >=10.0.20348.0
14751
14769
  - vc >=14.2,<15
14752
14770
  - vc14_runtime >=14.29.30139
14771
+ arch: x86_64
14772
+ platform: win
14753
14773
  license: Python-2.0
14754
14774
  size: 16614435
14755
14775
  timestamp: 1744663103022
@@ -14765,6 +14785,8 @@ packages:
14765
14785
  - python_abi 3.10.* *_cp310
14766
14786
  - ruamel.yaml
14767
14787
  - toml
14788
+ arch: x86_64
14789
+ platform: linux
14768
14790
  license: MIT
14769
14791
  license_family: MIT
14770
14792
  size: 752684
@@ -14780,6 +14802,8 @@ packages:
14780
14802
  - python_abi 3.11.* *_cp311
14781
14803
  - ruamel.yaml
14782
14804
  - toml
14805
+ arch: x86_64
14806
+ platform: linux
14783
14807
  license: MIT
14784
14808
  license_family: MIT
14785
14809
  size: 774302
@@ -14795,6 +14819,8 @@ packages:
14795
14819
  - python_abi 3.12.* *_cp312
14796
14820
  - ruamel.yaml
14797
14821
  - toml
14822
+ arch: x86_64
14823
+ platform: linux
14798
14824
  license: MIT
14799
14825
  license_family: MIT
14800
14826
  size: 768872
@@ -14810,6 +14836,8 @@ packages:
14810
14836
  - python_abi 3.13.* *_cp313
14811
14837
  - ruamel.yaml
14812
14838
  - toml
14839
+ arch: x86_64
14840
+ platform: linux
14813
14841
  license: MIT
14814
14842
  license_family: MIT
14815
14843
  size: 766775
@@ -14825,6 +14853,8 @@ packages:
14825
14853
  - python_abi 3.10.* *_cp310
14826
14854
  - ruamel.yaml
14827
14855
  - toml
14856
+ arch: aarch64
14857
+ platform: linux
14828
14858
  license: MIT
14829
14859
  license_family: MIT
14830
14860
  size: 715030
@@ -14840,6 +14870,8 @@ packages:
14840
14870
  - python_abi 3.11.* *_cp311
14841
14871
  - ruamel.yaml
14842
14872
  - toml
14873
+ arch: aarch64
14874
+ platform: linux
14843
14875
  license: MIT
14844
14876
  license_family: MIT
14845
14877
  size: 734401
@@ -14855,6 +14887,8 @@ packages:
14855
14887
  - python_abi 3.12.* *_cp312
14856
14888
  - ruamel.yaml
14857
14889
  - toml
14890
+ arch: aarch64
14891
+ platform: linux
14858
14892
  license: MIT
14859
14893
  license_family: MIT
14860
14894
  size: 726035
@@ -14870,6 +14904,8 @@ packages:
14870
14904
  - python_abi 3.13.* *_cp313
14871
14905
  - ruamel.yaml
14872
14906
  - toml
14907
+ arch: aarch64
14908
+ platform: linux
14873
14909
  license: MIT
14874
14910
  license_family: MIT
14875
14911
  size: 724285
@@ -14884,6 +14920,8 @@ packages:
14884
14920
  - python_abi 3.10.* *_cp310
14885
14921
  - ruamel.yaml
14886
14922
  - toml
14923
+ arch: x86_64
14924
+ platform: osx
14887
14925
  license: MIT
14888
14926
  license_family: MIT
14889
14927
  size: 686709
@@ -14898,6 +14936,8 @@ packages:
14898
14936
  - python_abi 3.11.* *_cp311
14899
14937
  - ruamel.yaml
14900
14938
  - toml
14939
+ arch: x86_64
14940
+ platform: osx
14901
14941
  license: MIT
14902
14942
  license_family: MIT
14903
14943
  size: 698995
@@ -14912,6 +14952,8 @@ packages:
14912
14952
  - python_abi 3.12.* *_cp312
14913
14953
  - ruamel.yaml
14914
14954
  - toml
14955
+ arch: x86_64
14956
+ platform: osx
14915
14957
  license: MIT
14916
14958
  license_family: MIT
14917
14959
  size: 685217
@@ -14926,6 +14968,8 @@ packages:
14926
14968
  - python_abi 3.13.* *_cp313
14927
14969
  - ruamel.yaml
14928
14970
  - toml
14971
+ arch: x86_64
14972
+ platform: osx
14929
14973
  license: MIT
14930
14974
  license_family: MIT
14931
14975
  size: 687987
@@ -14941,6 +14985,8 @@ packages:
14941
14985
  - python_abi 3.10.* *_cp310
14942
14986
  - ruamel.yaml
14943
14987
  - toml
14988
+ arch: arm64
14989
+ platform: osx
14944
14990
  license: MIT
14945
14991
  license_family: MIT
14946
14992
  size: 683806
@@ -14956,6 +15002,8 @@ packages:
14956
15002
  - python_abi 3.11.* *_cp311
14957
15003
  - ruamel.yaml
14958
15004
  - toml
15005
+ arch: arm64
15006
+ platform: osx
14959
15007
  license: MIT
14960
15008
  license_family: MIT
14961
15009
  size: 691227
@@ -14971,6 +15019,8 @@ packages:
14971
15019
  - python_abi 3.12.* *_cp312
14972
15020
  - ruamel.yaml
14973
15021
  - toml
15022
+ arch: arm64
15023
+ platform: osx
14974
15024
  license: MIT
14975
15025
  license_family: MIT
14976
15026
  size: 681412
@@ -14986,6 +15036,8 @@ packages:
14986
15036
  - python_abi 3.13.* *_cp313
14987
15037
  - ruamel.yaml
14988
15038
  - toml
15039
+ arch: arm64
15040
+ platform: osx
14989
15041
  license: MIT
14990
15042
  license_family: MIT
14991
15043
  size: 684872
@@ -15002,6 +15054,8 @@ packages:
15002
15054
  - ucrt >=10.0.20348.0
15003
15055
  - vc >=14.2,<15
15004
15056
  - vc14_runtime >=14.29.30139
15057
+ arch: x86_64
15058
+ platform: win
15005
15059
  license: MIT
15006
15060
  license_family: MIT
15007
15061
  size: 607423
@@ -15018,6 +15072,8 @@ packages:
15018
15072
  - ucrt >=10.0.20348.0
15019
15073
  - vc >=14.2,<15
15020
15074
  - vc14_runtime >=14.29.30139
15075
+ arch: x86_64
15076
+ platform: win
15021
15077
  license: MIT
15022
15078
  license_family: MIT
15023
15079
  size: 628594
@@ -15034,6 +15090,8 @@ packages:
15034
15090
  - ucrt >=10.0.20348.0
15035
15091
  - vc >=14.2,<15
15036
15092
  - vc14_runtime >=14.29.30139
15093
+ arch: x86_64
15094
+ platform: win
15037
15095
  license: MIT
15038
15096
  license_family: MIT
15039
15097
  size: 607016
@@ -15050,6 +15108,8 @@ packages:
15050
15108
  - ucrt >=10.0.20348.0
15051
15109
  - vc >=14.2,<15
15052
15110
  - vc14_runtime >=14.29.30139
15111
+ arch: x86_64
15112
+ platform: win
15053
15113
  license: MIT
15054
15114
  license_family: MIT
15055
15115
  size: 604818
@@ -15199,8 +15259,6 @@ packages:
15199
15259
  - python >=3.10,<3.11.0a0
15200
15260
  - python_abi 3.10.* *_cp310
15201
15261
  - yaml >=0.2.5,<0.3.0a0
15202
- arch: x86_64
15203
- platform: linux
15204
15262
  license: MIT
15205
15263
  license_family: MIT
15206
15264
  size: 182769
@@ -15240,8 +15298,6 @@ packages:
15240
15298
  - python >=3.13,<3.14.0a0
15241
15299
  - python_abi 3.13.* *_cp313
15242
15300
  - yaml >=0.2.5,<0.3.0a0
15243
- arch: x86_64
15244
- platform: linux
15245
15301
  license: MIT
15246
15302
  license_family: MIT
15247
15303
  size: 205919
@@ -15255,8 +15311,6 @@ packages:
15255
15311
  - python >=3.10,<3.11.0a0 *_cpython
15256
15312
  - python_abi 3.10.* *_cp310
15257
15313
  - yaml >=0.2.5,<0.3.0a0
15258
- arch: aarch64
15259
- platform: linux
15260
15314
  license: MIT
15261
15315
  license_family: MIT
15262
15316
  size: 174914
@@ -15296,8 +15350,6 @@ packages:
15296
15350
  - python >=3.13,<3.14.0a0 *_cp313
15297
15351
  - python_abi 3.13.* *_cp313
15298
15352
  - yaml >=0.2.5,<0.3.0a0
15299
- arch: aarch64
15300
- platform: linux
15301
15353
  license: MIT
15302
15354
  license_family: MIT
15303
15355
  size: 198985
@@ -15310,8 +15362,6 @@ packages:
15310
15362
  - python >=3.10,<3.11.0a0
15311
15363
  - python_abi 3.10.* *_cp310
15312
15364
  - yaml >=0.2.5,<0.3.0a0
15313
- arch: x86_64
15314
- platform: osx
15315
15365
  license: MIT
15316
15366
  license_family: MIT
15317
15367
  size: 168613
@@ -15348,8 +15398,6 @@ packages:
15348
15398
  - python >=3.13,<3.14.0a0
15349
15399
  - python_abi 3.13.* *_cp313
15350
15400
  - yaml >=0.2.5,<0.3.0a0
15351
- arch: x86_64
15352
- platform: osx
15353
15401
  license: MIT
15354
15402
  license_family: MIT
15355
15403
  size: 196573
@@ -15363,8 +15411,6 @@ packages:
15363
15411
  - python >=3.10,<3.11.0a0 *_cpython
15364
15412
  - python_abi 3.10.* *_cp310
15365
15413
  - yaml >=0.2.5,<0.3.0a0
15366
- arch: arm64
15367
- platform: osx
15368
15414
  license: MIT
15369
15415
  license_family: MIT
15370
15416
  size: 166853
@@ -15404,8 +15450,6 @@ packages:
15404
15450
  - python >=3.13,<3.14.0a0 *_cp313
15405
15451
  - python_abi 3.13.* *_cp313
15406
15452
  - yaml >=0.2.5,<0.3.0a0
15407
- arch: arm64
15408
- platform: osx
15409
15453
  license: MIT
15410
15454
  license_family: MIT
15411
15455
  size: 194243
@@ -15420,8 +15464,6 @@ packages:
15420
15464
  - vc >=14.2,<15
15421
15465
  - vc14_runtime >=14.29.30139
15422
15466
  - yaml >=0.2.5,<0.3.0a0
15423
- arch: x86_64
15424
- platform: win
15425
15467
  license: MIT
15426
15468
  license_family: MIT
15427
15469
  size: 157941
@@ -15464,8 +15506,6 @@ packages:
15464
15506
  - vc >=14.2,<15
15465
15507
  - vc14_runtime >=14.29.30139
15466
15508
  - yaml >=0.2.5,<0.3.0a0
15467
- arch: x86_64
15468
- platform: win
15469
15509
  license: MIT
15470
15510
  license_family: MIT
15471
15511
  size: 182783
@@ -17377,8 +17417,6 @@ packages:
17377
17417
  - libstdcxx >=13
17378
17418
  - python >=3.10,<3.11.0a0
17379
17419
  - python_abi 3.10.* *_cp310
17380
- arch: x86_64
17381
- platform: linux
17382
17420
  license: MIT
17383
17421
  license_family: MIT
17384
17422
  size: 13756
@@ -17421,8 +17459,6 @@ packages:
17421
17459
  - libstdcxx >=13
17422
17460
  - python >=3.13.0rc1,<3.14.0a0
17423
17461
  - python_abi 3.13.* *_cp313
17424
- arch: x86_64
17425
- platform: linux
17426
17462
  license: MIT
17427
17463
  license_family: MIT
17428
17464
  size: 13916
@@ -17437,8 +17473,6 @@ packages:
17437
17473
  - python >=3.10,<3.11.0a0
17438
17474
  - python >=3.10,<3.11.0a0 *_cpython
17439
17475
  - python_abi 3.10.* *_cp310
17440
- arch: aarch64
17441
- platform: linux
17442
17476
  license: MIT
17443
17477
  license_family: MIT
17444
17478
  size: 14690
@@ -17481,8 +17515,6 @@ packages:
17481
17515
  - python >=3.13.0rc1,<3.14.0a0
17482
17516
  - python >=3.13.0rc1,<3.14.0a0 *_cp313
17483
17517
  - python_abi 3.13.* *_cp313
17484
- arch: aarch64
17485
- platform: linux
17486
17518
  license: MIT
17487
17519
  license_family: MIT
17488
17520
  size: 14819
@@ -17496,8 +17528,6 @@ packages:
17496
17528
  - libcxx >=17
17497
17529
  - python >=3.10,<3.11.0a0
17498
17530
  - python_abi 3.10.* *_cp310
17499
- arch: x86_64
17500
- platform: osx
17501
17531
  license: MIT
17502
17532
  license_family: MIT
17503
17533
  size: 12925
@@ -17537,8 +17567,6 @@ packages:
17537
17567
  - libcxx >=17
17538
17568
  - python >=3.13.0rc1,<3.14.0a0
17539
17569
  - python_abi 3.13.* *_cp313
17540
- arch: x86_64
17541
- platform: osx
17542
17570
  license: MIT
17543
17571
  license_family: MIT
17544
17572
  size: 13126
@@ -17553,8 +17581,6 @@ packages:
17553
17581
  - python >=3.10,<3.11.0a0
17554
17582
  - python >=3.10,<3.11.0a0 *_cpython
17555
17583
  - python_abi 3.10.* *_cp310
17556
- arch: arm64
17557
- platform: osx
17558
17584
  license: MIT
17559
17585
  license_family: MIT
17560
17586
  size: 13565
@@ -17597,8 +17623,6 @@ packages:
17597
17623
  - python >=3.13.0rc1,<3.14.0a0
17598
17624
  - python >=3.13.0rc1,<3.14.0a0 *_cp313
17599
17625
  - python_abi 3.13.* *_cp313
17600
- arch: arm64
17601
- platform: osx
17602
17626
  license: MIT
17603
17627
  license_family: MIT
17604
17628
  size: 13689
@@ -17613,8 +17637,6 @@ packages:
17613
17637
  - ucrt >=10.0.20348.0
17614
17638
  - vc >=14.2,<15
17615
17639
  - vc14_runtime >=14.29.30139
17616
- arch: x86_64
17617
- platform: win
17618
17640
  license: MIT
17619
17641
  license_family: MIT
17620
17642
  size: 17065
@@ -17657,8 +17679,6 @@ packages:
17657
17679
  - ucrt >=10.0.20348.0
17658
17680
  - vc >=14.2,<15
17659
17681
  - vc14_runtime >=14.29.30139
17660
- arch: x86_64
17661
- platform: win
17662
17682
  license: MIT
17663
17683
  license_family: MIT
17664
17684
  size: 17210
@@ -6,7 +6,6 @@ authors = [
6
6
  channels = ["conda-forge"]
7
7
  name = "pydiverse.common"
8
8
  platforms = ["linux-64", "osx-64", "osx-arm64", "win-64", "linux-aarch64"]
9
- version = "0.1.0"
10
9
 
11
10
  [tasks]
12
11
  postinstall = "pip install --no-build-isolation --no-deps --disable-pip-version-check -e ."
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pydiverse-common"
3
- version = "0.3.2"
3
+ version = "0.3.4"
4
4
  description = "Common functionality shared between pydiverse libraries"
5
5
  authors = [
6
6
  { name = "QuantCo, Inc." },
@@ -24,19 +24,20 @@ classifiers = [
24
24
  "Topic :: Scientific/Engineering",
25
25
  "Topic :: Software Development",
26
26
  ]
27
+ requires-python = ">=3.10,<3.14"
28
+ dependencies = ["python-box>=7.3.2,<8.0.0"]
27
29
 
28
30
  [tool.hatch.build.targets.wheel]
29
31
  packages = ["src/pydiverse"]
30
32
 
31
33
  [tool.ruff]
32
- fix = true
33
34
  target-version = "py310"
34
35
  extend-exclude = ["docs/*"]
36
+ fix = true
35
37
 
36
38
  [tool.ruff.lint]
37
39
  select = ["F", "E", "UP", "W", "I001", "I002", "B", "A"]
38
- ignore = ["B028"]
39
- # 'ignore-init-module-imports' is deprecated and removed per warning
40
+ #ignore = ["B028"]
40
41
 
41
42
  [tool.ruff.lint.per-file-ignores]
42
43
  #"__init__.py" = ["F401", "F403"]
@@ -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
+ ]
@@ -5,6 +5,9 @@ import types
5
5
 
6
6
  import pytest
7
7
 
8
+ import pydiverse.common as pdc
9
+ from pydiverse.common.testing import ALL_TYPES
10
+
8
11
  try:
9
12
  import numpy as np
10
13
  import pandas as pd
@@ -141,3 +144,48 @@ def test_dtype_to_pandas_pyarrow():
141
144
  assert_conversion(Date(), pa.date32())
142
145
  assert_conversion(Time(), pa.time64("us"))
143
146
  assert_conversion(Datetime(), pa.timestamp("us"))
147
+
148
+
149
+ @pytest.mark.skipif(np is None, reason="requires pandas, numpy, and pyarrow")
150
+ @pytest.mark.parametrize(
151
+ "type_",
152
+ ALL_TYPES,
153
+ )
154
+ def test_all_types_numpy(type_):
155
+ if type_ is pdc.List:
156
+ type_obj = type_(pdc.Int64())
157
+ else:
158
+ type_obj = type_()
159
+ if type_ is pdc.NullType:
160
+ with pytest.raises(TypeError, match="pandas doesn't have a native null dtype"):
161
+ type_obj.to_pandas(PandasBackend.NUMPY)
162
+ elif type_ is pdc.Time:
163
+ with pytest.raises(TypeError, match="pandas doesn't have a native time dtype"):
164
+ type_obj.to_pandas(PandasBackend.NUMPY)
165
+ elif type_ is pdc.List:
166
+ with pytest.raises(TypeError, match="pandas doesn't have a native list dtype"):
167
+ type_obj.to_pandas(PandasBackend.NUMPY)
168
+ else:
169
+ dst_type = type_obj.to_pandas(PandasBackend.NUMPY)
170
+ back_type = Dtype.from_pandas(dst_type)
171
+ if type_ is pdc.Decimal:
172
+ assert isinstance(back_type, pdc.Float64)
173
+ elif type_ is pdc.Date:
174
+ assert isinstance(back_type, pdc.Datetime)
175
+ else:
176
+ assert isinstance(back_type, type_)
177
+
178
+
179
+ @pytest.mark.skipif(np is None, reason="requires pandas, numpy, and pyarrow")
180
+ @pytest.mark.parametrize(
181
+ "type_",
182
+ ALL_TYPES,
183
+ )
184
+ def test_all_types_arrow(type_):
185
+ if type_ is pdc.List:
186
+ type_obj = type_(pdc.Int64())
187
+ else:
188
+ type_obj = type_()
189
+ dst_type = type_obj.to_pandas(PandasBackend.ARROW)
190
+ back_type = Dtype.from_pandas(dst_type)
191
+ assert isinstance(back_type, type_)
@@ -1,9 +1,9 @@
1
1
  # Copyright (c) QuantCo and pydiverse contributors 2025-2025
2
2
  # SPDX-License-Identifier: BSD-3-Clause
3
- from typing import TYPE_CHECKING
4
3
 
5
4
  import pytest
6
5
 
6
+ import pydiverse.common as pdc
7
7
  from pydiverse.common import (
8
8
  Bool,
9
9
  Date,
@@ -22,13 +22,15 @@ from pydiverse.common import (
22
22
  UInt32,
23
23
  UInt64,
24
24
  )
25
+ from pydiverse.common.testing import ALL_TYPES
25
26
 
26
- pl = pytest.importorskip("polars")
27
-
28
- if TYPE_CHECKING:
27
+ try:
29
28
  import polars as pl
29
+ except ImportError:
30
+ pl = None
30
31
 
31
32
 
33
+ @pytest.mark.skipif(pl is None, reason="requires polars")
32
34
  def test_dtype_from_polars():
33
35
  def assert_conversion(type_, expected):
34
36
  assert Dtype.from_polars(type_) == expected
@@ -57,6 +59,7 @@ def test_dtype_from_polars():
57
59
  assert_conversion(pl.Datetime("ns"), Datetime())
58
60
 
59
61
 
62
+ @pytest.mark.skipif(pl is None, reason="requires polars")
60
63
  def test_dtype_to_polars():
61
64
  def assert_conversion(type_: Dtype, expected):
62
65
  assert type_.to_polars() == expected
@@ -80,3 +83,18 @@ def test_dtype_to_polars():
80
83
  assert_conversion(Date(), pl.Date)
81
84
  assert_conversion(Time(), pl.Time)
82
85
  assert_conversion(Datetime(), pl.Datetime("us"))
86
+
87
+
88
+ @pytest.mark.skipif(pl is None, reason="requires polars")
89
+ @pytest.mark.parametrize(
90
+ "type_",
91
+ ALL_TYPES,
92
+ )
93
+ def test_all_types(type_):
94
+ if type_ is pdc.List:
95
+ type_obj = type_(pdc.Int64())
96
+ else:
97
+ type_obj = type_()
98
+ dst_type = type_obj.to_polars()
99
+ back_type = Dtype.from_polars(dst_type)
100
+ assert isinstance(back_type, type_)
@@ -2,6 +2,9 @@
2
2
  # SPDX-License-Identifier: BSD-3-Clause
3
3
  import pytest
4
4
 
5
+ import pydiverse.common as pdc
6
+ from pydiverse.common.testing import ALL_TYPES
7
+
5
8
  try:
6
9
  import pyarrow as pa
7
10
  except ImportError:
@@ -87,3 +90,18 @@ def test_dtype_to_pyarrow():
87
90
  assert_conversion(Date(), pa.date32())
88
91
  assert_conversion(Time(), pa.time64("us"))
89
92
  assert_conversion(Datetime(), pa.timestamp("us"))
93
+
94
+
95
+ @pytest.mark.skipif(pa is None, reason="requires pandas, numpy, and pyarrow")
96
+ @pytest.mark.parametrize(
97
+ "type_",
98
+ ALL_TYPES,
99
+ )
100
+ def test_all_types(type_):
101
+ if type_ is pdc.List:
102
+ type_obj = type_(pdc.Int64())
103
+ else:
104
+ type_obj = type_()
105
+ dst_type = type_obj.to_arrow()
106
+ back_type = Dtype.from_arrow(dst_type)
107
+ assert isinstance(back_type, type_)
@@ -2,10 +2,12 @@
2
2
  # SPDX-License-Identifier: BSD-3-Clause
3
3
  import pytest
4
4
 
5
+ import pydiverse.common as pdc
5
6
  from pydiverse.common import (
6
7
  Bool,
7
8
  Date,
8
9
  Datetime,
10
+ Decimal,
9
11
  Dtype,
10
12
  Float32,
11
13
  Float64,
@@ -20,6 +22,7 @@ from pydiverse.common import (
20
22
  UInt32,
21
23
  UInt64,
22
24
  )
25
+ from pydiverse.common.testing import ALL_TYPES
23
26
 
24
27
  try:
25
28
  import sqlalchemy as sa
@@ -77,3 +80,29 @@ def test_dtype_to_sqlalchemy():
77
80
  assert_conversion(Date(), sa.Date)
78
81
  assert_conversion(Time(), sa.Time)
79
82
  assert_conversion(Datetime(), sa.DateTime)
83
+
84
+
85
+ @pytest.mark.skipif(sa is None, reason="requires polars")
86
+ @pytest.mark.parametrize(
87
+ "type_",
88
+ ALL_TYPES,
89
+ )
90
+ def test_all_types(type_):
91
+ if type_ is pdc.List:
92
+ type_obj = type_(pdc.Int64())
93
+ else:
94
+ type_obj = type_()
95
+ dst_type = type_obj.to_sql()
96
+ back_type = Dtype.from_sql(dst_type)
97
+ acceptance_map = {
98
+ # SQL is a bit less strict about integer precisions
99
+ Int8: Int16,
100
+ UInt8: Int16,
101
+ UInt16: Int32,
102
+ UInt32: Int64,
103
+ UInt64: Int64,
104
+ # we intentionally fetch Decimal as Float since Decimal is more a relational
105
+ # database thing
106
+ Decimal: Float64,
107
+ }
108
+ assert isinstance(back_type, acceptance_map.get(type_, type_))