Skip to content

Commit 858e3b0

Browse files
Add python bindings for some DataTypes (#49)
* Add bool_() to python api * Add complete DataType factory functions to Python API Expands the Python API with factory functions for all DataType aliases defined in dtypes.mojo, following the pattern established for bool_(). Adds wrapper functions for null, all integer types (int8-64, uint8-64), floating point types (float16, float32, float64), string, and binary. Includes comprehensive tests verifying all factory functions return correct DataType instances. Based on initial bool_() implementation pattern. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 462a5d6 commit 858e3b0

File tree

8 files changed

+160
-32
lines changed

8 files changed

+160
-32
lines changed

firebolt/module/__init__.mojo

Whitespace-only changes.

firebolt/module/dtypes_api.mojo

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
"""Python interface for dtypes."""
2+
3+
from python.bindings import PythonModuleBuilder, PythonObject
4+
from firebolt import dtypes
5+
6+
7+
fn null() raises -> PythonObject:
8+
"""Create a null DataType."""
9+
var result = materialize[dtypes.null]()
10+
return PythonObject(alloc=result^)
11+
12+
13+
fn bool_() raises -> PythonObject:
14+
"""Create a boolean DataType."""
15+
var result = materialize[dtypes.bool_]()
16+
return PythonObject(alloc=result^)
17+
18+
19+
fn int8() raises -> PythonObject:
20+
"""Create an int8 DataType."""
21+
var result = materialize[dtypes.int8]()
22+
return PythonObject(alloc=result^)
23+
24+
25+
fn int16() raises -> PythonObject:
26+
"""Create an int16 DataType."""
27+
var result = materialize[dtypes.int16]()
28+
return PythonObject(alloc=result^)
29+
30+
31+
fn int32() raises -> PythonObject:
32+
"""Create an int32 DataType."""
33+
var result = materialize[dtypes.int32]()
34+
return PythonObject(alloc=result^)
35+
36+
37+
fn int64() raises -> PythonObject:
38+
"""Create an int64 DataType."""
39+
var result = materialize[dtypes.int64]()
40+
return PythonObject(alloc=result^)
41+
42+
43+
fn uint8() raises -> PythonObject:
44+
"""Create a uint8 DataType."""
45+
var result = materialize[dtypes.uint8]()
46+
return PythonObject(alloc=result^)
47+
48+
49+
fn uint16() raises -> PythonObject:
50+
"""Create a uint16 DataType."""
51+
var result = materialize[dtypes.uint16]()
52+
return PythonObject(alloc=result^)
53+
54+
55+
fn uint32() raises -> PythonObject:
56+
"""Create a uint32 DataType."""
57+
var result = materialize[dtypes.uint32]()
58+
return PythonObject(alloc=result^)
59+
60+
61+
fn uint64() raises -> PythonObject:
62+
"""Create a uint64 DataType."""
63+
var result = materialize[dtypes.uint64]()
64+
return PythonObject(alloc=result^)
65+
66+
67+
fn float16() raises -> PythonObject:
68+
"""Create a float16 DataType."""
69+
var result = materialize[dtypes.float16]()
70+
return PythonObject(alloc=result^)
71+
72+
73+
fn float32() raises -> PythonObject:
74+
"""Create a float32 DataType."""
75+
var result = materialize[dtypes.float32]()
76+
return PythonObject(alloc=result^)
77+
78+
79+
fn float64() raises -> PythonObject:
80+
"""Create a float64 DataType."""
81+
var result = materialize[dtypes.float64]()
82+
return PythonObject(alloc=result^)
83+
84+
85+
fn string() raises -> PythonObject:
86+
"""Create a string DataType."""
87+
var result = materialize[dtypes.string]()
88+
return PythonObject(alloc=result^)
89+
90+
91+
fn binary() raises -> PythonObject:
92+
"""Create a binary DataType."""
93+
var result = materialize[dtypes.binary]()
94+
return PythonObject(alloc=result^)
95+
96+
97+
def add_to_module(mut builder: PythonModuleBuilder) -> None:
98+
"""Add DataType related data to the Python API."""
99+
100+
_ = builder.add_type[dtypes.DataType]("DataType")
101+
builder.def_function[null]("null", docstring="Create a null DataType.")
102+
builder.def_function[bool_]("bool_", docstring="Create a boolean DataType.")
103+
builder.def_function[int8]("int8", docstring="Create an int8 DataType.")
104+
builder.def_function[int16]("int16", docstring="Create an int16 DataType.")
105+
builder.def_function[int32]("int32", docstring="Create an int32 DataType.")
106+
builder.def_function[int64]("int64", docstring="Create an int64 DataType.")
107+
builder.def_function[uint8]("uint8", docstring="Create a uint8 DataType.")
108+
builder.def_function[uint16](
109+
"uint16", docstring="Create a uint16 DataType."
110+
)
111+
builder.def_function[uint32](
112+
"uint32", docstring="Create a uint32 DataType."
113+
)
114+
builder.def_function[uint64](
115+
"uint64", docstring="Create a uint64 DataType."
116+
)
117+
builder.def_function[float16](
118+
"float16", docstring="Create a float16 DataType."
119+
)
120+
builder.def_function[float32](
121+
"float32", docstring="Create a float32 DataType."
122+
)
123+
builder.def_function[float64](
124+
"float64", docstring="Create a float64 DataType."
125+
)
126+
builder.def_function[string](
127+
"string", docstring="Create a string DataType."
128+
)
129+
builder.def_function[binary](
130+
"binary", docstring="Create a binary DataType."
131+
)

pixi.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ platforms = ["osx-arm64", "linux-64"]
66
version = "0.1.0"
77

88
[tasks]
9+
build_pybolt = {cmd="mojo build -I . pybolt/pybolt.mojo --emit shared-lib -o pybolt/pybolt.so"}
910
test_mojo = {cmd = "mojo test firebolt -I ." }
10-
test_python = {cmd = "pytest -s -v pybolt/tests" }
11+
test_python = {cmd = "pytest -s -v pybolt/tests", depends-on=["build_pybolt"]}
1112
test = {depends-on = ["test_mojo", "test_python"]}
1213
fmt_mojo = {cmd = "mojo format firebolt"}
1314
fmt_python = {cmd = "ruff format pybolt" }

pybolt/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.so

pybolt/pybolt.mojo

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,17 @@
11
from python import PythonObject, Python
22
from python.bindings import PythonModuleBuilder
33
import math
4+
from firebolt.module.dtypes_api import add_to_module as add_dtypes
45
from os import abort
56

67

78
@export
89
fn PyInit_pybolt() -> PythonObject:
910
try:
1011
var m = PythonModuleBuilder("pybolt")
11-
m.def_function[to_pydict](
12-
"to_pydict",
13-
docstring="Transform a firebolt structure to python dictionary.",
14-
)
12+
add_dtypes(m)
1513
return m.finalize()
1614
except e:
1715
return abort[PythonObject](
1816
String("error creating Python Mojo module:", e)
1917
)
20-
21-
22-
fn to_pydict(py_obj: PythonObject) raises -> PythonObject:
23-
"""Transform a firebolt structure to a python dictionary.
24-
25-
This is a dummy function used to test the infrastructure.
26-
"""
27-
28-
ref cpy = Python().cpython()
29-
var dict_obj = cpy.PyDict_New()
30-
return PythonObject(from_owned=dict_obj)

pybolt/pytest.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[pytest]
2+
pythonpath=.

pybolt/tests/test_dtypes_api.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
"""Test the DataType Python api."""
2+
3+
import pybolt
4+
5+
6+
def test_factory_functions() -> None:
7+
"""Test that all DataType factory functions work and return correct types."""
8+
assert isinstance(pybolt.null(), pybolt.DataType)
9+
assert isinstance(pybolt.bool_(), pybolt.DataType)
10+
assert isinstance(pybolt.int8(), pybolt.DataType)
11+
assert isinstance(pybolt.int16(), pybolt.DataType)
12+
assert isinstance(pybolt.int32(), pybolt.DataType)
13+
assert isinstance(pybolt.int64(), pybolt.DataType)
14+
assert isinstance(pybolt.uint8(), pybolt.DataType)
15+
assert isinstance(pybolt.uint16(), pybolt.DataType)
16+
assert isinstance(pybolt.uint32(), pybolt.DataType)
17+
assert isinstance(pybolt.uint64(), pybolt.DataType)
18+
assert isinstance(pybolt.float16(), pybolt.DataType)
19+
assert isinstance(pybolt.float32(), pybolt.DataType)
20+
assert isinstance(pybolt.float64(), pybolt.DataType)
21+
assert isinstance(pybolt.string(), pybolt.DataType)
22+
assert isinstance(pybolt.binary(), pybolt.DataType)

pybolt/tests/test_pybolt.py

Lines changed: 0 additions & 16 deletions
This file was deleted.

0 commit comments

Comments
 (0)