From 37784f87579964e7da3a1261e79a520be7e60634 Mon Sep 17 00:00:00 2001 From: MoSafi2 Date: Thu, 18 Jun 2026 22:07:22 +0200 Subject: [PATCH 1/4] Mojo 1.0.0b2 syntax update --- CHANGELOG.md | 9 +++ examples/cairo/cairo_smoke.mojo | 64 +++++++++---------- .../global_consts_bindings_test.mojo | 33 ++++++++++ examples/libpng/libpng_smoke.mojo | 60 ++++++++--------- examples/sqlite/sqlite_smoke.mojo | 58 ++++++++--------- examples/zlib/zlib_dl_smoke.mojo | 4 +- mojo_bindgen/codegen/mojo_ir_printer.py | 36 ++++++----- mojo_bindgen/layout_tests/generator.py | 2 +- pixi.lock | 62 +++++++++--------- pixi.toml | 2 +- .../expect.emit.external.mojo | 10 +-- .../expect.emit.owned_dl_handle.mojo | 10 +-- .../expect.emit.external.mojo | 4 +- .../expect.emit.owned_dl_handle.mojo | 4 +- .../expect.emit.external.mojo | 4 +- .../expect.emit.owned_dl_handle.mojo | 4 +- .../expect.external.mojo | 22 +++---- .../globals_and_consts/expect.external.mojo | 18 +++--- .../opaque_forward_ptrs/expect.external.mojo | 8 +-- tests/unit/test_ir_codegen_edges.py | 20 +++--- tests/unit/test_layout_tests.py | 2 +- tests/unit/test_mojo_ir_printer.py | 14 ++-- tests/unit/test_type_lowering.py | 10 +-- 23 files changed, 254 insertions(+), 206 deletions(-) create mode 100644 examples/global_consts/global_consts_bindings_test.mojo diff --git a/CHANGELOG.md b/CHANGELOG.md index 57cf1bf..29ca769 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ All notable changes to this project are documented in this file. +## [0.3.1] 2026-06-18 + +### Changed + +- Update generated Mojo bindings, layout-test sidecars, and example smoke tests + for Mojo 1.0.0b2 syntax changes, including `def`, explicit `abi("C")`, + `reflect[T]`, and the new `UntrackedOrigin` / `UnsafeAnyOrigin` spelling + family. + ## [0.3] 2026-06-01 ### Added diff --git a/examples/cairo/cairo_smoke.mojo b/examples/cairo/cairo_smoke.mojo index 4798b5e..c09de1c 100644 --- a/examples/cairo/cairo_smoke.mojo +++ b/examples/cairo/cairo_smoke.mojo @@ -30,7 +30,7 @@ def _approx_eq(a: Float64, b: Float64, eps: Float64 = 1e-9) -> Bool: def _draw_panel_border( - cr: Optional[UnsafePointer[cairo_t, MutExternalOrigin]], + cr: Optional[UnsafePointer[cairo_t, MutUntrackedOrigin]], x: Float64, y: Float64, w: Float64, @@ -49,7 +49,7 @@ def run_metadata_and_lifecycle_checks() raises: _assert( "version_string_nonnull", cairo_version_string() - != Optional[UnsafePointer[Int8, ImmutExternalOrigin]](), + != Optional[UnsafePointer[Int8, ImmutUntrackedOrigin]](), ) var surf = cairo_image_surface_create( @@ -74,7 +74,7 @@ def run_metadata_and_lifecycle_checks() raises: _assert( "status_to_string_nonnull", cairo_status_to_string(materialize[OK]()) - != Optional[UnsafePointer[Int8, ImmutExternalOrigin]](), + != Optional[UnsafePointer[Int8, ImmutUntrackedOrigin]](), ) cairo_save(cr) @@ -118,12 +118,12 @@ def run_metadata_and_lifecycle_checks() raises: _assert( "get_target_nonnull", cairo_get_target(cr) - != Optional[UnsafePointer[cairo_surface_t, MutExternalOrigin]](), + != Optional[UnsafePointer[cairo_surface_t, MutUntrackedOrigin]](), ) _assert( "get_group_target_nonnull", cairo_get_group_target(cr) - != Optional[UnsafePointer[cairo_surface_t, MutExternalOrigin]](), + != Optional[UnsafePointer[cairo_surface_t, MutUntrackedOrigin]](), ) cairo_destroy(cr) @@ -132,7 +132,7 @@ def run_metadata_and_lifecycle_checks() raises: def draw_composite_scene( - cr: Optional[UnsafePointer[cairo_t, MutExternalOrigin]] + cr: Optional[UnsafePointer[cairo_t, MutUntrackedOrigin]] ) raises: cairo_set_source_rgb(cr, 1.0, 1.0, 1.0) cairo_paint(cr) @@ -256,12 +256,12 @@ def draw_composite_scene( cairo_pattern_get_matrix(rgba_pat, matrix) cairo_pattern_set_matrix( rgba_pat, - rebind[Optional[UnsafePointer[cairo_matrix_t, ImmutExternalOrigin]]]( + rebind[Optional[UnsafePointer[cairo_matrix_t, ImmutUntrackedOrigin]]]( matrix ), ) var surf_ptr = alloc[ - Optional[UnsafePointer[cairo_surface_t, MutExternalOrigin]] + Optional[UnsafePointer[cairo_surface_t, MutUntrackedOrigin]] ](1) _ok("pattern_get_surface", cairo_pattern_get_surface(surface_pat, surf_ptr)) var x0 = alloc[Float64](1) @@ -353,7 +353,7 @@ def draw_composite_scene( _assert( "panel4_get_source_nonnull", cairo_get_source(cr) - != Optional[UnsafePointer[cairo_pattern_t, MutExternalOrigin]](), + != Optional[UnsafePointer[cairo_pattern_t, MutUntrackedOrigin]](), ) cairo_pattern_destroy(source_probe) cairo_restore(cr) @@ -386,7 +386,7 @@ def draw_composite_scene( var family = CStringSlice("sans\0") cairo_select_font_face( cr, - rebind[UnsafePointer[Int8, ImmutExternalOrigin]](family.unsafe_ptr()), + rebind[UnsafePointer[Int8, ImmutUntrackedOrigin]](family.unsafe_ptr()), materialize[CAIRO_FONT_SLANT_NORMAL](), materialize[CAIRO_FONT_WEIGHT_BOLD](), ) @@ -404,7 +404,7 @@ def draw_composite_scene( cairo_font_face_destroy(ff2) var tf = cairo_toy_font_face_create( - rebind[UnsafePointer[Int8, ImmutExternalOrigin]](family.unsafe_ptr()), + rebind[UnsafePointer[Int8, ImmutUntrackedOrigin]](family.unsafe_ptr()), materialize[CAIRO_FONT_SLANT_ITALIC](), materialize[CAIRO_FONT_WEIGHT_NORMAL](), ) @@ -420,7 +420,7 @@ def draw_composite_scene( _assert( "panel6_toy_family_nonnull", cairo_toy_font_face_get_family(tf) - != Optional[UnsafePointer[Int8, ImmutExternalOrigin]](), + != Optional[UnsafePointer[Int8, ImmutUntrackedOrigin]](), ) cairo_font_face_destroy(tf) @@ -428,19 +428,19 @@ def draw_composite_scene( cairo_set_source_rgb(cr, 0.0, 0.0, 0.0) cairo_move_to(cr, 12.0, 60.0) cairo_show_text( - cr, rebind[UnsafePointer[Int8, ImmutExternalOrigin]](hello.unsafe_ptr()) + cr, rebind[UnsafePointer[Int8, ImmutUntrackedOrigin]](hello.unsafe_ptr()) ) _ok("panel6_show_text", cairo_status(cr)) cairo_move_to(cr, 12.0, 120.0) cairo_text_path( - cr, rebind[UnsafePointer[Int8, ImmutExternalOrigin]](hello.unsafe_ptr()) + cr, rebind[UnsafePointer[Int8, ImmutUntrackedOrigin]](hello.unsafe_ptr()) ) _ok("panel6_text_path", cairo_status(cr)) cairo_new_path(cr) var glyphs = cairo_glyph_allocate(4) _assert( "panel6_glyph_alloc_nonnull", - glyphs != Optional[UnsafePointer[cairo_glyph_t, MutExternalOrigin]](), + glyphs != Optional[UnsafePointer[cairo_glyph_t, MutUntrackedOrigin]](), ) cairo_glyph_free(glyphs) cairo_restore(cr) @@ -450,7 +450,7 @@ def draw_composite_scene( cairo_translate(cr, 20.0, 420.0) var rec = cairo_recording_surface_create( materialize[CAIRO_CONTENT_COLOR_ALPHA](), - Optional[UnsafePointer[cairo_rectangle_t, ImmutExternalOrigin]](), + Optional[UnsafePointer[cairo_rectangle_t, ImmutUntrackedOrigin]](), ) _ok("panel7_recording_surface_create", cairo_surface_status(rec)) var rec_cr = cairo_create(rec) @@ -472,20 +472,20 @@ def run_non_visual_object_checks() raises: var opts = cairo_font_options_create() _ok("font_options_create", cairo_font_options_status(opts)) var opts2 = cairo_font_options_copy( - rebind[UnsafePointer[cairo_font_options_t, ImmutExternalOrigin]](opts) + rebind[UnsafePointer[cairo_font_options_t, ImmutUntrackedOrigin]](opts) ) _ok("font_options_copy", cairo_font_options_status(opts2)) cairo_font_options_merge( opts, - rebind[UnsafePointer[cairo_font_options_t, ImmutExternalOrigin]](opts2), + rebind[UnsafePointer[cairo_font_options_t, ImmutUntrackedOrigin]](opts2), ) _assert( "font_options_equal", cairo_font_options_equal( - rebind[UnsafePointer[cairo_font_options_t, ImmutExternalOrigin]]( + rebind[UnsafePointer[cairo_font_options_t, ImmutUntrackedOrigin]]( opts ), - rebind[UnsafePointer[cairo_font_options_t, ImmutExternalOrigin]]( + rebind[UnsafePointer[cairo_font_options_t, ImmutUntrackedOrigin]]( opts2 ), ) @@ -494,7 +494,7 @@ def run_non_visual_object_checks() raises: _assert( "font_options_hash_stable", cairo_font_options_hash( - rebind[UnsafePointer[cairo_font_options_t, ImmutExternalOrigin]]( + rebind[UnsafePointer[cairo_font_options_t, ImmutUntrackedOrigin]]( opts ) ) @@ -506,7 +506,7 @@ def run_non_visual_object_checks() raises: cairo_font_options_get_antialias( rebind[ Optional[ - UnsafePointer[cairo_font_options_t, ImmutExternalOrigin] + UnsafePointer[cairo_font_options_t, ImmutUntrackedOrigin] ] ](opts) ) @@ -520,7 +520,7 @@ def run_non_visual_object_checks() raises: cairo_font_options_get_subpixel_order( rebind[ Optional[ - UnsafePointer[cairo_font_options_t, ImmutExternalOrigin] + UnsafePointer[cairo_font_options_t, ImmutUntrackedOrigin] ] ](opts) ) @@ -534,7 +534,7 @@ def run_non_visual_object_checks() raises: cairo_font_options_get_hint_style( rebind[ Optional[ - UnsafePointer[cairo_font_options_t, ImmutExternalOrigin] + UnsafePointer[cairo_font_options_t, ImmutUntrackedOrigin] ] ](opts) ) @@ -548,7 +548,7 @@ def run_non_visual_object_checks() raises: cairo_font_options_get_hint_metrics( rebind[ Optional[ - UnsafePointer[cairo_font_options_t, ImmutExternalOrigin] + UnsafePointer[cairo_font_options_t, ImmutUntrackedOrigin] ] ](opts) ) @@ -561,12 +561,12 @@ def run_non_visual_object_checks() raises: rect_storage[0] = cairo_rectangle_int_t(10, 10, 60, 60) var reg = cairo_region_create_rectangle( rebind[ - Optional[UnsafePointer[cairo_rectangle_int_t, ImmutExternalOrigin]] + Optional[UnsafePointer[cairo_rectangle_int_t, ImmutUntrackedOrigin]] ](rect_storage) ) rect_storage.free() var reg_const = rebind[ - Optional[UnsafePointer[cairo_region_t, ImmutExternalOrigin]] + Optional[UnsafePointer[cairo_region_t, ImmutUntrackedOrigin]] ](reg) _ok("region_create_rectangle", cairo_region_status(reg_const)) _assert( @@ -591,7 +591,7 @@ def run_non_visual_object_checks() raises: extents.free() var reg2 = cairo_region_copy(reg_const) var reg2_const = rebind[ - Optional[UnsafePointer[cairo_region_t, ImmutExternalOrigin]] + Optional[UnsafePointer[cairo_region_t, ImmutUntrackedOrigin]] ](reg2) _assert( "region_equal_after_copy", @@ -608,7 +608,7 @@ def run_non_visual_object_checks() raises: var empty = cairo_region_create() var empty_const = rebind[ - Optional[UnsafePointer[cairo_region_t, ImmutExternalOrigin]] + Optional[UnsafePointer[cairo_region_t, ImmutUntrackedOrigin]] ](empty) _ok("region_create_empty", cairo_region_status(empty_const)) _assert( @@ -621,20 +621,20 @@ def run_non_visual_object_checks() raises: def run_png_roundtrip_from_composite( - surface: Optional[UnsafePointer[cairo_surface_t, MutExternalOrigin]] + surface: Optional[UnsafePointer[cairo_surface_t, MutUntrackedOrigin]] ) raises: var out_path = CStringSlice("/tmp/mojo_bindgen_cairo_smoke_composite.png\0") _ok( "surface_write_to_png", cairo_surface_write_to_png( surface, - rebind[UnsafePointer[Int8, ImmutExternalOrigin]]( + rebind[UnsafePointer[Int8, ImmutUntrackedOrigin]]( out_path.unsafe_ptr() ), ), ) var loaded = cairo_image_surface_create_from_png( - rebind[UnsafePointer[Int8, ImmutExternalOrigin]](out_path.unsafe_ptr()) + rebind[UnsafePointer[Int8, ImmutUntrackedOrigin]](out_path.unsafe_ptr()) ) _ok("png_load", cairo_surface_status(loaded)) _assert("png_width", cairo_image_surface_get_width(loaded) == SCENE_W) diff --git a/examples/global_consts/global_consts_bindings_test.mojo b/examples/global_consts/global_consts_bindings_test.mojo new file mode 100644 index 0000000..da6906b --- /dev/null +++ b/examples/global_consts/global_consts_bindings_test.mojo @@ -0,0 +1,33 @@ +# Generated by mojo_bindgen - do not edit by hand. +# layout tests for: global_consts_bindings + +from std.sys.info import align_of, size_of +from std.reflection import reflect +from global_consts_bindings import point, region + + +def _check_eq(label: String, got: Int, expected: Int) raises: + if got != expected: + raise Error(label + ": got " + String(got) + ", expected " + String(expected)) + + +def test_layout_point() raises: + comptime r = reflect[point] + _check_eq("point.size", Int(size_of[point]()), 8) + _check_eq("point.align", Int(align_of[point]()), 4) + _check_eq("point.x.offset", Int(r.field_offset[name="x"]()), 0) + _check_eq("point.y.offset", Int(r.field_offset[name="y"]()), 4) + + +def test_layout_region() raises: + comptime r = reflect[region] + _check_eq("region.size", Int(size_of[region]()), 24) + _check_eq("region.align", Int(align_of[region]()), 8) + _check_eq("region.origin.offset", Int(r.field_offset[name="origin"]()), 0) + _check_eq("region.extent.offset", Int(r.field_offset[name="extent"]()), 8) + _check_eq("region.label.offset", Int(r.field_offset[name="label"]()), 16) + + +def main() raises: + test_layout_point() + test_layout_region() diff --git a/examples/libpng/libpng_smoke.mojo b/examples/libpng/libpng_smoke.mojo index 396aafe..3ea49bf 100644 --- a/examples/libpng/libpng_smoke.mojo +++ b/examples/libpng/libpng_smoke.mojo @@ -16,12 +16,12 @@ def _assert(label: String, cond: Bool) raises: print(label + "|ok") -def _cstr(s: StaticString) -> UnsafePointer[Int8, ImmutExternalOrigin]: - return rebind[UnsafePointer[Int8, ImmutExternalOrigin]](s.unsafe_ptr()) +def _cstr(s: StaticString) -> UnsafePointer[Int8, ImmutUntrackedOrigin]: + return rebind[UnsafePointer[Int8, ImmutUntrackedOrigin]](s.unsafe_ptr()) -def _cstr_mut(s: StaticString) -> UnsafePointer[Int8, MutExternalOrigin]: - return rebind[UnsafePointer[Int8, MutExternalOrigin]](s.unsafe_ptr()) +def _cstr_mut(s: StaticString) -> UnsafePointer[Int8, MutUntrackedOrigin]: + return rebind[UnsafePointer[Int8, MutUntrackedOrigin]](s.unsafe_ptr()) def _ignore_png_message(png_ptr: png.png_structp, msg: png.png_const_charp) abi("C"): @@ -63,7 +63,7 @@ def run_write_roundtrip_checks() raises: var image_write = alloc[png.png_image](1) image_write[0] = png.png_image( - opaque=Optional[UnsafePointer[png.png_control, MutExternalOrigin]](), + opaque=Optional[UnsafePointer[png.png_control, MutUntrackedOrigin]](), version=c_uint(png.PNG_IMAGE_VERSION), width=c_uint(IMAGE_W), height=c_uint(IMAGE_H), @@ -78,15 +78,15 @@ def run_write_roundtrip_checks() raises: image_write, png_path, 0, - rebind[ImmutOpaquePointer[ImmutExternalOrigin]](pixels), + rebind[ImmutOpaquePointer[ImmutUntrackedOrigin]](pixels), IMAGE_W * CHANNELS, - Optional[ImmutOpaquePointer[ImmutExternalOrigin]](), + Optional[ImmutOpaquePointer[ImmutUntrackedOrigin]](), ) _assert("libpng.write_to_file", write_ok != 0) var image_read = alloc[png.png_image](1) image_read[0] = png.png_image( - opaque=Optional[UnsafePointer[png.png_control, MutExternalOrigin]](), + opaque=Optional[UnsafePointer[png.png_control, MutUntrackedOrigin]](), version=c_uint(png.PNG_IMAGE_VERSION), width=0, height=0, @@ -106,9 +106,9 @@ def run_write_roundtrip_checks() raises: var finish_ok = png.png_image_finish_read( image_read, png.png_const_colorp(), - rebind[MutOpaquePointer[MutExternalOrigin]](out_pixels), + rebind[MutOpaquePointer[MutUntrackedOrigin]](out_pixels), IMAGE_W * CHANNELS, - Optional[MutOpaquePointer[MutExternalOrigin]](), + Optional[MutOpaquePointer[MutUntrackedOrigin]](), ) _assert("libpng.finish_read", finish_ok != 0) _assert("libpng.pixel_roundtrip_0", out_pixels[0] == pixels[0]) @@ -144,7 +144,7 @@ def run_memory_roundtrip_checks() raises: # Build a writer-side png_image matching run_write_roundtrip_checks(). var image_write = alloc[png.png_image](1) image_write[0] = png.png_image( - opaque=Optional[UnsafePointer[png.png_control, MutExternalOrigin]](), + opaque=Optional[UnsafePointer[png.png_control, MutUntrackedOrigin]](), version=c_uint(png.PNG_IMAGE_VERSION), width=c_uint(IMAGE_W), height=c_uint(IMAGE_H), @@ -160,12 +160,12 @@ def run_memory_roundtrip_checks() raises: var memory_bytes_out = alloc[png.png_alloc_size_t](1) var write_size_ok = png.png_image_write_to_memory( image_write, - Optional[MutOpaquePointer[MutExternalOrigin]](), + Optional[MutOpaquePointer[MutUntrackedOrigin]](), memory_bytes_out, 0, - rebind[ImmutOpaquePointer[ImmutExternalOrigin]](pixels), + rebind[ImmutOpaquePointer[ImmutUntrackedOrigin]](pixels), IMAGE_W * CHANNELS, - Optional[ImmutOpaquePointer[ImmutExternalOrigin]](), + Optional[ImmutOpaquePointer[ImmutUntrackedOrigin]](), ) _assert("libpng.write_to_memory_size", write_size_ok != 0) _assert("libpng.write_to_memory_size_nonzero", memory_bytes_out[0] > 0) @@ -173,18 +173,18 @@ def run_memory_roundtrip_checks() raises: var png_bytes = alloc[UInt8](Int(memory_bytes_out[0])) var write_ok = png.png_image_write_to_memory( image_write, - rebind[MutOpaquePointer[MutExternalOrigin]](png_bytes), + rebind[MutOpaquePointer[MutUntrackedOrigin]](png_bytes), memory_bytes_out, 0, - rebind[ImmutOpaquePointer[ImmutExternalOrigin]](pixels), + rebind[ImmutOpaquePointer[ImmutUntrackedOrigin]](pixels), IMAGE_W * CHANNELS, - Optional[ImmutOpaquePointer[ImmutExternalOrigin]](), + Optional[ImmutOpaquePointer[ImmutUntrackedOrigin]](), ) _assert("libpng.write_to_memory", write_ok != 0) var image_read = alloc[png.png_image](1) image_read[0] = png.png_image( - opaque=Optional[UnsafePointer[png.png_control, MutExternalOrigin]](), + opaque=Optional[UnsafePointer[png.png_control, MutUntrackedOrigin]](), version=UInt32(png.PNG_IMAGE_VERSION), width=0, height=0, @@ -197,7 +197,7 @@ def run_memory_roundtrip_checks() raises: var begin_ok = png.png_image_begin_read_from_memory( image_read, - rebind[ImmutOpaquePointer[ImmutExternalOrigin]](png_bytes), + rebind[ImmutOpaquePointer[ImmutUntrackedOrigin]](png_bytes), UInt(memory_bytes_out[0]), ) _assert("libpng.begin_read_from_memory", begin_ok != 0) @@ -207,9 +207,9 @@ def run_memory_roundtrip_checks() raises: var finish_ok = png.png_image_finish_read( image_read, png.png_const_colorp(), - rebind[MutOpaquePointer[MutExternalOrigin]](out_pixels), + rebind[MutOpaquePointer[MutUntrackedOrigin]](out_pixels), IMAGE_W * CHANNELS, - Optional[MutOpaquePointer[MutExternalOrigin]](), + Optional[MutOpaquePointer[MutUntrackedOrigin]](), ) _assert("libpng.finish_read_memory", finish_ok != 0) _assert("libpng.pixel_roundtrip_mem_0", out_pixels[0] == pixels[0]) @@ -227,7 +227,7 @@ def run_alpha_removal_compositing_checks() raises: # background color. var image_read = alloc[png.png_image](1) image_read[0] = png.png_image( - opaque=Optional[UnsafePointer[png.png_control, MutExternalOrigin]](), + opaque=Optional[UnsafePointer[png.png_control, MutUntrackedOrigin]](), version=UInt32(png.PNG_IMAGE_VERSION), width=0, height=0, @@ -247,16 +247,16 @@ def run_alpha_removal_compositing_checks() raises: var background = alloc[png.png_color_struct](1) background[0] = png.png_color_struct(red=7, green=11, blue=13) var background_ptr = rebind[ - UnsafePointer[png.png_color_struct, ImmutExternalOrigin] + UnsafePointer[png.png_color_struct, ImmutUntrackedOrigin] ](background) var out_rgb = alloc[UInt8](IMAGE_W * IMAGE_H * 3) var finish_ok = png.png_image_finish_read( image_read, background_ptr, - rebind[MutOpaquePointer[MutExternalOrigin]](out_rgb), + rebind[MutOpaquePointer[MutUntrackedOrigin]](out_rgb), IMAGE_W * 3, - Optional[MutOpaquePointer[MutExternalOrigin]](), + Optional[MutOpaquePointer[MutUntrackedOrigin]](), ) _assert("libpng.alpha_finish_read", finish_ok != 0) @@ -277,7 +277,7 @@ def run_alpha_removal_compositing_checks() raises: def run_transform_and_options_checks() raises: var png_ptr = png.png_create_write_struct( _cstr("1.6.43"), - Optional[MutOpaquePointer[MutExternalOrigin]](), + Optional[MutOpaquePointer[MutUntrackedOrigin]](), _ignore_png_message, _ignore_png_message, ) @@ -328,8 +328,8 @@ def run_transform_and_options_checks() raises: text=_cstr_mut("mojo-bindgen-smoke"), text_length=18, itxt_length=0, - lang=Optional[UnsafePointer[Int8, MutExternalOrigin]](), - lang_key=Optional[UnsafePointer[Int8, MutExternalOrigin]](), + lang=Optional[UnsafePointer[Int8, MutUntrackedOrigin]](), + lang_key=Optional[UnsafePointer[Int8, MutUntrackedOrigin]](), ) png.png_set_text( png_const_ptr, @@ -409,14 +409,14 @@ def run_lightweight_struct_api_checks() raises: sig[6] = 26 sig[7] = 10 var sig_ok = png.png_sig_cmp( - rebind[UnsafePointer[UInt8, ImmutExternalOrigin]](sig), + rebind[UnsafePointer[UInt8, ImmutUntrackedOrigin]](sig), 0, 8, ) _assert("libpng.sig_cmp_valid", sig_ok == 0) sig[1] = 81 var sig_bad = png.png_sig_cmp( - rebind[UnsafePointer[UInt8, ImmutExternalOrigin]](sig), + rebind[UnsafePointer[UInt8, ImmutUntrackedOrigin]](sig), 0, 8, ) diff --git a/examples/sqlite/sqlite_smoke.mojo b/examples/sqlite/sqlite_smoke.mojo index a0abdae..f245fe0 100644 --- a/examples/sqlite/sqlite_smoke.mojo +++ b/examples/sqlite/sqlite_smoke.mojo @@ -14,38 +14,38 @@ def _assert(label: String, cond: Bool) raises: print(label + "|ok") -def _cstr(s: StaticString) -> UnsafePointer[Int8, ImmutExternalOrigin]: - return rebind[UnsafePointer[Int8, ImmutExternalOrigin]](s.unsafe_ptr()) +def _cstr(s: StaticString) -> UnsafePointer[Int8, ImmutUntrackedOrigin]: + return rebind[UnsafePointer[Int8, ImmutUntrackedOrigin]](s.unsafe_ptr()) def _ignore_exec_row( - data: Optional[MutOpaquePointer[MutExternalOrigin]], + data: Optional[MutOpaquePointer[MutUntrackedOrigin]], columns: c_int, values: Optional[ - UnsafePointer[Optional[UnsafePointer[Int8, MutExternalOrigin]], MutExternalOrigin] + UnsafePointer[Optional[UnsafePointer[Int8, MutUntrackedOrigin]], MutUntrackedOrigin] ], names: Optional[ - UnsafePointer[Optional[UnsafePointer[Int8, MutExternalOrigin]], MutExternalOrigin] + UnsafePointer[Optional[UnsafePointer[Int8, MutUntrackedOrigin]], MutUntrackedOrigin] ], ) abi("C") -> c_int: return 0 def _ignore_bound_value( - value: Optional[UnsafePointer[NoneType, MutExternalOrigin]], + value: Optional[UnsafePointer[NoneType, MutUntrackedOrigin]], ) abi("C"): pass -def _errmsg(db: UnsafePointer[sql.sqlite3, MutExternalOrigin]) -> String: +def _errmsg(db: UnsafePointer[sql.sqlite3, MutUntrackedOrigin]) -> String: var p = sql.sqlite3_errmsg(db) - if p == Optional[UnsafePointer[Int8, ImmutExternalOrigin]](): + if p == Optional[UnsafePointer[Int8, ImmutUntrackedOrigin]](): return "" return String(p.value()) def _check_db_rc( - label: String, db: UnsafePointer[sql.sqlite3, MutExternalOrigin], rc: Int32 + label: String, db: UnsafePointer[sql.sqlite3, MutUntrackedOrigin], rc: Int32 ) raises: if rc != Int32(sql.SQLITE_OK): raise Error(label + " rc=" + String(rc) + " err=" + _errmsg(db)) @@ -57,24 +57,24 @@ def _check_db_rc( # --------------------------- -def _open_memory() raises -> UnsafePointer[sql.sqlite3, MutExternalOrigin]: - var ppDb = alloc[Optional[UnsafePointer[sql.sqlite3, MutExternalOrigin]]](1) +def _open_memory() raises -> UnsafePointer[sql.sqlite3, MutUntrackedOrigin]: + var ppDb = alloc[Optional[UnsafePointer[sql.sqlite3, MutUntrackedOrigin]]](1) var rc = sql.sqlite3_open_v2( _cstr(":memory:\0"), ppDb, Int32(sql.SQLITE_OPEN_READWRITE | sql.SQLITE_OPEN_CREATE), - Optional[UnsafePointer[Int8, ImmutExternalOrigin]](), + Optional[UnsafePointer[Int8, ImmutUntrackedOrigin]](), ) _assert("open.rc", rc == Int32(sql.SQLITE_OK)) _assert( "open.nonnull", - ppDb[0] != Optional[UnsafePointer[sql.sqlite3, MutExternalOrigin]](), + ppDb[0] != Optional[UnsafePointer[sql.sqlite3, MutUntrackedOrigin]](), ) return ppDb[0].value() def _exec( - db: UnsafePointer[sql.sqlite3, MutExternalOrigin], + db: UnsafePointer[sql.sqlite3, MutUntrackedOrigin], s: StaticString, label: String, ) raises: @@ -82,31 +82,31 @@ def _exec( db, _cstr(s), _ignore_exec_row, - Optional[MutOpaquePointer[MutExternalOrigin]](), - alloc[Optional[UnsafePointer[Int8, MutExternalOrigin]]](1), + Optional[MutOpaquePointer[MutUntrackedOrigin]](), + alloc[Optional[UnsafePointer[Int8, MutUntrackedOrigin]]](1), ) _check_db_rc(label, db, rc) def _prepare( - db: UnsafePointer[sql.sqlite3, MutExternalOrigin], + db: UnsafePointer[sql.sqlite3, MutUntrackedOrigin], s: StaticString, label: String, -) raises -> UnsafePointer[sql.sqlite3_stmt, MutExternalOrigin]: - var pp = alloc[Optional[UnsafePointer[sql.sqlite3_stmt, MutExternalOrigin]]](1) +) raises -> UnsafePointer[sql.sqlite3_stmt, MutUntrackedOrigin]: + var pp = alloc[Optional[UnsafePointer[sql.sqlite3_stmt, MutUntrackedOrigin]]](1) var rc = sql.sqlite3_prepare_v2( db, _cstr(s), -1, pp, - alloc[Optional[UnsafePointer[Int8, ImmutExternalOrigin]]](1), + alloc[Optional[UnsafePointer[Int8, ImmutUntrackedOrigin]]](1), ) _check_db_rc(label, db, rc) return pp[0].value() def _finalize( - stmt: UnsafePointer[sql.sqlite3_stmt, MutExternalOrigin], label: String + stmt: UnsafePointer[sql.sqlite3_stmt, MutUntrackedOrigin], label: String ) raises: var rc = sql.sqlite3_finalize(stmt) _assert(label, rc == Int32(sql.SQLITE_OK)) @@ -120,12 +120,12 @@ def _finalize( def run_basic_checks() raises: _assert("libversion_number", sql.sqlite3_libversion_number() > 0) var v = sql.sqlite3_libversion() - _assert("libversion_ptr", v != Optional[UnsafePointer[Int8, ImmutExternalOrigin]]()) + _assert("libversion_ptr", v != Optional[UnsafePointer[Int8, ImmutUntrackedOrigin]]()) print("basic|PASS") def run_exec_and_rowid( - db: UnsafePointer[sql.sqlite3, MutExternalOrigin], + db: UnsafePointer[sql.sqlite3, MutUntrackedOrigin], ) raises -> None: _exec( db, @@ -141,7 +141,7 @@ def run_exec_and_rowid( print("exec_rowid|PASS") -def run_prepare_reuse(db: UnsafePointer[sql.sqlite3, MutExternalOrigin]) raises: +def run_prepare_reuse(db: UnsafePointer[sql.sqlite3, MutUntrackedOrigin]) raises: _exec(db, "CREATE TABLE t2 (v INT);\0", "prep.schema") var stmt = _prepare(db, "INSERT INTO t2(v) VALUES (?);\0", "prep.insert") @@ -165,7 +165,7 @@ def run_prepare_reuse(db: UnsafePointer[sql.sqlite3, MutExternalOrigin]) raises: def run_text_roundtrip( - db: UnsafePointer[sql.sqlite3, MutExternalOrigin], + db: UnsafePointer[sql.sqlite3, MutUntrackedOrigin], ) raises -> None: _exec(db, "CREATE TABLE txt (v TEXT);\0", "text.schema") @@ -194,7 +194,7 @@ def run_text_roundtrip( ) var p = sql.sqlite3_column_text(stmt, 0) - _assert("col.text.ptr", p != Optional[UnsafePointer[UInt8, ImmutExternalOrigin]]()) + _assert("col.text.ptr", p != Optional[UnsafePointer[UInt8, ImmutUntrackedOrigin]]()) _finalize(stmt, "finalize.text.select") @@ -202,7 +202,7 @@ def run_text_roundtrip( def run_blob_roundtrip( - db: UnsafePointer[sql.sqlite3, MutExternalOrigin] + db: UnsafePointer[sql.sqlite3, MutUntrackedOrigin] ) raises: _exec(db, "CREATE TABLE b (v BLOB);\0", "blob.schema") @@ -217,7 +217,7 @@ def run_blob_roundtrip( var rc = sql.sqlite3_bind_blob( stmt, 1, - rebind[ImmutOpaquePointer[ImmutExternalOrigin]](buf), + rebind[ImmutOpaquePointer[ImmutUntrackedOrigin]](buf), 4, _ignore_bound_value, ) @@ -239,7 +239,7 @@ def run_blob_roundtrip( _assert("blob.size", size == 4) var data = sql.sqlite3_column_blob(stmt, 0) - _assert("blob.ptr", data != Optional[ImmutOpaquePointer[ImmutExternalOrigin]]()) + _assert("blob.ptr", data != Optional[ImmutOpaquePointer[ImmutUntrackedOrigin]]()) _finalize(stmt, "finalize.blob.select") diff --git a/examples/zlib/zlib_dl_smoke.mojo b/examples/zlib/zlib_dl_smoke.mojo index c28756d..4d2315b 100644 --- a/examples/zlib/zlib_dl_smoke.mojo +++ b/examples/zlib/zlib_dl_smoke.mojo @@ -12,8 +12,8 @@ from zlib_bindings_dl import ( ) -def _cstr(s: StaticString) -> UnsafePointer[Int8, ImmutExternalOrigin]: - return rebind[UnsafePointer[Int8, ImmutExternalOrigin]](s.unsafe_ptr()) +def _cstr(s: StaticString) -> UnsafePointer[Int8, ImmutUntrackedOrigin]: + return rebind[UnsafePointer[Int8, ImmutUntrackedOrigin]](s.unsafe_ptr()) def main() raises: diff --git a/mojo_bindgen/codegen/mojo_ir_printer.py b/mojo_bindgen/codegen/mojo_ir_printer.py index 9e3c4f8..8205351 100644 --- a/mojo_bindgen/codegen/mojo_ir_printer.py +++ b/mojo_bindgen/codegen/mojo_ir_printer.py @@ -245,15 +245,15 @@ def _render_support_decls(self, module: MojoModule) -> str: chunks.append( "struct GlobalVar[T: Copyable & ImplicitlyDestructible, //, link: StaticString]:\n" " @staticmethod\n" - " def _raw() raises -> UnsafePointer[Self.T, MutAnyOrigin]:\n" - " var opt: Optional[UnsafePointer[Self.T, MutAnyOrigin]] = _bindgen_dl().get_symbol[Self.T](StringSlice(Self.link))\n" + " def _raw() raises -> UnsafePointer[Self.T, MutUntrackedOrigin]:\n" + " var opt: Optional[UnsafePointer[Self.T, MutUntrackedOrigin]] = _bindgen_dl().get_symbol[Self.T](StringSlice(Self.link))\n" " if not opt:\n" ' raise Error(String("bindgen: missing C global symbol"))\n' " return opt.value()\n" "\n" " @staticmethod\n" - " def ptr() raises -> UnsafePointer[Self.T, MutExternalOrigin]:\n" - " return rebind[UnsafePointer[Self.T, MutExternalOrigin]](Self._raw())\n" + " def ptr() raises -> UnsafePointer[Self.T, MutUntrackedOrigin]:\n" + " return rebind[UnsafePointer[Self.T, MutUntrackedOrigin]](Self._raw())\n" "\n" " @staticmethod\n" " def load() raises -> Self.T:\n" @@ -261,20 +261,20 @@ def _render_support_decls(self, module: MojoModule) -> str: "\n" " @staticmethod\n" " def store(value: Self.T) raises -> None:\n" - " var p = rebind[UnsafePointer[Self.T, MutExternalOrigin]](Self._raw())\n" + " var p = rebind[UnsafePointer[Self.T, MutUntrackedOrigin]](Self._raw())\n" " p[] = value.copy()\n" "\n" "struct GlobalConst[T: Copyable & ImplicitlyDestructible, //, link: StaticString]:\n" " @staticmethod\n" - " def _raw() raises -> UnsafePointer[Self.T, MutAnyOrigin]:\n" - " var opt: Optional[UnsafePointer[Self.T, MutAnyOrigin]] = _bindgen_dl().get_symbol[Self.T](StringSlice(Self.link))\n" + " def _raw() raises -> UnsafePointer[Self.T, MutUntrackedOrigin]:\n" + " var opt: Optional[UnsafePointer[Self.T, MutUntrackedOrigin]] = _bindgen_dl().get_symbol[Self.T](StringSlice(Self.link))\n" " if not opt:\n" ' raise Error(String("bindgen: missing C global symbol"))\n' " return opt.value()\n" "\n" " @staticmethod\n" - " def ptr() raises -> UnsafePointer[Self.T, ImmutExternalOrigin]:\n" - " return rebind[UnsafePointer[Self.T, ImmutExternalOrigin]](Self._raw())\n" + " def ptr() raises -> UnsafePointer[Self.T, ImmutUntrackedOrigin]:\n" + " return rebind[UnsafePointer[Self.T, ImmutUntrackedOrigin]](Self._raw())\n" "\n" " @staticmethod\n" " def load() raises -> Self.T:\n" @@ -452,18 +452,18 @@ def _render_flexible_tail_helpers( b.dedent() b.add("@staticmethod") b.add( - f"def {tail.field_name}_ptr(base: UnsafePointer[{struct_name}, ImmutExternalOrigin]) -> UnsafePointer[{elem_type}, ImmutExternalOrigin]:" + f"def {tail.field_name}_ptr(base: UnsafePointer[{struct_name}, ImmutUntrackedOrigin]) -> UnsafePointer[{elem_type}, ImmutUntrackedOrigin]:" ) b.indent() - b.add(f"var raw = rebind[UnsafePointer[{elem_type}, ImmutExternalOrigin]](base)") + b.add(f"var raw = rebind[UnsafePointer[{elem_type}, ImmutUntrackedOrigin]](base)") b.add(f"return raw + {tail.byte_offset}") b.dedent() b.add("@staticmethod") b.add( - f"def {tail.field_name}_mut_ptr(base: UnsafePointer[{struct_name}, MutExternalOrigin]) -> UnsafePointer[{elem_type}, MutExternalOrigin]:" + f"def {tail.field_name}_mut_ptr(base: UnsafePointer[{struct_name}, MutUntrackedOrigin]) -> UnsafePointer[{elem_type}, MutUntrackedOrigin]:" ) b.indent() - b.add(f"var raw = rebind[UnsafePointer[{elem_type}, MutExternalOrigin]](base)") + b.add(f"var raw = rebind[UnsafePointer[{elem_type}, MutUntrackedOrigin]](base)") b.add(f"return raw + {tail.byte_offset}") b.dedent() @@ -836,9 +836,15 @@ def _render_function_param_name(param: Param, index: int) -> str: @staticmethod def _origin_name(origin: PointerOrigin, mutability: PointerMutability) -> str: if origin == PointerOrigin.ANY: - return "ImmutAnyOrigin" if mutability == PointerMutability.IMMUT else "MutAnyOrigin" + return ( + "ImmutUnsafeAnyOrigin" + if mutability == PointerMutability.IMMUT + else "MutUnsafeAnyOrigin" + ) return ( - "ImmutExternalOrigin" if mutability == PointerMutability.IMMUT else "MutExternalOrigin" + "ImmutUntrackedOrigin" + if mutability == PointerMutability.IMMUT + else "MutUntrackedOrigin" ) @staticmethod diff --git a/mojo_bindgen/layout_tests/generator.py b/mojo_bindgen/layout_tests/generator.py index 07510a2..1e7deac 100644 --- a/mojo_bindgen/layout_tests/generator.py +++ b/mojo_bindgen/layout_tests/generator.py @@ -180,7 +180,7 @@ def render_layout_test_module( for record in checks: lines.extend(["", "", f"def test_layout_{record.record_name}() raises:"]) - lines.append(f" comptime r = reflect[{record.record_name}]()") + lines.append(f" comptime r = reflect[{record.record_name}]") for check in record.checks: lines.append( f' _check_eq("{check.label}", Int({check.expression}), {check.expected})' diff --git a/pixi.lock b/pixi.lock index 8b3b074..02027f3 100644 --- a/pixi.lock +++ b/pixi.lock @@ -188,10 +188,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.15-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-4.1.0-pyhcf101f3_0.conda - - conda: https://conda.modular.com/max/linux-64/mojo-1.0.0b1-release.conda - - conda: https://conda.modular.com/max/linux-64/mojo-compiler-1.0.0b1-release.conda - - conda: https://conda.modular.com/max/noarch/mblack-26.3.0-release.conda - - conda: https://conda.modular.com/max/noarch/mojo-python-1.0.0b1-release.conda + - conda: https://conda.modular.com/max/linux-64/mojo-1.0.0b2-release.conda + - conda: https://conda.modular.com/max/linux-64/mojo-compiler-1.0.0b2-release.conda + - conda: https://conda.modular.com/max/noarch/mblack-26.4.0-release.conda + - conda: https://conda.modular.com/max/noarch/mojo-python-1.0.0b2-release.conda - pypi: . - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/16/6b/330d8ebae582b30c2959a1ef4c3bc344ebde48c2ff0c3f113c4710735e11/pyright-1.1.409-py3-none-any.whl @@ -264,10 +264,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-4.1.0-pyhcf101f3_0.conda - - conda: https://conda.modular.com/max/linux-64/mojo-1.0.0b1-release.conda - - conda: https://conda.modular.com/max/linux-64/mojo-compiler-1.0.0b1-release.conda - - conda: https://conda.modular.com/max/noarch/mblack-26.3.0-release.conda - - conda: https://conda.modular.com/max/noarch/mojo-python-1.0.0b1-release.conda + - conda: https://conda.modular.com/max/linux-64/mojo-1.0.0b2-release.conda + - conda: https://conda.modular.com/max/linux-64/mojo-compiler-1.0.0b2-release.conda + - conda: https://conda.modular.com/max/noarch/mblack-26.4.0-release.conda + - conda: https://conda.modular.com/max/noarch/mojo-python-1.0.0b2-release.conda - pypi: . - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1d/fc/716c1e62e512ef1c160e7984a73a5fc7df45166f2ff3f254e71c58076f7c/libclang-18.1.1-py2.py3-none-manylinux2010_x86_64.whl @@ -2631,31 +2631,31 @@ packages: - pkg:pypi/zipp?source=compressed-mapping size: 24190 timestamp: 1779159948016 -- conda: https://conda.modular.com/max/linux-64/mojo-1.0.0b1-release.conda - sha256: a8f36a83ece187307d7d78c152828eac58edb002d515de2bcbe9f5a19388b70c - md5: 11bdf0256d179b89dc00ca4150c6963c +- conda: https://conda.modular.com/max/linux-64/mojo-1.0.0b2-release.conda + sha256: 7553366c138bae2fcf8617582f1bb6d6b6742087bd6a83ea83aa41c023499382 + md5: 8d4390edde2dcf29880c57b3088f15aa depends: - python >=3.10 - - mojo-compiler ==1.0.0b1 - - mblack ==26.3.0 + - mojo-compiler ==1.0.0b2 + - mblack ==26.4.0 - jupyter_client >=8.6.2,<8.7 license: LicenseRef-Modular-Proprietary run_exports: {} - size: 94106548 - timestamp: 1777595784229 -- conda: https://conda.modular.com/max/linux-64/mojo-compiler-1.0.0b1-release.conda - sha256: 706c7f8e2be740dda8039bf96182b578bfbbd9220ca1a7f762e1f82acc4eb784 - md5: 2fc6038c3837e50bb855bcf7f930c1c9 + size: 96475709 + timestamp: 1781237127405 +- conda: https://conda.modular.com/max/linux-64/mojo-compiler-1.0.0b2-release.conda + sha256: 87f8e9ef573f37072423aeb56a7c468bdb5f5889476bce4aa7c3396665c651fe + md5: 6be85d17872f5c2370015ca4ec07dd0d depends: - - mojo-python ==1.0.0b1 + - mojo-python ==1.0.0b2 license: LicenseRef-Modular-Proprietary run_exports: {} - size: 89421276 - timestamp: 1777595833113 -- conda: https://conda.modular.com/max/noarch/mblack-26.3.0-release.conda + size: 85342385 + timestamp: 1781237127405 +- conda: https://conda.modular.com/max/noarch/mblack-26.4.0-release.conda noarch: python - sha256: c7c36d5b223862acffaaacdfc6f672ca198a046a66f4a956ca57933123fb93b2 - md5: 63c657fb1780079c3f6cbb7a758a16d2 + sha256: e2497cbefbf5d962cd0db8c1b893e7e48d8f3603cab84a9d8bad0030b5bb26b1 + md5: ec6bf2b9588f5ba4bd3472c0773c4892 depends: - python >=3.10 - click >=8.0.0 @@ -2666,18 +2666,18 @@ packages: - tomli >=1.1.0 license: LicenseRef-Modular-Proprietary run_exports: {} - size: 135000 - timestamp: 1777574970629 -- conda: https://conda.modular.com/max/noarch/mojo-python-1.0.0b1-release.conda + size: 135301 + timestamp: 1781220755102 +- conda: https://conda.modular.com/max/noarch/mojo-python-1.0.0b2-release.conda noarch: python - sha256: b0554c7705685c86e8a8063bcd11ed58897a498c8e1e19ef045f5ebba2c8874f - md5: d0ad2f8ba3758f03bfda84d92bb34b67 + sha256: 37bf44a74edcd2ebaec7fe8299ef183e006ad051bfcf21caa06becc0e0eeffd5 + md5: 8781bd673909835fa59ce818e3835839 depends: - python >=3.10 license: LicenseRef-Modular-Proprietary run_exports: {} - size: 23114 - timestamp: 1777594699418 + size: 24682 + timestamp: 1781220753246 - pypi: . name: mojo-bindgen requires_dist: diff --git a/pixi.toml b/pixi.toml index dad516e..40c3df2 100644 --- a/pixi.toml +++ b/pixi.toml @@ -29,7 +29,7 @@ example-sqlite = "bash examples/sqlite/generate.sh" example-global-consts = "bash examples/global_consts/generate.sh" [dependencies] -mojo = ">=1.0.0b1,<2" +mojo = ">=1.0.0b2,<2" python = ">=3.14.4,<3.15" pip = ">=26.0.1,<27" rich = ">=15.0.0,<16" diff --git a/tests/e2e/fixtures/atomic_types_runtime/expect.emit.external.mojo b/tests/e2e/fixtures/atomic_types_runtime/expect.emit.external.mojo index a663649..298d5b3 100644 --- a/tests/e2e/fixtures/atomic_types_runtime/expect.emit.external.mojo +++ b/tests/e2e/fixtures/atomic_types_runtime/expect.emit.external.mojo @@ -4,8 +4,8 @@ def at_reset( def at_inc( def at_dec( def at_get( -def at_addr() abi("C") -> Optional[UnsafePointer[Atomic[DType.int32], MutExternalOrigin]]: -def at_addr_const() abi("C") -> Optional[UnsafePointer[Atomic[DType.int32], ImmutExternalOrigin]]: -def at_store_ptr(dst: Optional[UnsafePointer[Atomic[DType.int32], MutExternalOrigin]], value: c_int) abi("C") -> None: -def at_load_ptr(src: Optional[UnsafePointer[Atomic[DType.int32], ImmutExternalOrigin]]) abi("C") -> c_int: -def at_inc_ptr(dst: Optional[UnsafePointer[Atomic[DType.int32], MutExternalOrigin]]) abi("C") -> c_int: +def at_addr() abi("C") -> Optional[UnsafePointer[Atomic[DType.int32], MutUntrackedOrigin]]: +def at_addr_const() abi("C") -> Optional[UnsafePointer[Atomic[DType.int32], ImmutUntrackedOrigin]]: +def at_store_ptr(dst: Optional[UnsafePointer[Atomic[DType.int32], MutUntrackedOrigin]], value: c_int) abi("C") -> None: +def at_load_ptr(src: Optional[UnsafePointer[Atomic[DType.int32], ImmutUntrackedOrigin]]) abi("C") -> c_int: +def at_inc_ptr(dst: Optional[UnsafePointer[Atomic[DType.int32], MutUntrackedOrigin]]) abi("C") -> c_int: diff --git a/tests/e2e/fixtures/atomic_types_runtime/expect.emit.owned_dl_handle.mojo b/tests/e2e/fixtures/atomic_types_runtime/expect.emit.owned_dl_handle.mojo index c316e78..be6612f 100644 --- a/tests/e2e/fixtures/atomic_types_runtime/expect.emit.owned_dl_handle.mojo +++ b/tests/e2e/fixtures/atomic_types_runtime/expect.emit.owned_dl_handle.mojo @@ -4,8 +4,8 @@ def at_reset( def at_inc( def at_dec( def at_get( -def at_addr() raises -> Optional[UnsafePointer[Atomic[DType.int32], MutExternalOrigin]]: -def at_addr_const() raises -> Optional[UnsafePointer[Atomic[DType.int32], ImmutExternalOrigin]]: -def at_store_ptr(dst: Optional[UnsafePointer[Atomic[DType.int32], MutExternalOrigin]], value: c_int) raises -> None: -def at_load_ptr(src: Optional[UnsafePointer[Atomic[DType.int32], ImmutExternalOrigin]]) raises -> c_int: -def at_inc_ptr(dst: Optional[UnsafePointer[Atomic[DType.int32], MutExternalOrigin]]) raises -> c_int: +def at_addr() raises -> Optional[UnsafePointer[Atomic[DType.int32], MutUntrackedOrigin]]: +def at_addr_const() raises -> Optional[UnsafePointer[Atomic[DType.int32], ImmutUntrackedOrigin]]: +def at_store_ptr(dst: Optional[UnsafePointer[Atomic[DType.int32], MutUntrackedOrigin]], value: c_int) raises -> None: +def at_load_ptr(src: Optional[UnsafePointer[Atomic[DType.int32], ImmutUntrackedOrigin]]) raises -> c_int: +def at_inc_ptr(dst: Optional[UnsafePointer[Atomic[DType.int32], MutUntrackedOrigin]]) raises -> c_int: diff --git a/tests/e2e/fixtures/incomplete_array_padding/expect.emit.external.mojo b/tests/e2e/fixtures/incomplete_array_padding/expect.emit.external.mojo index cd27d1d..080343d 100644 --- a/tests/e2e/fixtures/incomplete_array_padding/expect.emit.external.mojo +++ b/tests/e2e/fixtures/incomplete_array_padding/expect.emit.external.mojo @@ -3,8 +3,8 @@ struct iap_packet var payload: InlineArray[uint8_t, 0] @staticmethod def payload_offset() -> UInt: -def payload_ptr(base: UnsafePointer[iap_packet, ImmutExternalOrigin]) -> UnsafePointer[uint8_t, ImmutExternalOrigin]: -def payload_mut_ptr(base: UnsafePointer[iap_packet, MutExternalOrigin]) -> UnsafePointer[uint8_t, MutExternalOrigin]: +def payload_ptr(base: UnsafePointer[iap_packet, ImmutUntrackedOrigin]) -> UnsafePointer[uint8_t, ImmutUntrackedOrigin]: +def payload_mut_ptr(base: UnsafePointer[iap_packet, MutUntrackedOrigin]) -> UnsafePointer[uint8_t, MutUntrackedOrigin]: def iap_fixture( def iap_header_size( def iap_sanity( diff --git a/tests/e2e/fixtures/incomplete_array_padding/expect.emit.owned_dl_handle.mojo b/tests/e2e/fixtures/incomplete_array_padding/expect.emit.owned_dl_handle.mojo index 4b44b19..52db218 100644 --- a/tests/e2e/fixtures/incomplete_array_padding/expect.emit.owned_dl_handle.mojo +++ b/tests/e2e/fixtures/incomplete_array_padding/expect.emit.owned_dl_handle.mojo @@ -2,8 +2,8 @@ struct iap_packet var payload: InlineArray[uint8_t, 0] @staticmethod def payload_offset() -> UInt: -def payload_ptr(base: UnsafePointer[iap_packet, ImmutExternalOrigin]) -> UnsafePointer[uint8_t, ImmutExternalOrigin]: -def payload_mut_ptr(base: UnsafePointer[iap_packet, MutExternalOrigin]) -> UnsafePointer[uint8_t, MutExternalOrigin]: +def payload_ptr(base: UnsafePointer[iap_packet, ImmutUntrackedOrigin]) -> UnsafePointer[uint8_t, ImmutUntrackedOrigin]: +def payload_mut_ptr(base: UnsafePointer[iap_packet, MutUntrackedOrigin]) -> UnsafePointer[uint8_t, MutUntrackedOrigin]: def iap_fixture( def iap_header_size( def iap_sanity( diff --git a/tests/e2e/fixtures/zero_length_tail_access/expect.emit.external.mojo b/tests/e2e/fixtures/zero_length_tail_access/expect.emit.external.mojo index bdac3c6..e4eb15d 100644 --- a/tests/e2e/fixtures/zero_length_tail_access/expect.emit.external.mojo +++ b/tests/e2e/fixtures/zero_length_tail_access/expect.emit.external.mojo @@ -3,8 +3,8 @@ struct zta_packet var payload: InlineArray[uint8_t, 0] @staticmethod def payload_offset() -> UInt: -def payload_ptr(base: UnsafePointer[zta_packet, ImmutExternalOrigin]) -> UnsafePointer[uint8_t, ImmutExternalOrigin]: -def payload_mut_ptr(base: UnsafePointer[zta_packet, MutExternalOrigin]) -> UnsafePointer[uint8_t, MutExternalOrigin]: +def payload_ptr(base: UnsafePointer[zta_packet, ImmutUntrackedOrigin]) -> UnsafePointer[uint8_t, ImmutUntrackedOrigin]: +def payload_mut_ptr(base: UnsafePointer[zta_packet, MutUntrackedOrigin]) -> UnsafePointer[uint8_t, MutUntrackedOrigin]: def zta_fixture( def zta_header_size( def zta_sanity( diff --git a/tests/e2e/fixtures/zero_length_tail_access/expect.emit.owned_dl_handle.mojo b/tests/e2e/fixtures/zero_length_tail_access/expect.emit.owned_dl_handle.mojo index 16b0681..3356e14 100644 --- a/tests/e2e/fixtures/zero_length_tail_access/expect.emit.owned_dl_handle.mojo +++ b/tests/e2e/fixtures/zero_length_tail_access/expect.emit.owned_dl_handle.mojo @@ -2,8 +2,8 @@ struct zta_packet var payload: InlineArray[uint8_t, 0] @staticmethod def payload_offset() -> UInt: -def payload_ptr(base: UnsafePointer[zta_packet, ImmutExternalOrigin]) -> UnsafePointer[uint8_t, ImmutExternalOrigin]: -def payload_mut_ptr(base: UnsafePointer[zta_packet, MutExternalOrigin]) -> UnsafePointer[uint8_t, MutExternalOrigin]: +def payload_ptr(base: UnsafePointer[zta_packet, ImmutUntrackedOrigin]) -> UnsafePointer[uint8_t, ImmutUntrackedOrigin]: +def payload_mut_ptr(base: UnsafePointer[zta_packet, MutUntrackedOrigin]) -> UnsafePointer[uint8_t, MutUntrackedOrigin]: def zta_fixture( def zta_header_size( def zta_sanity( diff --git a/tests/surface/fixtures/global_stub_const_ptr/expect.external.mojo b/tests/surface/fixtures/global_stub_const_ptr/expect.external.mojo index ca7ddc1..ec43f74 100644 --- a/tests/surface/fixtures/global_stub_const_ptr/expect.external.mojo +++ b/tests/surface/fixtures/global_stub_const_ptr/expect.external.mojo @@ -11,15 +11,15 @@ def _bindgen_dl() raises -> OwnedDLHandle: struct GlobalVar[T: Copyable & ImplicitlyDestructible, //, link: StaticString]: @staticmethod - def _raw() raises -> UnsafePointer[Self.T, MutAnyOrigin]: - var opt: Optional[UnsafePointer[Self.T, MutAnyOrigin]] = _bindgen_dl().get_symbol[Self.T](StringSlice(Self.link)) + def _raw() raises -> UnsafePointer[Self.T, MutUntrackedOrigin]: + var opt: Optional[UnsafePointer[Self.T, MutUntrackedOrigin]] = _bindgen_dl().get_symbol[Self.T](StringSlice(Self.link)) if not opt: raise Error(String("bindgen: missing C global symbol")) return opt.value() @staticmethod - def ptr() raises -> UnsafePointer[Self.T, MutExternalOrigin]: - return rebind[UnsafePointer[Self.T, MutExternalOrigin]](Self._raw()) + def ptr() raises -> UnsafePointer[Self.T, MutUntrackedOrigin]: + return rebind[UnsafePointer[Self.T, MutUntrackedOrigin]](Self._raw()) @staticmethod def load() raises -> Self.T: @@ -27,20 +27,20 @@ struct GlobalVar[T: Copyable & ImplicitlyDestructible, //, link: StaticString]: @staticmethod def store(value: Self.T) raises -> None: - var p = rebind[UnsafePointer[Self.T, MutExternalOrigin]](Self._raw()) + var p = rebind[UnsafePointer[Self.T, MutUntrackedOrigin]](Self._raw()) p[] = value.copy() struct GlobalConst[T: Copyable & ImplicitlyDestructible, //, link: StaticString]: @staticmethod - def _raw() raises -> UnsafePointer[Self.T, MutAnyOrigin]: - var opt: Optional[UnsafePointer[Self.T, MutAnyOrigin]] = _bindgen_dl().get_symbol[Self.T](StringSlice(Self.link)) + def _raw() raises -> UnsafePointer[Self.T, MutUntrackedOrigin]: + var opt: Optional[UnsafePointer[Self.T, MutUntrackedOrigin]] = _bindgen_dl().get_symbol[Self.T](StringSlice(Self.link)) if not opt: raise Error(String("bindgen: missing C global symbol")) return opt.value() @staticmethod - def ptr() raises -> UnsafePointer[Self.T, ImmutExternalOrigin]: - return rebind[UnsafePointer[Self.T, ImmutExternalOrigin]](Self._raw()) + def ptr() raises -> UnsafePointer[Self.T, ImmutUntrackedOrigin]: + return rebind[UnsafePointer[Self.T, ImmutUntrackedOrigin]](Self._raw()) @staticmethod def load() raises -> Self.T: @@ -49,5 +49,5 @@ struct GlobalConst[T: Copyable & ImplicitlyDestructible, //, link: StaticString] struct gscp_cfg(Copyable, Movable): pass -# global `gscp_default_cfg` -> Optional[UnsafePointer[gscp_cfg, ImmutExternalOrigin]] -comptime gscp_default_cfg = GlobalVar[T=Optional[UnsafePointer[gscp_cfg, ImmutExternalOrigin]], link="gscp_default_cfg"] +# global `gscp_default_cfg` -> Optional[UnsafePointer[gscp_cfg, ImmutUntrackedOrigin]] +comptime gscp_default_cfg = GlobalVar[T=Optional[UnsafePointer[gscp_cfg, ImmutUntrackedOrigin]], link="gscp_default_cfg"] diff --git a/tests/surface/fixtures/globals_and_consts/expect.external.mojo b/tests/surface/fixtures/globals_and_consts/expect.external.mojo index a9aa7fc..fcc1a1a 100644 --- a/tests/surface/fixtures/globals_and_consts/expect.external.mojo +++ b/tests/surface/fixtures/globals_and_consts/expect.external.mojo @@ -11,15 +11,15 @@ def _bindgen_dl() raises -> OwnedDLHandle: struct GlobalVar[T: Copyable & ImplicitlyDestructible, //, link: StaticString]: @staticmethod - def _raw() raises -> UnsafePointer[Self.T, MutAnyOrigin]: - var opt: Optional[UnsafePointer[Self.T, MutAnyOrigin]] = _bindgen_dl().get_symbol[Self.T](StringSlice(Self.link)) + def _raw() raises -> UnsafePointer[Self.T, MutUntrackedOrigin]: + var opt: Optional[UnsafePointer[Self.T, MutUntrackedOrigin]] = _bindgen_dl().get_symbol[Self.T](StringSlice(Self.link)) if not opt: raise Error(String("bindgen: missing C global symbol")) return opt.value() @staticmethod - def ptr() raises -> UnsafePointer[Self.T, MutExternalOrigin]: - return rebind[UnsafePointer[Self.T, MutExternalOrigin]](Self._raw()) + def ptr() raises -> UnsafePointer[Self.T, MutUntrackedOrigin]: + return rebind[UnsafePointer[Self.T, MutUntrackedOrigin]](Self._raw()) @staticmethod def load() raises -> Self.T: @@ -27,20 +27,20 @@ struct GlobalVar[T: Copyable & ImplicitlyDestructible, //, link: StaticString]: @staticmethod def store(value: Self.T) raises -> None: - var p = rebind[UnsafePointer[Self.T, MutExternalOrigin]](Self._raw()) + var p = rebind[UnsafePointer[Self.T, MutUntrackedOrigin]](Self._raw()) p[] = value.copy() struct GlobalConst[T: Copyable & ImplicitlyDestructible, //, link: StaticString]: @staticmethod - def _raw() raises -> UnsafePointer[Self.T, MutAnyOrigin]: - var opt: Optional[UnsafePointer[Self.T, MutAnyOrigin]] = _bindgen_dl().get_symbol[Self.T](StringSlice(Self.link)) + def _raw() raises -> UnsafePointer[Self.T, MutUntrackedOrigin]: + var opt: Optional[UnsafePointer[Self.T, MutUntrackedOrigin]] = _bindgen_dl().get_symbol[Self.T](StringSlice(Self.link)) if not opt: raise Error(String("bindgen: missing C global symbol")) return opt.value() @staticmethod - def ptr() raises -> UnsafePointer[Self.T, ImmutExternalOrigin]: - return rebind[UnsafePointer[Self.T, ImmutExternalOrigin]](Self._raw()) + def ptr() raises -> UnsafePointer[Self.T, ImmutUntrackedOrigin]: + return rebind[UnsafePointer[Self.T, ImmutUntrackedOrigin]](Self._raw()) @staticmethod def load() raises -> Self.T: diff --git a/tests/surface/fixtures/opaque_forward_ptrs/expect.external.mojo b/tests/surface/fixtures/opaque_forward_ptrs/expect.external.mojo index 342517d..a3b2d50 100644 --- a/tests/surface/fixtures/opaque_forward_ptrs/expect.external.mojo +++ b/tests/surface/fixtures/opaque_forward_ptrs/expect.external.mojo @@ -8,8 +8,8 @@ from std.ffi import external_call struct ofp_handle(Copyable, Movable): pass -def ofp_open() abi("C") -> Optional[UnsafePointer[ofp_handle, MutExternalOrigin]]: - return external_call["ofp_open", Optional[UnsafePointer[ofp_handle, MutExternalOrigin]]]() +def ofp_open() abi("C") -> Optional[UnsafePointer[ofp_handle, MutUntrackedOrigin]]: + return external_call["ofp_open", Optional[UnsafePointer[ofp_handle, MutUntrackedOrigin]]]() -def ofp_close(handle: Optional[UnsafePointer[ofp_handle, MutExternalOrigin]]) abi("C") -> None: - external_call["ofp_close", NoneType, Optional[UnsafePointer[ofp_handle, MutExternalOrigin]]](handle) +def ofp_close(handle: Optional[UnsafePointer[ofp_handle, MutUntrackedOrigin]]) abi("C") -> None: + external_call["ofp_close", NoneType, Optional[UnsafePointer[ofp_handle, MutUntrackedOrigin]]](handle) diff --git a/tests/unit/test_ir_codegen_edges.py b/tests/unit/test_ir_codegen_edges.py index cb2e580..8f636ac 100644 --- a/tests/unit/test_ir_codegen_edges.py +++ b/tests/unit/test_ir_codegen_edges.py @@ -785,7 +785,7 @@ def test_generator_preserves_typedef_names_in_fields_globals_and_aliases() -> No ) out = MojoGenerator(MojoEmitOptions()).generate(unit) assert "comptime my_uint = c_int" in out - assert "comptime my_uint_ptr = Optional[UnsafePointer[my_uint, MutExternalOrigin]]" in out + assert "comptime my_uint_ptr = Optional[UnsafePointer[my_uint, MutUntrackedOrigin]]" in out assert "var value: my_uint" in out assert "var ptr: my_uint_ptr" in out assert 'comptime global_ptr = GlobalVar[T=my_uint_ptr, link="global_ptr"]' in out @@ -1153,19 +1153,19 @@ def test_generator_uses_callback_alias_types_in_wrapper_abi_lists() -> None: assert "comptime sqlite3_create_collation_v2_xDestroy_cb = def (" in out assert ( "def sqlite3_create_collation_v2(" - "db: Optional[UnsafePointer[sqlite3, MutExternalOrigin]], " - "zName: Optional[UnsafePointer[c_char, MutExternalOrigin]], " + "db: Optional[UnsafePointer[sqlite3, MutUntrackedOrigin]], " + "zName: Optional[UnsafePointer[c_char, MutUntrackedOrigin]], " "eTextRep: c_int, " - "ctx: Optional[MutOpaquePointer[MutExternalOrigin]], " + "ctx: Optional[MutOpaquePointer[MutUntrackedOrigin]], " "xCompare: sqlite3_create_collation_v2_xCompare_cb, " "xDestroy: sqlite3_create_collation_v2_xDestroy_cb" ') abi("C") -> c_int:' ) in out assert ( 'return external_call["sqlite3_create_collation_v2", c_int, ' - "Optional[UnsafePointer[sqlite3, MutExternalOrigin]], " - "Optional[UnsafePointer[c_char, MutExternalOrigin]], c_int, " - "Optional[MutOpaquePointer[MutExternalOrigin]], " + "Optional[UnsafePointer[sqlite3, MutUntrackedOrigin]], " + "Optional[UnsafePointer[c_char, MutUntrackedOrigin]], c_int, " + "Optional[MutOpaquePointer[MutUntrackedOrigin]], " "sqlite3_create_collation_v2_xCompare_cb, sqlite3_create_collation_v2_xDestroy_cb]" "(db, zName, eTextRep, ctx, xCompare, xDestroy)" ) in out @@ -1217,12 +1217,12 @@ def test_generator_keeps_nested_callback_typedef_in_wrapper_abi_lists() -> None: assert "comptime nested_cb_t = def (" in out assert ( "def install_nested_cb(slot: Optional[UnsafePointer[Optional[UnsafePointer[nested_cb_t, " - 'MutExternalOrigin]], MutExternalOrigin]]) abi("C") -> None:' + 'MutUntrackedOrigin]], MutUntrackedOrigin]]) abi("C") -> None:' ) in out assert ( 'external_call["install_nested_cb", NoneType, ' - "Optional[UnsafePointer[Optional[UnsafePointer[nested_cb_t, MutExternalOrigin]], " - "MutExternalOrigin]]](slot)" + "Optional[UnsafePointer[Optional[UnsafePointer[nested_cb_t, MutUntrackedOrigin]], " + "MutUntrackedOrigin]]](slot)" ) in out diff --git a/tests/unit/test_layout_tests.py b/tests/unit/test_layout_tests.py index 4a5dc99..3985dc6 100644 --- a/tests/unit/test_layout_tests.py +++ b/tests/unit/test_layout_tests.py @@ -333,7 +333,7 @@ def test_render_layout_test_module_imports_records_and_calls_tests() -> None: assert "from std.reflection import reflect" in out assert "from bindings import Sample" in out assert "def test_layout_Sample() raises:" in out - assert "comptime r = reflect[Sample]()" in out + assert "comptime r = reflect[Sample]" in out assert "r.field_offset[index=0]()" in out assert ( "def main() raises:\n TestSuite.discover_tests[__functions_in_module()]().run()" in out diff --git a/tests/unit/test_mojo_ir_printer.py b/tests/unit/test_mojo_ir_printer.py index 8bb46af..1a51de2 100644 --- a/tests/unit/test_mojo_ir_printer.py +++ b/tests/unit/test_mojo_ir_printer.py @@ -297,7 +297,7 @@ def test_render_mojo_module_external_surface_with_synthesized_callback_aliases() assert "comptime Packet = UnsafeUnion[c_int, Widget]" in out assert "comptime LIMIT = (1 + 2)" in out assert ( - 'def install(cb: install_cb, widget: UnsafePointer[Widget, ImmutExternalOrigin]) abi("C") -> None:' + 'def install(cb: install_cb, widget: UnsafePointer[Widget, ImmutUntrackedOrigin]) abi("C") -> None:' in out ) @@ -391,7 +391,7 @@ def test_render_callback_alias_uses_none_in_signature_position() -> None: ) assert ( - 'comptime log_callback_t = def (msg: UnsafePointer[c_char, ImmutExternalOrigin]) thin abi("C") -> None' + 'comptime log_callback_t = def (msg: UnsafePointer[c_char, ImmutUntrackedOrigin]) thin abi("C") -> None' in out ) @@ -438,12 +438,12 @@ def test_render_struct_emits_flexible_tail_helpers() -> None: assert "@staticmethod" in rendered assert "def payload_offset() -> UInt:" in rendered assert ( - "def payload_ptr(base: UnsafePointer[Packet, ImmutExternalOrigin]) -> " - "UnsafePointer[c_uchar, ImmutExternalOrigin]:" in rendered + "def payload_ptr(base: UnsafePointer[Packet, ImmutUntrackedOrigin]) -> " + "UnsafePointer[c_uchar, ImmutUntrackedOrigin]:" in rendered ) assert ( - "def payload_mut_ptr(base: UnsafePointer[Packet, MutExternalOrigin]) -> " - "UnsafePointer[c_uchar, MutExternalOrigin]:" in rendered + "def payload_mut_ptr(base: UnsafePointer[Packet, MutUntrackedOrigin]) -> " + "UnsafePointer[c_uchar, MutUntrackedOrigin]:" in rendered ) assert "return raw + 4" in rendered @@ -950,4 +950,4 @@ def test_rendered_mojo_module_compiles_with_mixed_decl_kinds(tmp_path: Path) -> in rendered ) assert 'def install(cb: binary_cb_t) abi("C") -> None:' in rendered - assert "def load_widget() raises -> UnsafePointer[Widget, MutExternalOrigin]:" in rendered + assert "def load_widget() raises -> UnsafePointer[Widget, MutUntrackedOrigin]:" in rendered diff --git a/tests/unit/test_type_lowering.py b/tests/unit/test_type_lowering.py index ef06ff3..1cb8586 100644 --- a/tests/unit/test_type_lowering.py +++ b/tests/unit/test_type_lowering.py @@ -152,11 +152,11 @@ def test_codegen_preserves_callback_parameter_names_and_falls_back_for_unnamed( out = MojoGenerator(MojoEmitOptions()).generate(unit) assert ( - 'comptime named_cb_t = def (value: c_int, userdata: Optional[MutOpaquePointer[MutExternalOrigin]]) thin abi("C") -> c_int' + 'comptime named_cb_t = def (value: c_int, userdata: Optional[MutOpaquePointer[MutUntrackedOrigin]]) thin abi("C") -> c_int' in out ) assert ( - 'comptime callbacks_t_poll_cb = def (timeout_ms: c_int, arg1: Optional[MutOpaquePointer[MutExternalOrigin]]) thin abi("C") -> c_int' + 'comptime callbacks_t_poll_cb = def (timeout_ms: c_int, arg1: Optional[MutOpaquePointer[MutUntrackedOrigin]]) thin abi("C") -> c_int' in out ) @@ -588,11 +588,11 @@ def test_codegen_emits_named_nested_record_defs_before_parent(tmp_path: Path) -> assert "struct sqlite3_index_info" in out assert out.index("struct sqlite3_index_constraint") < out.index("struct sqlite3_index_info") assert ( - "var aConstraint: Optional[UnsafePointer[sqlite3_index_constraint, MutExternalOrigin]]" + "var aConstraint: Optional[UnsafePointer[sqlite3_index_constraint, MutUntrackedOrigin]]" in out ) - assert "var aOrderBy: Optional[UnsafePointer[sqlite3_index_orderby, MutExternalOrigin]]" in out + assert "var aOrderBy: Optional[UnsafePointer[sqlite3_index_orderby, MutUntrackedOrigin]]" in out assert ( - "var aConstraintUsage: Optional[UnsafePointer[sqlite3_index_constraint_usage, MutExternalOrigin]]" + "var aConstraintUsage: Optional[UnsafePointer[sqlite3_index_constraint_usage, MutUntrackedOrigin]]" in out ) From 96554235fd70370ad98bd605c75207d1417bc62c Mon Sep 17 00:00:00 2001 From: MoSafi2 Date: Thu, 18 Jun 2026 23:30:53 +0200 Subject: [PATCH 2/4] fix check-light parser typing --- mojo_bindgen/parsing/frontend.py | 10 +- mojo_bindgen/parsing/lowering/__init__.py | 1 - mojo_bindgen/parsing/lowering/const_expr.py | 3 +- .../parsing/lowering/decl_lowering.py | 7 +- .../parsing/lowering/record_lowering.py | 27 +-- .../parsing/lowering/type_lowering.py | 9 +- pyproject.toml | 1 - typings/clang/__init__.pyi | 1 + typings/clang/cindex.pyi | 179 ++++++++++++++++++ uv.lock | 2 +- 10 files changed, 214 insertions(+), 26 deletions(-) create mode 100644 typings/clang/__init__.pyi create mode 100644 typings/clang/cindex.pyi diff --git a/mojo_bindgen/parsing/frontend.py b/mojo_bindgen/parsing/frontend.py index 3f94c87..09568ea 100644 --- a/mojo_bindgen/parsing/frontend.py +++ b/mojo_bindgen/parsing/frontend.py @@ -12,7 +12,7 @@ from collections.abc import Iterator from dataclasses import dataclass from pathlib import Path -from typing import ClassVar +from typing import Any, ClassVar, cast import clang.cindex as cx @@ -279,8 +279,8 @@ def get_element_type(self, t: cx.Type) -> cx.Type: """Return a vector or complex element type across libclang variants.""" getter = getattr(t, "get_element_type", None) if callable(getter): - return getter() - return getattr(t, "element_type") + return cast(cx.Type, getter()) + return cast(cx.Type, getattr(t, "element_type")) def get_num_elements(self, t: cx.Type) -> int | None: """Return vector element count across libclang variants.""" @@ -317,14 +317,14 @@ def get_value_type(self, t: cx.Type) -> cx.Type | None: getter = getattr(t, "get_value_type", None) if callable(getter): try: - value_type = getter() + value_type = cast(cx.Type, getter()) except Exception: return None return None if value_type.kind == cx.TypeKind.INVALID else value_type if not self._ensure_value_type_api(): return None try: - value_type = cx.conf.lib.clang_Type_getValueType(t) + value_type = cast(cx.Type, cast(Any, cx.conf.lib).clang_Type_getValueType(t)) except Exception: return None return None if value_type.kind == cx.TypeKind.INVALID else value_type diff --git a/mojo_bindgen/parsing/lowering/__init__.py b/mojo_bindgen/parsing/lowering/__init__.py index 16a8dc7..fc35af6 100644 --- a/mojo_bindgen/parsing/lowering/__init__.py +++ b/mojo_bindgen/parsing/lowering/__init__.py @@ -35,6 +35,5 @@ "RecordRegistry", "TypeContext", "TypeLowerer", - "_suffix_probe_parse_args", "default_signed_int_primitive", ] diff --git a/mojo_bindgen/parsing/lowering/const_expr.py b/mojo_bindgen/parsing/lowering/const_expr.py index ba82f23..dd7258e 100644 --- a/mojo_bindgen/parsing/lowering/const_expr.py +++ b/mojo_bindgen/parsing/lowering/const_expr.py @@ -26,6 +26,7 @@ IntKind, IntLiteral, IntType, + MacroDeclKind, NullPtrLiteral, RefExpr, SizeOfExpr, @@ -330,7 +331,7 @@ class ParsedMacro: """Classification result for one macro definition.""" tokens: list[str] - kind: str + kind: MacroDeclKind expr: ConstExpr | None = None primitive: IntType | FloatType | VoidType | None = None diagnostic: str | None = None diff --git a/mojo_bindgen/parsing/lowering/decl_lowering.py b/mojo_bindgen/parsing/lowering/decl_lowering.py index 0d99793..8fde156 100644 --- a/mojo_bindgen/parsing/lowering/decl_lowering.py +++ b/mojo_bindgen/parsing/lowering/decl_lowering.py @@ -17,6 +17,7 @@ Function, GlobalVar, IntLiteral, + IntType, MacroDecl, Param, Typedef, @@ -199,11 +200,11 @@ def _function_is_noreturn(cursor: cx.Cursor) -> bool: return True return False - def _anonymous_enum_as_consts(self, cursor: cx.Cursor) -> list[Const]: + def _anonymous_enum_as_consts(self, cursor: cx.Cursor) -> list[Decl]: underlying = self.primitive_resolver.resolve_primitive(cursor.enum_type) if underlying is None: underlying = default_signed_int_primitive() - out: list[Const] = [] + out: list[Decl] = [] for child in cursor.get_children(): if child.kind == cx.CursorKind.ENUM_CONSTANT_DECL: out.append( @@ -221,7 +222,7 @@ def _build_enum(self, cursor: cx.Cursor) -> Enum | None: if not c_name: return None underlying = self.primitive_resolver.resolve_primitive(cursor.enum_type) - if underlying is None: + if not isinstance(underlying, IntType): underlying = default_signed_int_primitive() enumerants: list[Enumerant] = [] for child in cursor.get_children(): diff --git a/mojo_bindgen/parsing/lowering/record_lowering.py b/mojo_bindgen/parsing/lowering/record_lowering.py index 71bd175..40ed78d 100644 --- a/mojo_bindgen/parsing/lowering/record_lowering.py +++ b/mojo_bindgen/parsing/lowering/record_lowering.py @@ -8,10 +8,11 @@ from __future__ import annotations from dataclasses import dataclass +from typing import cast import clang.cindex as cx -from mojo_bindgen.ir import Array, Field, IntType, Struct, StructRef, Type +from mojo_bindgen.ir import Array, FamPattern, Field, IntType, Struct, StructRef, Type from mojo_bindgen.parsing.diagnostics import ParserDiagnosticSink from mojo_bindgen.parsing.doc_comments import cursor_doc_comment from mojo_bindgen.parsing.lowering.type_lowering import TypeContext, TypeLowerer @@ -67,6 +68,7 @@ def _field_decl_site(self, parent_type: cx.Type, field_cursor: cx.Cursor) -> Fie attached = self._attached_inline_record_definition(field_cursor) if field_cursor.is_bitfield(): + bit_width = field_cursor.get_bitfield_width() return FieldSite( name=name, source_name=name, @@ -77,7 +79,7 @@ def _field_decl_site(self, parent_type: cx.Type, field_cursor: cx.Cursor) -> Fie is_anonymous=not bool(name), is_bitfield=True, bit_offset=max(bit_offset, 0), - bit_width=field_cursor.get_bitfield_width(), + bit_width=bit_width if bit_width is not None else 0, ) return FieldSite( @@ -199,7 +201,7 @@ def _field_bit_offset(parent_type: cx.Type, cursor: cx.Cursor | None) -> int: getter = getattr(cursor, "get_field_offsetof", None) if callable(getter): try: - return getter() + return cast(int, getter()) except Exception: return -1 return -1 @@ -251,14 +253,15 @@ def lower_top_level_record(self, cursor: cx.Cursor) -> Struct | None: ) return None - def completed_records_since(self, start: int) -> tuple[int, list[Struct | None]]: + def completed_records_since(self, start: int) -> tuple[int, list[Struct]]: """Return lowered record definitions completed after one marker index.""" decl_ids = self._completed_record_decl_ids[start:] - return len(self._completed_record_decl_ids), [ - self.registry.get(decl_id) - for decl_id in decl_ids - if self.registry.get(decl_id) is not None - ] + records: list[Struct] = [] + for decl_id in decl_ids: + record = self.registry.get(decl_id) + if record is not None: + records.append(record) + return len(self._completed_record_decl_ids), records def lower_record_definition(self, cursor: cx.Cursor) -> Struct: """Lower one complete struct/union definition exactly once.""" @@ -315,7 +318,7 @@ def _lower_field_site( is_anonymous=site.is_anonymous, is_bitfield=True, bit_offset=site.bit_offset, - bit_width=site.bit_width, + bit_width=site.bit_width if site.bit_width is not None else 0, doc=( cursor_doc_comment(site.field_cursor) if site.field_cursor is not None @@ -370,13 +373,13 @@ def _fam_pattern_for_site( record: Struct, index: int, field_count: int, - ) -> str | None: + ) -> FamPattern | None: if record.is_union or site.field_cursor is None: return None if not isinstance(field_type, Array): return None - pattern: str | None = None + pattern: FamPattern | None = None if field_type.array_kind == "flexible" and field_type.size is None: pattern = "c99_empty" elif field_type.array_kind == "fixed" and field_type.size == 0: diff --git a/mojo_bindgen/parsing/lowering/type_lowering.py b/mojo_bindgen/parsing/lowering/type_lowering.py index 005de57..527ea06 100644 --- a/mojo_bindgen/parsing/lowering/type_lowering.py +++ b/mojo_bindgen/parsing/lowering/type_lowering.py @@ -9,11 +9,13 @@ from mojo_bindgen.ir import ( Array, + ArrayKind, AtomicType, ComplexType, EnumRef, FloatType, FunctionPtr, + IntType, Param, Pointer, QualifiedType, @@ -63,7 +65,7 @@ def _safe_align(t: cx.Type) -> int | None: return max(0, t.get_align()) or None -def _array_kind(t: cx.Type, ctx: TypeContext) -> str: +def _array_kind(t: cx.Type, ctx: TypeContext) -> ArrayKind: if t.kind == cx.TypeKind.CONSTANTARRAY: return "fixed" if t.kind == cx.TypeKind.INCOMPLETEARRAY: @@ -244,7 +246,8 @@ def _lower_function_pointer_with_cursor( canonical_pointee = _normalize(pointee.get_canonical()) if canonical_pointee.kind not in (cx.TypeKind.FUNCTIONPROTO, cx.TypeKind.FUNCTIONNOPROTO): return None - return self._lower_pointer(t, ctx, source_cursor=source_cursor) + lowered = self._lower_pointer(t, ctx, source_cursor=source_cursor) + return lowered if isinstance(lowered, FunctionPtr) else None def _lower_fn_proto_parameter( self, sugared: cx.Type, canonical: cx.Type, ctx: TypeContext @@ -381,6 +384,8 @@ def _lower_enum(self, t: cx.Type) -> Type: decl = t.get_declaration() name = decl.spelling underlying = self.primitive_resolver.resolve_primitive(decl.enum_type) + if not isinstance(underlying, IntType): + underlying = None if name and underlying is not None: decl_id = self.registry.decl_id_for_cursor(decl) return EnumRef( diff --git a/pyproject.toml b/pyproject.toml index f006455..baaa424 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -69,7 +69,6 @@ ignore = ["E501", "UP007"] [tool.pyright] # `libclang` Python bindings ship without accurate stubs; typecheck the rest of the package. include = ["mojo_bindgen"] -exclude = ["mojo_bindgen/parsing"] # Align with the oldest supported checker grammar; runtime is 3.14+. pythonVersion = "3.13" typeCheckingMode = "basic" diff --git a/typings/clang/__init__.pyi b/typings/clang/__init__.pyi new file mode 100644 index 0000000..81a8a3e --- /dev/null +++ b/typings/clang/__init__.pyi @@ -0,0 +1 @@ +from . import cindex as cindex diff --git a/typings/clang/cindex.pyi b/typings/clang/cindex.pyi new file mode 100644 index 0000000..03c5c3f --- /dev/null +++ b/typings/clang/cindex.pyi @@ -0,0 +1,179 @@ +from collections.abc import Iterable, Iterator, Sequence +from typing import Any, ClassVar + + +class _NamedValue: + name: str + + +class TypeKind(_NamedValue): + INVALID: ClassVar[TypeKind] + UNEXPOSED: ClassVar[TypeKind] + VOID: ClassVar[TypeKind] + BOOL: ClassVar[TypeKind] + CHAR_U: ClassVar[TypeKind] + UCHAR: ClassVar[TypeKind] + CHAR16: ClassVar[TypeKind] + CHAR32: ClassVar[TypeKind] + USHORT: ClassVar[TypeKind] + UINT: ClassVar[TypeKind] + ULONG: ClassVar[TypeKind] + ULONGLONG: ClassVar[TypeKind] + UINT128: ClassVar[TypeKind] + CHAR_S: ClassVar[TypeKind] + SCHAR: ClassVar[TypeKind] + WCHAR: ClassVar[TypeKind] + SHORT: ClassVar[TypeKind] + INT: ClassVar[TypeKind] + LONG: ClassVar[TypeKind] + LONGLONG: ClassVar[TypeKind] + INT128: ClassVar[TypeKind] + HALF: ClassVar[TypeKind] + FLOAT: ClassVar[TypeKind] + DOUBLE: ClassVar[TypeKind] + LONGDOUBLE: ClassVar[TypeKind] + POINTER: ClassVar[TypeKind] + RECORD: ClassVar[TypeKind] + ENUM: ClassVar[TypeKind] + TYPEDEF: ClassVar[TypeKind] + CONSTANTARRAY: ClassVar[TypeKind] + INCOMPLETEARRAY: ClassVar[TypeKind] + VARIABLEARRAY: ClassVar[TypeKind] + DEPENDENTSIZEDARRAY: ClassVar[TypeKind] + FUNCTIONPROTO: ClassVar[TypeKind] + FUNCTIONNOPROTO: ClassVar[TypeKind] + ELABORATED: ClassVar[TypeKind] + COMPLEX: ClassVar[TypeKind] + VECTOR: ClassVar[TypeKind] + EXTVECTOR: ClassVar[TypeKind] + ATOMIC: ClassVar[TypeKind] + + +class CursorKind(_NamedValue): + TRANSLATION_UNIT: ClassVar[CursorKind] + FUNCTION_DECL: ClassVar[CursorKind] + STRUCT_DECL: ClassVar[CursorKind] + UNION_DECL: ClassVar[CursorKind] + ENUM_DECL: ClassVar[CursorKind] + ENUM_CONSTANT_DECL: ClassVar[CursorKind] + TYPEDEF_DECL: ClassVar[CursorKind] + VAR_DECL: ClassVar[CursorKind] + FIELD_DECL: ClassVar[CursorKind] + PARM_DECL: ClassVar[CursorKind] + MACRO_DEFINITION: ClassVar[CursorKind] + PACKED_ATTR: ClassVar[CursorKind] + ALIGNED_ATTR: ClassVar[CursorKind] + UNEXPOSED_ATTR: ClassVar[CursorKind] + + +class Token: + spelling: str + + +class File: + name: str + + +class SourceLocation: + file: File | None + line: int + column: int + + +class Diagnostic: + Note: ClassVar[int] + Warning: ClassVar[int] + Error: ClassVar[int] + Fatal: ClassVar[int] + severity: int + location: SourceLocation + spelling: str + + +class Type: + kind: TypeKind + spelling: str + element_type: Type + element_count: int + enum_type: Type + + @staticmethod + def from_result(value: Any) -> Type: ... + def get_canonical(self) -> Type: ... + def get_named_type(self) -> Type: ... + def is_const_qualified(self) -> bool: ... + def is_volatile_qualified(self) -> bool: ... + def is_restrict_qualified(self) -> bool: ... + def get_size(self) -> int: ... + def get_align(self) -> int: ... + def get_offset(self, field_name: str) -> int: ... + def get_fields(self) -> Iterator[Cursor]: ... + def get_declaration(self) -> Cursor: ... + def get_result(self) -> Type: ... + def get_pointee(self) -> Type: ... + def get_array_element_type(self) -> Type: ... + def get_array_size(self) -> int: ... + def argument_types(self) -> Iterable[Type]: ... + def is_function_variadic(self) -> bool: ... + def get_element_type(self) -> Type: ... + def get_num_elements(self) -> int: ... + def get_calling_conv(self) -> Any: ... + def get_value_type(self) -> Type: ... + + +class Cursor: + kind: CursorKind + spelling: str + type: Type + enum_type: Type + enum_value: int + underlying_typedef_type: Type + location: SourceLocation + is_macro_function_like: bool + + def is_definition(self) -> bool: ... + def get_usr(self) -> str: ... + def get_definition(self) -> Cursor | None: ... + def get_children(self) -> Iterator[Cursor]: ... + def walk_preorder(self) -> Iterator[Cursor]: ... + def get_tokens(self) -> Iterator[Token]: ... + def get_arguments(self) -> Iterator[Cursor]: ... + def is_bitfield(self) -> bool: ... + def get_bitfield_width(self) -> int | None: ... + def get_field_offsetof(self) -> int: ... + + +class TranslationUnit: + PARSE_DETAILED_PROCESSING_RECORD: ClassVar[int] + PARSE_SKIP_FUNCTION_BODIES: ClassVar[int] + PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION: ClassVar[int] + cursor: Cursor + diagnostics: Sequence[Diagnostic] + + +class TranslationUnitLoadError(Exception): ... + + +class Index: + @staticmethod + def create() -> Index: ... + def parse( + self, + path: str, + *, + args: Sequence[str] | None = ..., + unsaved_files: Sequence[tuple[str, str]] | None = ..., + options: int = ..., + ) -> TranslationUnit: ... + + +class _Conf: + lib: Any + + +conf: _Conf +c_object_p: Any +_CXString: Any + + +def register_function(lib: Any, item: tuple[str, list[Any], Any, Any], ignore_errors: bool) -> None: ... diff --git a/uv.lock b/uv.lock index e3b768c..7f53b53 100644 --- a/uv.lock +++ b/uv.lock @@ -83,7 +83,7 @@ wheels = [ [[package]] name = "mojo-bindgen" -version = "0.2.1" +version = "0.3.1" source = { editable = "." } dependencies = [ { name = "libclang" }, From 6270a085737931dc9b6de0ba6e34f1e5fbeb9d12 Mon Sep 17 00:00:00 2001 From: MoSafi2 Date: Fri, 19 Jun 2026 18:09:59 +0200 Subject: [PATCH 3/4] changed emission for owned_dl_lib to be non raising --- .../analysis/mojo/mojo_emit_options.py | 6 +- mojo_bindgen/cli.py | 2 +- mojo_bindgen/codegen/mojo_ir_printer.py | 115 +++- mojo_bindgen/codegen/normalize_mojo_module.py | 12 +- pixi.lock | 593 +++++++++--------- .../expect.emit.owned_dl_handle.mojo | 10 +- .../expect.runtime.owned_dl_handle.json | 8 +- .../expect.emit.owned_dl_handle.mojo | 4 +- .../expect.emit.owned_dl_handle.mojo | 4 +- .../expect.emit.owned_dl_handle.mojo | 4 +- .../expect.emit.owned_dl_handle.mojo | 4 +- .../expect.emit.external.mojo | 2 +- .../expect.emit.owned_dl_handle.mojo | 2 +- tests/e2e/test_e2e_runtime.py | 5 - .../expect.external.mojo | 66 +- .../globals_and_consts/expect.external.mojo | 66 +- tests/unit/test_ir_codegen_edges.py | 20 +- tests/unit/test_mojo_ir_printer.py | 25 +- 18 files changed, 552 insertions(+), 396 deletions(-) diff --git a/mojo_bindgen/analysis/mojo/mojo_emit_options.py b/mojo_bindgen/analysis/mojo/mojo_emit_options.py index ee3af30..89fa652 100644 --- a/mojo_bindgen/analysis/mojo/mojo_emit_options.py +++ b/mojo_bindgen/analysis/mojo/mojo_emit_options.py @@ -23,11 +23,11 @@ class MojoEmitOptions: linking: LinkingMode = "external_call" """external_call: link C symbols at mojo build time; emitted wrappers use ``abi("C")``. - owned_dl_handle: resolve via ``OwnedDLHandle.call`` (raises); wrappers omit ``abi("C")`` on - the ``def`` line because ``abi("C")`` combined with ``raises`` currently fails LLVM mapping.""" + owned_dl_handle: cache a dynamic library handle and resolve explicit C-ABI function pointers; + load or symbol failures abort.""" library_path_hint: str | None = None - """If set with owned_dl_handle, pass this path to OwnedDLHandle(...). If None, use DEFAULT_RTLD (symbols must be linked into the process).""" + """If set with owned_dl_handle, load this path. If None, try the link name and common shared-library names.""" module_comment: bool = True """Emit a leading comment with source header and library metadata.""" diff --git a/mojo_bindgen/cli.py b/mojo_bindgen/cli.py index a574388..738f43d 100644 --- a/mojo_bindgen/cli.py +++ b/mojo_bindgen/cli.py @@ -119,7 +119,7 @@ def run( typer.Option( "--library-path", metavar="PATH", - help="Path hint for OwnedDLHandle when --link-mode owned-dl-handle.", + help="Shared-library path to cache when --link-mode owned-dl-handle.", ), ] = None, diagnostics: Annotated[ diff --git a/mojo_bindgen/codegen/mojo_ir_printer.py b/mojo_bindgen/codegen/mojo_ir_printer.py index 8205351..587f4a6 100644 --- a/mojo_bindgen/codegen/mojo_ir_printer.py +++ b/mojo_bindgen/codegen/mojo_ir_printer.py @@ -245,39 +245,45 @@ def _render_support_decls(self, module: MojoModule) -> str: chunks.append( "struct GlobalVar[T: Copyable & ImplicitlyDestructible, //, link: StaticString]:\n" " @staticmethod\n" - " def _raw() raises -> UnsafePointer[Self.T, MutUntrackedOrigin]:\n" - " var opt: Optional[UnsafePointer[Self.T, MutUntrackedOrigin]] = _bindgen_dl().get_symbol[Self.T](StringSlice(Self.link))\n" + " def _raw() -> UnsafePointer[Self.T, MutUntrackedOrigin]:\n" + " var opt: Optional[UnsafePointer[Self.T, MutUntrackedOrigin]] = _bindgen_dylib().get_symbol[Self.T](StringSlice(Self.link))\n" " if not opt:\n" - ' raise Error(String("bindgen: missing C global symbol"))\n' + " abort(\n" + " t\"bindgen: missing C global symbol '{Self.link}' \"\n" + " t\"in dynamic library '{_BINDGEN_LIB_NAME}'\"\n" + " )\n" " return opt.value()\n" "\n" " @staticmethod\n" - " def ptr() raises -> UnsafePointer[Self.T, MutUntrackedOrigin]:\n" + " def ptr() -> UnsafePointer[Self.T, MutUntrackedOrigin]:\n" " return rebind[UnsafePointer[Self.T, MutUntrackedOrigin]](Self._raw())\n" "\n" " @staticmethod\n" - " def load() raises -> Self.T:\n" + " def load() -> Self.T:\n" " return Self._raw()[].copy()\n" "\n" " @staticmethod\n" - " def store(value: Self.T) raises -> None:\n" + " def store(value: Self.T) -> None:\n" " var p = rebind[UnsafePointer[Self.T, MutUntrackedOrigin]](Self._raw())\n" " p[] = value.copy()\n" "\n" "struct GlobalConst[T: Copyable & ImplicitlyDestructible, //, link: StaticString]:\n" " @staticmethod\n" - " def _raw() raises -> UnsafePointer[Self.T, MutUntrackedOrigin]:\n" - " var opt: Optional[UnsafePointer[Self.T, MutUntrackedOrigin]] = _bindgen_dl().get_symbol[Self.T](StringSlice(Self.link))\n" + " def _raw() -> UnsafePointer[Self.T, MutUntrackedOrigin]:\n" + " var opt: Optional[UnsafePointer[Self.T, MutUntrackedOrigin]] = _bindgen_dylib().get_symbol[Self.T](StringSlice(Self.link))\n" " if not opt:\n" - ' raise Error(String("bindgen: missing C global symbol"))\n' + " abort(\n" + " t\"bindgen: missing C global symbol '{Self.link}' \"\n" + " t\"in dynamic library '{_BINDGEN_LIB_NAME}'\"\n" + " )\n" " return opt.value()\n" "\n" " @staticmethod\n" - " def ptr() raises -> UnsafePointer[Self.T, ImmutUntrackedOrigin]:\n" + " def ptr() -> UnsafePointer[Self.T, ImmutUntrackedOrigin]:\n" " return rebind[UnsafePointer[Self.T, ImmutUntrackedOrigin]](Self._raw())\n" "\n" " @staticmethod\n" - " def load() raises -> Self.T:\n" + " def load() -> Self.T:\n" " return Self._raw()[].copy()" ) else: @@ -286,18 +292,76 @@ def _render_support_decls(self, module: MojoModule) -> str: @staticmethod def _render_dl_handle_helper(module: MojoModule) -> str: + library_lit = _escape_mojo_string(module.library) + link_lit = _escape_mojo_string(module.link_name) + if module.link_mode == LinkMode.EXTERNAL_CALL: + return ( + f'comptime _BINDGEN_LIB_NAME = "{library_lit}"\n' + f'comptime _BINDGEN_LINK_NAME = "{link_lit}"\n' + "\n" + "def _bindgen_init_dylib() -> OwnedDLHandle:\n" + " try:\n" + " return OwnedDLHandle(DEFAULT_RTLD)\n" + " except e:\n" + ' abort(t"bindgen: failed to open process dynamic symbol table: {e}")\n' + "\n" + 'comptime _BINDGEN_DYLIB = _Global["mojo_bindgen/' + f'{library_lit}", _bindgen_init_dylib]\n' + "\n" + MojoIRPrinter._render_cached_dl_helpers() + ) if module.link_mode == LinkMode.OWNED_DL_HANDLE and module.library_path_hint is not None: - path_lit = module.library_path_hint.replace("\\", "\\\\").replace('"', '\\"') + path_lit = _escape_mojo_string(module.library_path_hint) return ( + f'comptime _BINDGEN_LIB_NAME = "{library_lit}"\n' + f'comptime _BINDGEN_LINK_NAME = "{link_lit}"\n' f'comptime _BINDGEN_LIB_PATH: String = "{path_lit}"\n' "\n" - "def _bindgen_dl() raises -> OwnedDLHandle:\n" - " return OwnedDLHandle(_BINDGEN_LIB_PATH)" + "def _bindgen_init_dylib() -> OwnedDLHandle:\n" + " return _find_dylib[_BINDGEN_LIB_NAME](_BINDGEN_LIB_PATH)\n" + "\n" + 'comptime _BINDGEN_DYLIB = _Global["mojo_bindgen/' + f'{library_lit}", _bindgen_init_dylib]\n' + "\n" + MojoIRPrinter._render_cached_dl_helpers() ) return ( - "# Resolve symbols from libraries already linked into this process.\n" - "def _bindgen_dl() raises -> OwnedDLHandle:\n" - " return OwnedDLHandle(DEFAULT_RTLD)" + f'comptime _BINDGEN_LIB_NAME = "{library_lit}"\n' + f'comptime _BINDGEN_LINK_NAME = "{link_lit}"\n' + "\n" + "def _bindgen_init_dylib() -> OwnedDLHandle:\n" + " return _find_dylib[_BINDGEN_LIB_NAME](\n" + " _BINDGEN_LINK_NAME,\n" + ' "lib" + String(_BINDGEN_LINK_NAME) + ".so",\n' + ' "lib" + String(_BINDGEN_LINK_NAME) + ".dylib",\n' + " )\n" + "\n" + 'comptime _BINDGEN_DYLIB = _Global["mojo_bindgen/' + f'{library_lit}", _bindgen_init_dylib]\n' + "\n" + MojoIRPrinter._render_cached_dl_helpers() + ) + + @staticmethod + def _render_cached_dl_helpers() -> str: + return ( + "# Returns a borrowed process-lifetime dynamic library handle; do not close it.\n" + "def _bindgen_dylib() -> _DLHandle:\n" + " var dylib_ptr = _get_global[\n" + " _BINDGEN_DYLIB.name,\n" + " _BINDGEN_DYLIB._init_wrapper,\n" + " _BINDGEN_DYLIB._deinit_wrapper,\n" + " ]()\n" + " var dylib = unsafe_cast[Type=_BINDGEN_DYLIB.StorageType](dylib_ptr).value()[].borrow()\n" + " if not dylib:\n" + " abort(t\"bindgen: failed to load dynamic library '{_BINDGEN_LIB_NAME}'\")\n" + " return dylib\n" + "\n" + "def _bindgen_function[Fn: TrivialRegisterPassable](symbol: StringSlice) -> Fn:\n" + " var fn_ptr = _bindgen_dylib().get_symbol[NoneType](symbol)\n" + " if not fn_ptr:\n" + " abort(\n" + " t\"bindgen: missing C function symbol '{symbol}' \"\n" + " t\"in dynamic library '{_BINDGEN_LIB_NAME}'\"\n" + " )\n" + " return UnsafePointer(to=fn_ptr.value()).bitcast[Fn]()[]" ) def _render_decl(self, decl: MojoDecl) -> str: @@ -619,9 +683,11 @@ def _render_function_decl(self, decl: FunctionDecl) -> str: params_text = ", ".join(params) return_type = self._render_type(decl.return_type) symbol = self._link_symbol(decl.call_target, decl.link_name) + symbol_lit = _escape_mojo_string(symbol) bracket_inner = ", ".join( [f'"{symbol}"', return_type] + [self._render_type(param.type) for param in decl.params] ) + fn_type = self._render_c_abi_function_pointer_type(decl) call_args = ", ".join( self._render_param_name(param.name, i) for i, param in enumerate(decl.params) ) @@ -655,18 +721,25 @@ def _render_function_decl(self, decl: FunctionDecl) -> str: b.add(f"return external_call[{bracket_inner}]({call_args})") else: if return_type == "NoneType": - b.add(f"def {decl.name}({params_text}) raises -> None:") + b.add(f"def {decl.name}({params_text}) -> None:") b.indent() self._render_docstring(b, decl.doc) - b.add(f"_bindgen_dl().call[{bracket_inner}]({call_args})") + b.add(f'var fn_ = _bindgen_function[{fn_type}](StringSlice("{symbol_lit}"))') + b.add(f"fn_({call_args})") else: - b.add(f"def {decl.name}({params_text}) raises -> {return_type}:") + b.add(f"def {decl.name}({params_text}) -> {return_type}:") b.indent() self._render_docstring(b, decl.doc) - b.add(f"return _bindgen_dl().call[{bracket_inner}]({call_args})") + b.add(f'var fn_ = _bindgen_function[{fn_type}](StringSlice("{symbol_lit}"))') + b.add(f"return fn_({call_args})") b.dedent() return b.render() + def _render_c_abi_function_pointer_type(self, decl: FunctionDecl) -> str: + params = ", ".join(self._render_type(param.type) for param in decl.params) + return_type = self._render_type(decl.return_type) + return f'def({params}) thin abi("C") -> {return_type}' + def _render_global_decl(self, decl: GlobalDecl) -> str: b = CodeBuilder() b.extend(self._doc_comment_lines(decl.doc)) diff --git a/mojo_bindgen/codegen/normalize_mojo_module.py b/mojo_bindgen/codegen/normalize_mojo_module.py index 1d8acf3..1a561dd 100644 --- a/mojo_bindgen/codegen/normalize_mojo_module.py +++ b/mojo_bindgen/codegen/normalize_mojo_module.py @@ -377,7 +377,14 @@ def _collect_dependencies(self, decls: list[MojoDecl]) -> ModuleDependencies: self._record_support_decl(SupportDeclKind.DL_HANDLE_HELPERS) if SupportDeclKind.DL_HANDLE_HELPERS in self._support_decl_kinds: - self._record_import("std.ffi", "DEFAULT_RTLD", "OwnedDLHandle") + ffi_imports = ["OwnedDLHandle", "_DLHandle", "_Global", "_get_global"] + if self._module.link_mode == LinkMode.EXTERNAL_CALL: + ffi_imports.append("DEFAULT_RTLD") + else: + ffi_imports.append("_find_dylib") + self._record_import("std.ffi", *ffi_imports) + self._record_import("std.memory.unsafe_pointer", "unsafe_cast") + self._record_import("std.os", "abort") for decl in decls: if isinstance(decl, FunctionDecl) and decl.kind == FunctionKind.WRAPPER: @@ -407,6 +414,9 @@ def _ordered_imports(self) -> list[ModuleImport]: ordered_ffi.append("DEFAULT_RTLD") if "OwnedDLHandle" in ffi_names: ordered_ffi.append("OwnedDLHandle") + for private_name in ("_DLHandle", "_Global", "_find_dylib", "_get_global"): + if private_name in ffi_names: + ordered_ffi.append(private_name) if "UnsafeUnion" in ffi_names: ordered_ffi.append("UnsafeUnion") ordered_ffi.extend(sorted(name for name in ffi_names if name.startswith("c_"))) diff --git a/pixi.lock b/pixi.lock index 02027f3..3f2b4d2 100644 --- a/pixi.lock +++ b/pixi.lock @@ -17,11 +17,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py314h4a8dc5f_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py314h42812f9_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.21-py314h42812f9_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-15.2.0-ha6850e4_19.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-hbde042b_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda @@ -29,7 +29,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.1-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.1-hecca717_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_19.conda @@ -39,48 +39,48 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-15.2.0-h90f66d4_19.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.22-h280c20c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.2-h0c1763c_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_19.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42.1-h5347b49_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42.2-h5347b49_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.52.1-h280c20c_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/nodejs-25.8.2-he4ff34a_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.3-h35e630c_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py314h0f05182_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.5-habeac84_100_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.6-habeac84_100_cp314.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py314h67df5f8_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py312hda471dd_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py314h2e6c369_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/rust-1.95.0-h53717f1_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-2026.5.1-py314h1bee95f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/rust-1.96.0-h53717f1_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py314h5bd0f2a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.7-py314h5bd0f2a_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h09e67af_11.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-doc-0.0.4-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.14.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.5.0-py314h680f03e_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.6.0-py314h680f03e_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.15.0-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.4.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.4.0-hac0b51c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.6.17-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.5.20-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.6.17-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.4.1-pyhc90fa1f_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.3-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.5-py314hd8ed1ab_100.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.6-py314hd8ed1ab_100.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.3.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda @@ -92,11 +92,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.28.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.15-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.18-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-9.0.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.1.0-pyha191276_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.13.0-pyh53cf698_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.14.1-pyh53cf698_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipywidgets-8.1.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda @@ -108,14 +107,15 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-1.1.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-builder-1.0.2-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_console-6.6.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.18.2-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.20.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.16-pyhcf101f3_1.conda @@ -128,11 +128,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.11.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-7.5.6-pyhcf101f3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-7.6.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda @@ -140,8 +140,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.7-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh145f28c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.1.2-pyh145f28c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.10.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.52-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.52-hd8ed1ab_0.conda @@ -152,8 +152,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.5-h4df99d1_100.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efcf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.6-h4df99d1_100.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-4.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda @@ -162,9 +162,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rich-15.0.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/rust-std-x86_64-unknown-linux-gnu-1.95.0-h2c6d0dc_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/rust-std-x86_64-unknown-linux-gnu-1.96.0-h2c6d0dc_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyha191276_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda @@ -174,7 +173,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typer-0.25.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda @@ -182,7 +181,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.7.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.7.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.8.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda @@ -194,14 +193,14 @@ environments: - conda: https://conda.modular.com/max/noarch/mojo-python-1.0.0b2-release.conda - pypi: . - pypi: https://files.pythonhosted.org/packages/0d/fe/6bea5c9162869c5beba5d9c8abbed835ec85bf1ec1fba05a3822325c45f3/build-1.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/16/6b/330d8ebae582b30c2959a1ef4c3bc344ebde48c2ff0c3f113c4710735e11/pyright-1.1.409-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/1d/fc/716c1e62e512ef1c160e7984a73a5fc7df45166f2ff3f254e71c58076f7c/libclang-18.1.1-py2.py3-none-manylinux2010_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/1e/c0/56472c251d09858a53e51efbd485b09e1995d8731668b76d52e5dd6ee0f1/ruff-0.15.14-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/6d/ff/d353d6b7bbd73cc0ec37f4463d7540e45e894338abdd9964eee0de332708/ruff-0.15.18-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d7/33/288b5868fa00846dacf249633719d747893e54aebd196b9968ac1878a5d3/pyright-1.1.410-py3-none-any.whl install: channels: - url: https://conda.modular.com/max/ @@ -213,34 +212,34 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-hbde042b_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.1-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.1-hecca717_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_19.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.22-h280c20c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.2-h0c1763c_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_19.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42.1-h5347b49_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42.2-h5347b49_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.5-habeac84_100_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.3-h35e630c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.6-habeac84_100_cp314.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py312hda471dd_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py314h5bd0f2a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.7-py314h5bd0f2a_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h09e67af_11.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-doc-0.0.4-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.6.17-hbd8a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.4.1-pyhc90fa1f_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.5-py314hd8ed1ab_100.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.6-py314hd8ed1ab_100.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-9.0.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda @@ -249,17 +248,17 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh145f28c_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.1.2-pyh145f28c_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.10.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.5-h4df99d1_100.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.6-h4df99d1_100.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rich-15.0.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typer-0.25.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda @@ -369,9 +368,9 @@ packages: - pkg:pypi/cffi?source=hash-mapping size: 300271 timestamp: 1761203085220 -- conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py314h42812f9_0.conda - sha256: d9e89e351d7189c41615cfceca76b3bcacaa9c81d9945ac1caa6fb9e5184f610 - md5: 57e6fad901c05754d5256fe3ab9f277b +- conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.21-py314h42812f9_0.conda + sha256: c16696b23e1d75b6eea7d0c8b9c31c03d1987eeb61852f09b6d4042ca015acd3 + md5: a7eb8029c4fe320c0179085707017c2d depends: - python - libgcc >=14 @@ -382,8 +381,8 @@ packages: license_family: MIT purls: - pkg:pypi/debugpy?source=hash-mapping - size: 2886804 - timestamp: 1769744977998 + size: 2842115 + timestamp: 1780390153580 - conda: https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-15.2.0-ha6850e4_19.conda sha256: 2c0b2870210cfc7e8561676844f4bd3884b345c19100e1da84cbfb4994d8f104 md5: 1c2eddf7501ef92050d3fbb11df61ee3 @@ -423,9 +422,9 @@ packages: purls: [] size: 134088 timestamp: 1754905959823 -- conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda - sha256: 3e307628ca3527448dd1cb14ad7bb9d04d1d28c7d4c5f97ba196ae984571dd25 - md5: fb53fb07ce46a575c5d004bbc96032c2 +- conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-hbde042b_1.conda + sha256: 9b07046870772f28740e3f6149f09ff222843733087a33c5540b169c6289652d + md5: 54157a1c8c0bb70f62dd0b17fba7e7f2 depends: - __glibc >=2.17,<3.0.a0 - keyutils >=1.6.3,<2.0a0 @@ -433,12 +432,12 @@ packages: - libedit >=3.1.20250104,<4.0a0 - libgcc >=14 - libstdcxx >=14 - - openssl >=3.5.5,<4.0a0 + - openssl >=3.5.7,<4.0a0 license: MIT license_family: MIT purls: [] - size: 1386730 - timestamp: 1769769569681 + size: 1388990 + timestamp: 1781859420533 - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda sha256: 3d584956604909ff5df353767f3a2a2f60e07d070b328d109f30ac40cd62df6c md5: 18335a698559cdbcd86150a48bf54ba6 @@ -525,9 +524,9 @@ packages: purls: [] size: 112766 timestamp: 1702146165126 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.1-hecca717_0.conda - sha256: 363018b25fdb5534c79783d912bd4b685a3547f4fc5996357ad548899b0ee8e7 - md5: 93764a5ca80616e9c10106cdaec92f74 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.1-hecca717_1.conda + sha256: 16feffd9ddbbe5b718515d38ee376c685ba95491cd901244e24671d20b952a77 + md5: b24d3c612f71e7aa74158d92106318b2 depends: - __glibc >=2.17,<3.0.a0 - libgcc >=14 @@ -536,8 +535,8 @@ packages: license: MIT license_family: MIT purls: [] - size: 77294 - timestamp: 1779278686680 + size: 77856 + timestamp: 1781203599810 - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda sha256: 31f19b6a88ce40ebc0d5a992c131f57d919f73c0b92cd1617a5bec83f6e961e6 md5: a360c33a5abe61c07959e449fa1453eb @@ -645,17 +644,17 @@ packages: purls: [] size: 269272 timestamp: 1779163468406 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda - sha256: 54cdcd3214313b62c2a8ee277e6f42150d9b748264c1b70d958bf735e420ef8d - md5: 7dc38adcbf71e6b38748e919e16e0dce +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.2-h0c1763c_0.conda + sha256: 1ab603b6ec93933e76027e1f23b21b22b858ba1b56f1e1695ef6fe5e80cb7358 + md5: 062b0ac602fb0adf250e3dfa86f221c4 depends: - __glibc >=2.17,<3.0.a0 - libgcc >=14 - libzlib >=1.3.2,<2.0a0 license: blessing purls: [] - size: 954962 - timestamp: 1777986471789 + size: 957849 + timestamp: 1780574429573 - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_19.conda sha256: dff1058c76ec6b8759e41cefa2508162d00e4a5e6721aa68ec3fd10094e702dc md5: 5794b3bdc38177caf969dabd3af08549 @@ -669,17 +668,17 @@ packages: purls: [] size: 5852044 timestamp: 1778269036376 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42.1-h5347b49_0.conda - sha256: 3f0edf1280e2f6684a986f821eaa3e123d2694a00b31b96ca0d4a4c12c129231 - md5: 7d0a66598195ef00b6efc55aefc7453b +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42.2-h5347b49_0.conda + sha256: 9b1bdce27a7e31f7d241aeecff67a1f3101d52a2b1e33ccc2cdf2613072bf81f + md5: 01bb81d12c957de066ea7362007df642 depends: - - __glibc >=2.17,<3.0.a0 - libgcc >=14 + - __glibc >=2.17,<3.0.a0 license: BSD-3-Clause license_family: BSD purls: [] - size: 40163 - timestamp: 1779118517630 + size: 40017 + timestamp: 1781625522462 - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.52.1-h280c20c_0.conda sha256: e28e4519223f78b3163599ca89c3f2d80bfb53e907e7fc74e806e60d1efa578b md5: 4e33d49bf4fc853855a3b00643aa5484 @@ -754,9 +753,9 @@ packages: purls: [] size: 18829340 timestamp: 1774514313036 -- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda - sha256: c0ef482280e38c71a08ad6d71448194b719630345b0c9c60744a2010e8a8e0cb - md5: da1b85b6a87e141f5140bb9924cecab0 +- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.3-h35e630c_0.conda + sha256: d48f5c22b9897c01e4dff3680f1f57ceb02711ab9c62f74339b080419dfad34b + md5: 79dd2074b5cd5c5c6b2930514a11e22d depends: - __glibc >=2.17,<3.0.a0 - ca-certificates @@ -764,8 +763,8 @@ packages: license: Apache-2.0 license_family: Apache purls: [] - size: 3167099 - timestamp: 1775587756857 + size: 3159683 + timestamp: 1781069855778 - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py314h0f05182_0.conda sha256: f15574ed6c8c8ed8c15a0c5a00102b1efe8b867c0bd286b498cd98d95bd69ae5 md5: 4f225a966cfee267a79c5cb6382bd121 @@ -780,24 +779,24 @@ packages: - pkg:pypi/psutil?source=hash-mapping size: 231303 timestamp: 1769678156552 -- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.5-habeac84_100_cp314.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.6-habeac84_100_cp314.conda build_number: 100 - sha256: 55eed9bf2a3f6e90311276f0834737fe7c2d9ec3e5e2e557507858df4c7521e6 - md5: da92e59ff92f2d5ede4f612af20f583f + sha256: 6d28ac2b061179deb434d3d57afa98ffd20ec3c5d44ab8048a1ca33424b22d38 + md5: 0b9b2f83b5b600e1ac38becde8d0dd44 depends: - __glibc >=2.17,<3.0.a0 - bzip2 >=1.0.8,<2.0a0 - ld_impl_linux-64 >=2.36.1 - - libexpat >=2.8.0,<3.0a0 + - libexpat >=2.8.1,<3.0a0 - libffi >=3.5.2,<3.6.0a0 - libgcc >=14 - liblzma >=5.8.3,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.53.1,<4.0a0 + - libsqlite >=3.53.2,<4.0a0 - libuuid >=2.42.1,<3.0a0 - libzlib >=1.3.2,<2.0a0 - ncurses >=6.6,<7.0a0 - - openssl >=3.5.6,<4.0a0 + - openssl >=3.5.7,<4.0a0 - python_abi 3.14.* *_cp314 - readline >=8.3,<9.0a0 - tk >=8.6.13,<8.7.0a0 @@ -805,8 +804,8 @@ packages: - zstd >=1.5.7,<1.6.0a0 license: Python-2.0 purls: [] - size: 36745188 - timestamp: 1779236923603 + size: 36717183 + timestamp: 1781255094700 python_site_packages_path: lib/python3.14/site-packages - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py314h67df5f8_1.conda sha256: b318fb070c7a1f89980ef124b80a0b5ccf3928143708a85e0053cde0169c699d @@ -853,37 +852,37 @@ packages: purls: [] size: 345073 timestamp: 1765813471974 -- conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py314h2e6c369_0.conda - sha256: e53b0cbf3b324eaa03ca1fe1a688fdf4ab42cea9c25270b0a7307d8aaaa4f446 - md5: c1c368b5437b0d1a68f372ccf01cb133 +- conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-2026.5.1-py314h1bee95f_0.conda + sha256: 79d753848377c415578f42285f5f87be711503b887c99e8890fd51d3fae1d6a5 + md5: fb5b4fc759b225d4f32730cc8380ec8e depends: - python - - libgcc >=14 - __glibc >=2.17,<3.0.a0 + - libgcc >=14 - python_abi 3.14.* *_cp314 constrains: - __glibc >=2.17 license: MIT license_family: MIT purls: - - pkg:pypi/rpds-py?source=hash-mapping - size: 376121 - timestamp: 1764543122774 -- conda: https://conda.anaconda.org/conda-forge/linux-64/rust-1.95.0-h53717f1_1.conda - sha256: 0f7965acec00e5b35d7b4748ea0da57249ab3db2177d13eb87909c0a142148b5 - md5: 26172b61a3f03c31e56065413ffc1f2f + - pkg:pypi/rpds-py?source=compressed-mapping + size: 309696 + timestamp: 1779976994059 +- conda: https://conda.anaconda.org/conda-forge/linux-64/rust-1.96.0-h53717f1_0.conda + sha256: d084a53a1ce2cea8d6f9cf45108e516a629118dd3f8fb3113d87d1dcd3eea669 + md5: 5b80270d422d9fddf028cb4ce68370b2 depends: - __glibc >=2.17,<3.0.a0 - gcc_impl_linux-64 - libgcc >=14 - libzlib >=1.3.2,<2.0a0 - - rust-std-x86_64-unknown-linux-gnu 1.95.0 h2c6d0dc_1 + - rust-std-x86_64-unknown-linux-gnu 1.96.0 h2c6d0dc_0 - sysroot_linux-64 >=2.17 license: MIT license_family: MIT purls: [] - size: 182907915 - timestamp: 1777536012536 + size: 171986391 + timestamp: 1780046427552 - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda sha256: cafeec44494f842ffeca27e9c8b0c27ed714f93ac77ddadc6aaf726b5554ebac md5: cffd3bdd58090148f4cfcd831f4b26ab @@ -898,9 +897,9 @@ packages: purls: [] size: 3301196 timestamp: 1769460227866 -- conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py314h5bd0f2a_0.conda - sha256: ed8d06093ff530a2dae9ed1e51eb6f908fbfd171e8b62f4eae782d67b420be5a - md5: dc1ff1e915ab35a06b6fa61efae73ab5 +- conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.7-py314h5bd0f2a_0.conda + sha256: bbb7056f7c5fd606df16ed73ee68687050de2c02fd69a3f69a1cb533a7ed2ae8 + md5: 4a8e5889712641aabdf6695e292857fe depends: - __glibc >=2.17,<3.0.a0 - libgcc >=14 @@ -910,8 +909,8 @@ packages: license_family: Apache purls: - pkg:pypi/tornado?source=hash-mapping - size: 912476 - timestamp: 1774358032579 + size: 918368 + timestamp: 1781006801436 - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda sha256: 6d9ea2f731e284e9316d95fa61869fe7bbba33df7929f82693c121022810f4ad md5: a77f85f77be52ff59391544bfe73390a @@ -971,9 +970,9 @@ packages: - pkg:pypi/annotated-doc?source=hash-mapping size: 14222 timestamp: 1762868213144 -- conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda - sha256: f09aed24661cd45ba54a43772504f05c0698248734f9ae8cd289d314ac89707e - md5: af2df4b9108808da3dc76710fe50eae2 +- conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.14.0-pyhcf101f3_0.conda + sha256: dc9c18c3766f82d88dbe6b25d25580e14fcc94d3c84524f610b713c2a72dd038 + md5: e679dcf15f30bf6e3f1bb3ba69bcf29c depends: - exceptiongroup >=1.0.2 - idna >=2.8 @@ -987,9 +986,9 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/anyio?source=hash-mapping - size: 146764 - timestamp: 1774359453364 + - pkg:pypi/anyio?source=compressed-mapping + size: 161074 + timestamp: 1781616881402 - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda sha256: bea62005badcb98b1ae1796ec5d70ea0fc9539e7d59708ac4e7d41e2f4bb0bad md5: 8ac12aff0860280ee0cff7fa2cf63f3b @@ -1071,20 +1070,20 @@ packages: - pkg:pypi/babel?source=hash-mapping size: 7684321 timestamp: 1772555330347 -- conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.5.0-py314h680f03e_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.6.0-py314h680f03e_0.conda noarch: generic - sha256: a1c97297e867776760489537bc5ae36fa83a154be30e3b79385a39ca4cb058fe - md5: 1133126d840e75287d83947be3fc3e71 + sha256: 709cac7434d1c5a8828105036212a2a36022a07d807e89e2e99cac939c2d2526 + md5: 40d89d8546ad6e139e73ec8f6d56068b depends: - python >=3.14 license: BSD-3-Clause AND MIT AND EPL-2.0 purls: - pkg:pypi/backports-zstd?source=compressed-mapping - size: 7533 - timestamp: 1778594057496 -- conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda - sha256: bf1e71c3c0a5b024e44ff928225a0874fc3c3356ec1a0b6fe719108e6d1288f6 - md5: 5267bef8efea4127aacd1f4e1f149b6e + size: 7526 + timestamp: 1781450817767 +- conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.15.0-pyha770c72_0.conda + sha256: aed4b9dcf68ec2a75e5645fed14d77fd884d38d2e52bfa6ef4b278d90cd88781 + md5: 3b261da3fe9b4168738712832410b022 depends: - python >=3.10 - soupsieve >=1.2 @@ -1092,12 +1091,12 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/beautifulsoup4?source=hash-mapping - size: 90399 - timestamp: 1764520638652 -- conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda - sha256: f8ff1f98423674278964a46c93a1766f9e91960d44efd91c6c3ed56a33813f46 - md5: 7c5ebdc286220e8021bf55e6384acd67 + - pkg:pypi/beautifulsoup4?source=compressed-mapping + size: 92704 + timestamp: 1780853175566 +- conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.4.0-pyhcf101f3_0.conda + sha256: 0c786f3e571bd58ac73d730d06314716663884d848ae320de0b438fae5e0bea9 + md5: 93009c29cdd6f2500468f2502fff9209 depends: - python >=3.10 - webencodings @@ -1106,28 +1105,28 @@ packages: - tinycss2 >=1.1.0,<1.5 license: Apache-2.0 AND MIT purls: - - pkg:pypi/bleach?source=hash-mapping - size: 142008 - timestamp: 1770719370680 -- conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda - sha256: 7c07a865e5e4cca233cc4e0eb3f0f5ff6c90776461687b4fb0b1764133e1fd61 - md5: f11a319b9700b203aa14c295858782b6 + - pkg:pypi/bleach?source=compressed-mapping + size: 142246 + timestamp: 1780675823953 +- conda: https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.4.0-hac0b51c_0.conda + sha256: ede77e412304cd080e23967352a7904932207d0167ecdccd6a9e210530942be6 + md5: 5f710eab1f3c4e773c75686f5e8e6481 depends: - - bleach ==6.3.0 pyhcf101f3_1 + - bleach ==6.4.0 pyhcf101f3_0 - tinycss2 license: Apache-2.0 AND MIT purls: [] - size: 4409 - timestamp: 1770719370682 -- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda - sha256: 9812a303a1395e1dafbd92e5bc8a1ff6013bcbba0a09c7f03a8d23e43560aa9b - md5: 489b8e97e666c93f68fdb35c3c9b957f + size: 4406 + timestamp: 1780675823953 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.6.17-hbd8a1cb_0.conda + sha256: f8e3c730fa14ee3f170493779f06522c4acf89169f43db4f039727709b6419cf + md5: a9965dd99f683c5f444428f896635716 depends: - __unix license: ISC purls: [] - size: 129868 - timestamp: 1779289852439 + size: 128866 + timestamp: 1781708962055 - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 noarch: python sha256: 561e6660f26c35d137ee150187d89767c988413c978e1b712d53f27ddf70ea17 @@ -1150,16 +1149,16 @@ packages: - pkg:pypi/cached-property?source=hash-mapping size: 11065 timestamp: 1615209567874 -- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.5.20-pyhd8ed1ab_0.conda - sha256: 645655a3510e38e625da136595f3f16f2130c3263630cc3bc8f60f619ddbe490 - md5: 9fefff2f745ea1cc2ef15211a20c054a +- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.6.17-pyhd8ed1ab_0.conda + sha256: 6c13620e458ba43278379d0cdacc30c497336bddfda81681fd50d114a65c702f + md5: c13824fedced67005d3832c152fe9c2f depends: - python >=3.10 license: ISC purls: - pkg:pypi/certifi?source=compressed-mapping - size: 134201 - timestamp: 1779285131141 + size: 133877 + timestamp: 1781719949728 - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda sha256: 3f9483d62ce24ecd063f8a5a714448445dc8d9e201147c46699fc0033e824457 md5: a9167b9571f3baa9d448faa2139d1089 @@ -1179,6 +1178,7 @@ packages: - python - python >=3.10 license: BSD-3-Clause + license_family: BSD purls: - pkg:pypi/click?source=compressed-mapping size: 104999 @@ -1195,17 +1195,17 @@ packages: - pkg:pypi/comm?source=hash-mapping size: 14690 timestamp: 1753453984907 -- conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.5-py314hd8ed1ab_100.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.6-py314hd8ed1ab_100.conda noarch: generic - sha256: 777882d2685f368417f31bbe1b28f73687fc6c8f6a5768bda20ffeefa6b07f5b - md5: a749029ce5d0632a913db19d17f944ab + sha256: 7a548856ef5307890a8cadfc196655117658f8c24589ce175caa4c1c2ded9d13 + md5: b28fe35fd43d5f425c0dccbe5b5039fd depends: - python >=3.14,<3.15.0a0 - python_abi * *_cp314 license: Python-2.0 purls: [] - size: 50212 - timestamp: 1779236682725 + size: 49333 + timestamp: 1781254618863 - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.3.1-pyhd8ed1ab_0.conda sha256: 430bd9d731b265f0bedb3183ac3ecfaa1656390c092b6e864ff8cc1229843c8c md5: 61dcf784d59ef0bd62c57d982b154ace @@ -1343,9 +1343,9 @@ packages: - pkg:pypi/hyperframe?source=hash-mapping size: 17397 timestamp: 1737618427549 -- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.15-pyhcf101f3_0.conda - sha256: 3d25f9f6f7ab3e1ce6429fc8c8aae0335cf446692e715068488536d220cc43de - md5: 1b9083b7f00609605d1483dbc6071a81 +- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.18-pyhcf101f3_0.conda + sha256: c75632ea624aa450a394f570749420c5a2e0997d0216bc29d5d45b0f39df0426 + md5: 577b04680ae422adb86fc60d7b940659 depends: - python >=3.10 - python @@ -1353,8 +1353,8 @@ packages: license_family: BSD purls: - pkg:pypi/idna?source=compressed-mapping - size: 62642 - timestamp: 1779294335905 + size: 163869 + timestamp: 1781620148226 - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-9.0.0-pyhcf101f3_0.conda sha256: 43e2a5497cad1598ff88a3e69f69bc88b7b8f141fa63c60eab5db296317318b8 md5: ffc17e785d64e12fc311af9184221839 @@ -1363,24 +1363,11 @@ packages: - zipp >=3.20 - python license: Apache-2.0 + license_family: APACHE purls: - pkg:pypi/importlib-metadata?source=compressed-mapping size: 34766 timestamp: 1779714582554 -- conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda - sha256: a563a51aa522998172838e867e6dedcf630bc45796e8612f5a1f6d73e9c8125a - md5: 0ba6225c279baf7ea9473a62ea0ec9ae - depends: - - python >=3.10 - - zipp >=3.1.0 - constrains: - - importlib-resources >=7.1.0,<7.1.1.0a0 - license: Apache-2.0 - license_family: APACHE - purls: - - pkg:pypi/importlib-resources?source=hash-mapping - size: 34809 - timestamp: 1776068839274 - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.1.0-pyha191276_0.conda sha256: a9d6b74115dbd62e19017ff8fa4885b07b5164427f262cc15b5307e5aaf3ee73 md5: c6f63cfe66adaa5650788e3106b6683a @@ -1409,9 +1396,9 @@ packages: - pkg:pypi/ipykernel?source=hash-mapping size: 133820 timestamp: 1761567932044 -- conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.13.0-pyh53cf698_0.conda - sha256: a0af49948a1842dfd15a0b0b2fd56c94ddbd07e07a6c8b4bc70d43015eafaff0 - md5: 73e9657cd19605740d21efb14d8d0cb9 +- conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.14.1-pyh53cf698_0.conda + sha256: a3f76e06c31bcf1bda0f633d5c9f1c834286b4f6decc6626067a6cffee283318 + md5: fbd58549b374103c1a80577f09a328ef depends: - __unix - decorator >=5.1.0 @@ -1431,8 +1418,8 @@ packages: license_family: BSD purls: - pkg:pypi/ipython?source=hash-mapping - size: 651632 - timestamp: 1777038396606 + size: 652893 + timestamp: 1780654403616 - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda sha256: 894682a42a7d659ae12878dbcb274516a7031bbea9104e92f8e88c1f2765a104 md5: bd80ba060603cc228d9d81c257093119 @@ -1585,6 +1572,22 @@ packages: - pkg:pypi/jupyter?source=hash-mapping size: 8891 timestamp: 1733818677113 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-builder-1.0.2-pyhcf101f3_0.conda + sha256: a845bffdbcdd1749dd4a46e47be5d4e0e1c87cdda547e3a87d297a6963ab0821 + md5: 12b0a9513f6abaa944c313c4a01d5500 + depends: + - jupyter_core + - python >=3.10 + - tomli + - traitlets + - python + constrains: + - nodejs >=22 + license: BSD-3-Clause AND MIT AND ISC + purls: + - pkg:pypi/jupyter-builder?source=hash-mapping + size: 858738 + timestamp: 1781271993460 - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.3.1-pyhcf101f3_0.conda sha256: 3766e2ae59641c172cec8a821528bfa6bf9543ffaaeb8b358bfd5259dcf18e4e md5: 0c3b465ceee138b9c39279cc02e5c4a0 @@ -1673,9 +1676,9 @@ packages: - pkg:pypi/jupyter-events?source=hash-mapping size: 24002 timestamp: 1776861872237 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.18.2-pyhcf101f3_0.conda - sha256: 04fb8ea7749f67abaf76df6257bf86688e1389ceed55eb4fb0176fd2e882dbd6 - md5: 5ee7945accf0f215ddd6055d25d7cd83 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.20.0-pyhcf101f3_0.conda + sha256: 3e8759fdc404f149e7e722e0af472044a0ef9e70d0a3a7690ddcfe1232a0e868 + md5: b2ddb0e13b5600070c4019c4db8a78e6 depends: - anyio >=3.1.0 - argon2-cffi >=21.1 @@ -1700,9 +1703,9 @@ packages: license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/jupyter-server?source=hash-mapping - size: 360522 - timestamp: 1778060967727 + - pkg:pypi/jupyter-server?source=compressed-mapping + size: 363068 + timestamp: 1781713810089 - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda sha256: 5eda79ed9f53f590031d29346abd183051263227dd9ee667b5ca1133ce297654 md5: 7b8bace4943e0dc345fc45938826f2b8 @@ -1716,31 +1719,31 @@ packages: - pkg:pypi/jupyter-server-terminals?source=hash-mapping size: 22052 timestamp: 1768574057200 -- conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.5.7-pyhd8ed1ab_0.conda - sha256: b85befad5ba1f50c0cc042a2ffb26441d13ffc2f18572dc20d3541476da0c7b9 - md5: 2ffe77234070324e763a6eddabb5f467 +- conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.6.0-pyhd8ed1ab_0.conda + sha256: 8a1704a556cdcec791639a788857e4abee2866f0b92e0fa0fe3e5a9d935b3d09 + md5: b838c6dcec21a6575d5f6fcaf34693be depends: - async-lru >=1.0.0 - httpx >=0.25.0,<1 - ipykernel >=6.5.0,!=6.30.0 - jinja2 >=3.0.3 + - jupyter-builder >=1.0.2 - jupyter-lsp >=2.0.0 - jupyter_core - - jupyter_server >=2.4.0,<3 + - jupyter_server >=2.19.0,<3 - jupyterlab_server >=2.28.0,<3 - notebook-shim >=0.2 - - packaging + - packaging >=23.2 - python >=3.10 - - setuptools >=41.1.0 - tomli >=1.2.2 - tornado >=6.2.0 - traitlets license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/jupyterlab?source=hash-mapping - size: 8861204 - timestamp: 1777483115382 + - pkg:pypi/jupyterlab?source=compressed-mapping + size: 13602435 + timestamp: 1781794002520 - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda sha256: dc24b900742fdaf1e077d9a3458fd865711de80bca95fe3c6d46610c532c6ef0 md5: fd312693df06da3578383232528c468d @@ -1888,21 +1891,21 @@ packages: - pkg:pypi/mypy-extensions?source=hash-mapping size: 11766 timestamp: 1745776666688 -- conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda - sha256: 1b66960ee06874ddceeebe375d5f17fb5f393d025a09e15b830ad0c4fffb585b - md5: 00f5b8dafa842e0c27c1cd7296aa4875 +- conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.11.0-pyhd8ed1ab_0.conda + sha256: eceb424236fbbb9b337a857fe5448307b57a2a3fb2db389ae37e7a8b8cdca2ab + md5: cf01a81d7960ad9c829bf2e794fcee9a depends: - - jupyter_client >=6.1.12 - - jupyter_core >=4.12,!=5.0.* - - nbformat >=5.1 - - python >=3.8 - - traitlets >=5.4 + - jupyter_client >=7.0.0 + - jupyter_core >=5.4 + - nbformat >=5.2.0 + - python >=3.10 + - traitlets >=5.13 license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/nbclient?source=hash-mapping - size: 28473 - timestamp: 1766485646962 + - pkg:pypi/nbclient?source=compressed-mapping + size: 29138 + timestamp: 1780661039538 - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda sha256: ab2ac79c5892c5434d50b3542d96645bdaa06d025b6e03734be29200de248ac2 md5: 2bce0d047658a91b99441390b9b27045 @@ -1959,13 +1962,13 @@ packages: - pkg:pypi/nest-asyncio?source=hash-mapping size: 11543 timestamp: 1733325673691 -- conda: https://conda.anaconda.org/conda-forge/noarch/notebook-7.5.6-pyhcf101f3_1.conda - sha256: 14e85ec737c3f5976d18c71e5a07721c1ff835684330961c3c69e8ba2e7d6ff4 - md5: 1fa699844c163bf17717fed8ca229846 +- conda: https://conda.anaconda.org/conda-forge/noarch/notebook-7.6.0-pyhcf101f3_0.conda + sha256: 5b48c26a966caae81169cc8056321a4c139103880eb01e1f4f02ad6ff9390421 + md5: d9eb17006787e506bcb70f16daf1b1c1 depends: - - importlib_resources >=5.0 - - jupyter_server >=2.4.0,<3 - - jupyterlab >=4.5.7,<4.6 + - jupyter_server >=2.19.0,<3 + - jupyter-builder >=1.0.2,<2 + - jupyterlab >=4.6.0,<4.7 - jupyterlab_server >=2.28.0,<3 - notebook-shim >=0.2,<0.3 - python >=3.10 @@ -1974,9 +1977,9 @@ packages: license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/notebook?source=hash-mapping - size: 10114589 - timestamp: 1777553380465 + - pkg:pypi/notebook?source=compressed-mapping + size: 4629848 + timestamp: 1781800954960 - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_1.conda sha256: 7b920e46b9f7a2d2aa6434222e5c8d739021dbc5cc75f32d124a8191d86f9056 md5: e7f89ea5f7ea9401642758ff50a2d9c1 @@ -2058,29 +2061,29 @@ packages: - pkg:pypi/pexpect?source=hash-mapping size: 53561 timestamp: 1733302019362 -- conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh145f28c_0.conda - sha256: 00acccc6f69568ddc56d4d5cc031fdb27eb6a1588a80b1f3a5233bd2a6f944f0 - md5: 2e7e59a063366f1fc4f45ac86bd9485f +- conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.1.2-pyh145f28c_0.conda + sha256: 9e673d3c6003f416df11670a14b026a04e3a45ebec55357987e15b860f138f2a + md5: 733cc07ed34162ac50b936464b163366 depends: - python >=3.13.0a0 license: MIT license_family: MIT purls: - - pkg:pypi/pip?source=hash-mapping - size: 1199678 - timestamp: 1777924078252 -- conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda - sha256: 8f29915c172f1f7f4f7c9391cd5dac3ebf5d13745c8b7c8006032615246345a5 - md5: 89c0b6d1793601a2a3a3f7d2d3d8b937 + - pkg:pypi/pip?source=compressed-mapping + size: 1202377 + timestamp: 1780262809860 +- conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.10.0-pyhcf101f3_0.conda + sha256: 9e5e1fd3506ccfc4d444fc4d2d39b0ed097d5d0e3bd3d4bdf6bcc81aaf66860d + md5: 2c5ef45db85d34799771629bd5860fd7 depends: - python >=3.10 - python license: MIT license_family: MIT purls: - - pkg:pypi/platformdirs?source=hash-mapping - size: 25862 - timestamp: 1775741140609 + - pkg:pypi/platformdirs?source=compressed-mapping + size: 26308 + timestamp: 1779972894916 - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda sha256: 4d7ec90d4f9c1f3b4a50623fefe4ebba69f651b102b373f7c0e9dbbfa43d495c md5: a11ab1f31af799dd93c3a39881528884 @@ -2197,19 +2200,19 @@ packages: - pkg:pypi/fastjsonschema?source=hash-mapping size: 244628 timestamp: 1755304154927 -- conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.5-h4df99d1_100.conda - sha256: 41dd7da285d71d519257fa7dacb1cae060d5ebfaa5f92cba5994899d2978e943 - md5: 41954747ba952ec4b01e16c2c9e8d8ff +- conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.6-h4df99d1_100.conda + sha256: 84c129bdd6abcecac42a948f2670d17fe735d02d3a5a483a9b1f1bc33ba38c28 + md5: 224f69f177eb5aae6c9a6052846bf609 depends: - - cpython 3.14.5.* + - cpython 3.14.6.* - python_abi * *_cp314 license: Python-2.0 purls: [] - size: 50212 - timestamp: 1779236703009 -- conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efcf_0.conda - sha256: 1c55116c22512cef7b01d55ae49697707f2c1fd829407183c19817e2d300fd8d - md5: 1cd2f3e885162ee1366312bd1b1677fd + size: 49315 + timestamp: 1781254664376 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-4.1.0-pyhd8ed1ab_0.conda + sha256: a0dfe07d0bc1d8c47a38b79ad4a8eb1bc7b86fb33ee5293ebb45dfdc46191f4e + md5: 982ed0cbfc0fe09f25861e3d111e9717 depends: - python >=3.10 - typing_extensions @@ -2217,8 +2220,8 @@ packages: license_family: BSD purls: - pkg:pypi/python-json-logger?source=hash-mapping - size: 18969 - timestamp: 1777318679482 + size: 19249 + timestamp: 1781036004580 - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda sha256: e943f9c15a6bdba2e1b9f423ab913b3f6b02197b0ef9f8e6b7464d78b59965b9 md5: f6ad7450fc21e00ecc23812baed6d2e4 @@ -2325,18 +2328,18 @@ packages: - pkg:pypi/rich?source=hash-mapping size: 208577 timestamp: 1775991661559 -- conda: https://conda.anaconda.org/conda-forge/noarch/rust-std-x86_64-unknown-linux-gnu-1.95.0-h2c6d0dc_1.conda - sha256: 5d2e2b38a6d2a7653afc93706da04a5a14a6de9834cd34c0a2f4d7af619a3bc6 - md5: 835766243561e6c6f34b617b9eb89110 +- conda: https://conda.anaconda.org/conda-forge/noarch/rust-std-x86_64-unknown-linux-gnu-1.96.0-h2c6d0dc_0.conda + sha256: e8c453fc331eedd6b7a02356d177802a2c03b0bc6490d86c0e63c15ef172d53f + md5: cbbc8546ba8381cb792744564cec0430 depends: - __unix constrains: - - rust >=1.95.0,<1.95.1.0a0 + - rust >=1.96.0,<1.96.1.0a0 license: MIT license_family: MIT purls: [] - size: 36416714 - timestamp: 1777535938349 + size: 36676677 + timestamp: 1780046295074 - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyha191276_1.conda sha256: 59656f6b2db07229351dfb3a859c35e57cc8e8bcbc86d4e501bff881a6f771f1 md5: 28eb91468df04f655a57bcfbb35fc5c5 @@ -2350,17 +2353,6 @@ packages: - pkg:pypi/send2trash?source=hash-mapping size: 24108 timestamp: 1770937597662 -- conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda - sha256: 82088a6e4daa33329a30bc26dc19a98c7c1d3f05c0f73ce9845d4eab4924e9e1 - md5: 8e194e7b992f99a5015edbd4ebd38efd - depends: - - python >=3.10 - license: MIT - license_family: MIT - purls: - - pkg:pypi/setuptools?source=hash-mapping - size: 639697 - timestamp: 1773074868565 - conda: https://conda.anaconda.org/conda-forge/noarch/shellingham-1.5.4-pyhd8ed1ab_2.conda sha256: 1d6534df8e7924d9087bd388fbac5bd868c5bf8971c36885f9f016da0657d22b md5: 83ea3a2ddb7a75c1b09cea582aa4f106 @@ -2401,6 +2393,7 @@ packages: depends: - python >=3.10 license: MIT + license_family: MIT purls: - pkg:pypi/soupsieve?source=compressed-mapping size: 38802 @@ -2470,18 +2463,18 @@ packages: - pkg:pypi/tomli?source=hash-mapping size: 21561 timestamp: 1774492402955 -- conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda - sha256: dfb681579be59c2e790c95f7f49b7529a9b0511d6385ad276e3c8988cbd54d2c - md5: 4bada6a6d908a27262af8ebddf4f7492 +- conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.1-pyhcf101f3_0.conda + sha256: b89a823edf524956b94a2a4db974866e4501f05c68976eff458c5dcf07f88431 + md5: 37e3be7b6e2977d37b8fa5da229f5dc0 depends: - python >=3.10 - python license: BSD-3-Clause license_family: BSD purls: - - pkg:pypi/traitlets?source=hash-mapping - size: 115165 - timestamp: 1778074251714 + - pkg:pypi/traitlets?source=compressed-mapping + size: 115158 + timestamp: 1780507822178 - conda: https://conda.anaconda.org/conda-forge/noarch/typer-0.25.1-pyhcf101f3_0.conda sha256: 18fc3a27bc995318d09142fe16d01ea454e76f377bf8f68db03b8b18f11085ed md5: ef114c2eb2ff19f6bf616c81f4710841 @@ -2564,17 +2557,17 @@ packages: - pkg:pypi/urllib3?source=hash-mapping size: 103560 timestamp: 1778188657149 -- conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.7.0-pyhd8ed1ab_0.conda - sha256: 1ee2d8384972ecbf8630ce8a3ea9d16858358ad3e8566675295e66996d5352da - md5: eb9538b8e55069434a18547f43b96059 +- conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.8.1-pyhd8ed1ab_0.conda + sha256: 5ddde23d65aecde7e8dac0b9d9c7821ead2b87a320d787f9e4288c0ee00fa332 + md5: 19c961dd9cab6c3e13cd195f0176dbfa depends: - python >=3.10 license: MIT license_family: MIT purls: - - pkg:pypi/wcwidth?source=hash-mapping - size: 82917 - timestamp: 1777744489106 + - pkg:pypi/wcwidth?source=compressed-mapping + size: 133769 + timestamp: 1780932915297 - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda sha256: 21f6c8a20fe050d09bfda3fb0a9c3493936ce7d6e1b3b5f8b01319ee46d6c6f6 md5: 6639b6b0d8b5a284f027a2003669aa65 @@ -2640,7 +2633,6 @@ packages: - mblack ==26.4.0 - jupyter_client >=8.6.2,<8.7 license: LicenseRef-Modular-Proprietary - run_exports: {} size: 96475709 timestamp: 1781237127405 - conda: https://conda.modular.com/max/linux-64/mojo-compiler-1.0.0b2-release.conda @@ -2649,7 +2641,6 @@ packages: depends: - mojo-python ==1.0.0b2 license: LicenseRef-Modular-Proprietary - run_exports: {} size: 85342385 timestamp: 1781237127405 - conda: https://conda.modular.com/max/noarch/mblack-26.4.0-release.conda @@ -2665,7 +2656,6 @@ packages: - platformdirs >=2 - tomli >=1.1.0 license: LicenseRef-Modular-Proprietary - run_exports: {} size: 135301 timestamp: 1781220755102 - conda: https://conda.modular.com/max/noarch/mojo-python-1.0.0b2-release.conda @@ -2675,7 +2665,6 @@ packages: depends: - python >=3.10 license: LicenseRef-Modular-Proprietary - run_exports: {} size: 24682 timestamp: 1781220753246 - pypi: . @@ -2704,27 +2693,30 @@ packages: - virtualenv>=20.17 ; python_full_version >= '3.10' and python_full_version < '3.14' and extra == 'virtualenv' - virtualenv>=20.31 ; python_full_version >= '3.14' and extra == 'virtualenv' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/16/6b/330d8ebae582b30c2959a1ef4c3bc344ebde48c2ff0c3f113c4710735e11/pyright-1.1.409-py3-none-any.whl - name: pyright - version: 1.1.409 - sha256: aa3ea228cab90c845c7a60d28db7a844c04315356392aa09fafcee98c8c22fb3 - requires_dist: - - nodeenv>=1.6.0 - - typing-extensions>=4.1 - - twine>=3.4.1 ; extra == 'dev' - - nodejs-wheel-binaries ; extra == 'nodejs' - - twine>=3.4.1 ; extra == 'all' - - nodejs-wheel-binaries ; extra == 'all' - requires_python: '>=3.7' - pypi: https://files.pythonhosted.org/packages/1d/fc/716c1e62e512ef1c160e7984a73a5fc7df45166f2ff3f254e71c58076f7c/libclang-18.1.1-py2.py3-none-manylinux2010_x86_64.whl name: libclang version: 18.1.1 sha256: c533091d8a3bbf7460a00cb6c1a71da93bffe148f172c7d03b1c31fbf8aa2a0b -- pypi: https://files.pythonhosted.org/packages/1e/c0/56472c251d09858a53e51efbd485b09e1995d8731668b76d52e5dd6ee0f1/ruff-0.15.14-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - name: ruff - version: 0.15.14 - sha256: 715c543cf450c4888251f91c52f1942a800541d9bddd7ac060aa4e6b77ae7cba - requires_python: '>=3.7' +- pypi: https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl + name: pytest + version: 9.1.1 + sha256: 37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c + requires_dist: + - colorama>=0.4 ; sys_platform == 'win32' + - exceptiongroup>=1 ; python_full_version < '3.11' + - iniconfig>=1.0.1 + - packaging>=22 + - pluggy>=1.5,<2 + - pygments>=2.7.2 + - tomli>=1 ; python_full_version < '3.11' + - argcomplete ; extra == 'dev' + - attrs>=19.2 ; extra == 'dev' + - hypothesis>=3.56 ; extra == 'dev' + - mock ; extra == 'dev' + - requests ; extra == 'dev' + - setuptools ; extra == 'dev' + - xmlschema ; extra == 'dev' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl name: pluggy version: 1.6.0 @@ -2736,6 +2728,11 @@ packages: - pytest-benchmark ; extra == 'testing' - coverage ; extra == 'testing' requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/6d/ff/d353d6b7bbd73cc0ec37f4463d7540e45e894338abdd9964eee0de332708/ruff-0.15.18-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + name: ruff + version: 0.15.18 + sha256: 5f0480ce690cbb6c4db6e5d08f19fce98e10ba131a8b60c1bcdac42771e3ae2d + requires_python: '>=3.7' - pypi: https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl name: nodeenv version: 1.10.0 @@ -2751,23 +2748,15 @@ packages: version: 2.3.0 sha256: f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl - name: pytest - version: 9.0.3 - sha256: 2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9 +- pypi: https://files.pythonhosted.org/packages/d7/33/288b5868fa00846dacf249633719d747893e54aebd196b9968ac1878a5d3/pyright-1.1.410-py3-none-any.whl + name: pyright + version: 1.1.410 + sha256: 5e961bed37cacf96b3f7cd7b1da39b350a9239aa2e69138d0e88f728cfaf296c requires_dist: - - colorama>=0.4 ; sys_platform == 'win32' - - exceptiongroup>=1 ; python_full_version < '3.11' - - iniconfig>=1.0.1 - - packaging>=22 - - pluggy>=1.5,<2 - - pygments>=2.7.2 - - tomli>=1 ; python_full_version < '3.11' - - argcomplete ; extra == 'dev' - - attrs>=19.2 ; extra == 'dev' - - hypothesis>=3.56 ; extra == 'dev' - - mock ; extra == 'dev' - - requests ; extra == 'dev' - - setuptools ; extra == 'dev' - - xmlschema ; extra == 'dev' - requires_python: '>=3.10' + - nodeenv>=1.6.0 + - typing-extensions>=4.1 + - twine>=3.4.1 ; extra == 'dev' + - nodejs-wheel-binaries ; extra == 'nodejs' + - twine>=3.4.1 ; extra == 'all' + - nodejs-wheel-binaries ; extra == 'all' + requires_python: '>=3.7' diff --git a/tests/e2e/fixtures/atomic_types_runtime/expect.emit.owned_dl_handle.mojo b/tests/e2e/fixtures/atomic_types_runtime/expect.emit.owned_dl_handle.mojo index be6612f..7b46d2e 100644 --- a/tests/e2e/fixtures/atomic_types_runtime/expect.emit.owned_dl_handle.mojo +++ b/tests/e2e/fixtures/atomic_types_runtime/expect.emit.owned_dl_handle.mojo @@ -4,8 +4,8 @@ def at_reset( def at_inc( def at_dec( def at_get( -def at_addr() raises -> Optional[UnsafePointer[Atomic[DType.int32], MutUntrackedOrigin]]: -def at_addr_const() raises -> Optional[UnsafePointer[Atomic[DType.int32], ImmutUntrackedOrigin]]: -def at_store_ptr(dst: Optional[UnsafePointer[Atomic[DType.int32], MutUntrackedOrigin]], value: c_int) raises -> None: -def at_load_ptr(src: Optional[UnsafePointer[Atomic[DType.int32], ImmutUntrackedOrigin]]) raises -> c_int: -def at_inc_ptr(dst: Optional[UnsafePointer[Atomic[DType.int32], MutUntrackedOrigin]]) raises -> c_int: +def at_addr() -> Optional[UnsafePointer[Atomic[DType.int32], MutUntrackedOrigin]]: +def at_addr_const() -> Optional[UnsafePointer[Atomic[DType.int32], ImmutUntrackedOrigin]]: +def at_store_ptr(dst: Optional[UnsafePointer[Atomic[DType.int32], MutUntrackedOrigin]], value: c_int) -> None: +def at_load_ptr(src: Optional[UnsafePointer[Atomic[DType.int32], ImmutUntrackedOrigin]]) -> c_int: +def at_inc_ptr(dst: Optional[UnsafePointer[Atomic[DType.int32], MutUntrackedOrigin]]) -> c_int: diff --git a/tests/e2e/fixtures/complex_types_runtime/expect.runtime.owned_dl_handle.json b/tests/e2e/fixtures/complex_types_runtime/expect.runtime.owned_dl_handle.json index 6bb83f6..91c3d26 100644 --- a/tests/e2e/fixtures/complex_types_runtime/expect.runtime.owned_dl_handle.json +++ b/tests/e2e/fixtures/complex_types_runtime/expect.runtime.owned_dl_handle.json @@ -1,6 +1,6 @@ { - "cplx_add_real_case0": -0.5, - "cplx_add_imag_case0": 0.0, - "cplx_mul_real_case0": -3.0, - "cplx_mul_imag_case0": 0.0 + "cplx_add_real_case0": 3.75, + "cplx_add_imag_case0": -1.5, + "cplx_mul_real_case0": 4.375, + "cplx_mul_imag_case0": -3.75 } diff --git a/tests/e2e/fixtures/fnptr_return/expect.emit.owned_dl_handle.mojo b/tests/e2e/fixtures/fnptr_return/expect.emit.owned_dl_handle.mojo index b5b2571..9d86654 100644 --- a/tests/e2e/fixtures/fnptr_return/expect.emit.owned_dl_handle.mojo +++ b/tests/e2e/fixtures/fnptr_return/expect.emit.owned_dl_handle.mojo @@ -1,5 +1,5 @@ comptime int32_t = Int32 comptime pfr_binary_op_t = def (arg0: int32_t, arg1: int32_t) thin abi("C") -> int32_t -def pfr_select_add() raises -> pfr_binary_op_t: -return _bindgen_dl().call["pfr_select_add", pfr_binary_op_t]() +def pfr_select_add() -> pfr_binary_op_t: +_bindgen_function[def() thin abi("C") -> pfr_binary_op_t](StringSlice("pfr_select_add")) def pfr_sanity( diff --git a/tests/e2e/fixtures/full_surface_runtime/expect.emit.owned_dl_handle.mojo b/tests/e2e/fixtures/full_surface_runtime/expect.emit.owned_dl_handle.mojo index 261b993..5408558 100644 --- a/tests/e2e/fixtures/full_surface_runtime/expect.emit.owned_dl_handle.mojo +++ b/tests/e2e/fixtures/full_surface_runtime/expect.emit.owned_dl_handle.mojo @@ -1,5 +1,5 @@ -def _bindgen_dl( -_bindgen_dl().call[ +def _bindgen_dylib( +_bindgen_function[ struct surf_point struct surf_pair struct surf_flags diff --git a/tests/e2e/fixtures/functional_math/expect.emit.owned_dl_handle.mojo b/tests/e2e/fixtures/functional_math/expect.emit.owned_dl_handle.mojo index e6d1a62..d152449 100644 --- a/tests/e2e/fixtures/functional_math/expect.emit.owned_dl_handle.mojo +++ b/tests/e2e/fixtures/functional_math/expect.emit.owned_dl_handle.mojo @@ -1,6 +1,6 @@ # Each non-comment line must be present in the emitted file. -def _bindgen_dl( -_bindgen_dl().call[ +def _bindgen_dylib( +_bindgen_function[ def fm_add( def fm_mix3( def fm_affine( diff --git a/tests/e2e/fixtures/functional_records/expect.emit.owned_dl_handle.mojo b/tests/e2e/fixtures/functional_records/expect.emit.owned_dl_handle.mojo index 2c4e806..8814009 100644 --- a/tests/e2e/fixtures/functional_records/expect.emit.owned_dl_handle.mojo +++ b/tests/e2e/fixtures/functional_records/expect.emit.owned_dl_handle.mojo @@ -1,5 +1,5 @@ -def _bindgen_dl( -_bindgen_dl().call[ +def _bindgen_dylib( +_bindgen_function[ def fr_linear( def fr_apply_mode( def fr_is_nonzero( diff --git a/tests/e2e/fixtures/globals_consts_runtime/expect.emit.external.mojo b/tests/e2e/fixtures/globals_consts_runtime/expect.emit.external.mojo index 21e0565..31a5a09 100644 --- a/tests/e2e/fixtures/globals_consts_runtime/expect.emit.external.mojo +++ b/tests/e2e/fixtures/globals_consts_runtime/expect.emit.external.mojo @@ -1,5 +1,5 @@ # Each non-comment line must be present in the emitted file. -from std.ffi import external_call, DEFAULT_RTLD, OwnedDLHandle +from std.ffi import external_call, DEFAULT_RTLD, OwnedDLHandle, _DLHandle, _Global, _get_global from std.builtin.simd import SIMD from std.atomic import Atomic struct GlobalVar[T: Copyable & ImplicitlyDestructible, //, link: StaticString]: diff --git a/tests/e2e/fixtures/globals_consts_runtime/expect.emit.owned_dl_handle.mojo b/tests/e2e/fixtures/globals_consts_runtime/expect.emit.owned_dl_handle.mojo index e3a1a93..043bfdb 100644 --- a/tests/e2e/fixtures/globals_consts_runtime/expect.emit.owned_dl_handle.mojo +++ b/tests/e2e/fixtures/globals_consts_runtime/expect.emit.owned_dl_handle.mojo @@ -2,7 +2,7 @@ from std.builtin.simd import SIMD from std.atomic import Atomic comptime _BINDGEN_LIB_PATH: String -def _bindgen_dl() raises -> OwnedDLHandle: +def _bindgen_dylib() -> _DLHandle: comptime int32_t = Int32 comptime gcr_vec4 = SIMD[DType.float32, 4] comptime gcr_mut = GlobalVar[T=int32_t, link="gcr_mut"] diff --git a/tests/e2e/test_e2e_runtime.py b/tests/e2e/test_e2e_runtime.py index f026d81..d1427e3 100644 --- a/tests/e2e/test_e2e_runtime.py +++ b/tests/e2e/test_e2e_runtime.py @@ -294,11 +294,6 @@ def test_golden_runtime_case(case_dir: Path, tmp_path: Path) -> None: if build_dl.returncode == 0: dl_env = os.environ.copy() - # Mojo cannot keep a module-level OwnedDLHandle alive yet, so the generated - # owned-dl-handle bindings reopen the library on each call. Preloading the - # fixture DSO keeps one process-lifetime instance resident, which preserves - # C global/atomic state across those transient handles. - dl_env["LD_PRELOAD"] = str(lib_path) runtime_dl = _run([str(dl_bin)], cwd=_REPO_ROOT, env=dl_env) _check_phase( "runtime_owned_dl_handle", diff --git a/tests/surface/fixtures/global_stub_const_ptr/expect.external.mojo b/tests/surface/fixtures/global_stub_const_ptr/expect.external.mojo index ec43f74..8dd717c 100644 --- a/tests/surface/fixtures/global_stub_const_ptr/expect.external.mojo +++ b/tests/surface/fixtures/global_stub_const_ptr/expect.external.mojo @@ -3,47 +3,83 @@ # library: surface_globals link_name: surface_globals # FFI mode: external_call -from std.ffi import external_call, DEFAULT_RTLD, OwnedDLHandle +from std.ffi import external_call, DEFAULT_RTLD, OwnedDLHandle, _DLHandle, _Global, _get_global +from std.memory.unsafe_pointer import unsafe_cast +from std.os import abort -# Resolve symbols from libraries already linked into this process. -def _bindgen_dl() raises -> OwnedDLHandle: - return OwnedDLHandle(DEFAULT_RTLD) +comptime _BINDGEN_LIB_NAME = "surface_globals" +comptime _BINDGEN_LINK_NAME = "surface_globals" + +def _bindgen_init_dylib() -> OwnedDLHandle: + try: + return OwnedDLHandle(DEFAULT_RTLD) + except e: + abort(t"bindgen: failed to open process dynamic symbol table: {e}") + +comptime _BINDGEN_DYLIB = _Global["mojo_bindgen/surface_globals", _bindgen_init_dylib] + +# Returns a borrowed process-lifetime dynamic library handle; do not close it. +def _bindgen_dylib() -> _DLHandle: + var dylib_ptr = _get_global[ + _BINDGEN_DYLIB.name, + _BINDGEN_DYLIB._init_wrapper, + _BINDGEN_DYLIB._deinit_wrapper, + ]() + var dylib = unsafe_cast[Type=_BINDGEN_DYLIB.StorageType](dylib_ptr).value()[].borrow() + if not dylib: + abort(t"bindgen: failed to load dynamic library '{_BINDGEN_LIB_NAME}'") + return dylib + +def _bindgen_function[Fn: TrivialRegisterPassable](symbol: StringSlice) -> Fn: + var fn_ptr = _bindgen_dylib().get_symbol[NoneType](symbol) + if not fn_ptr: + abort( + t"bindgen: missing C function symbol '{symbol}' " + t"in dynamic library '{_BINDGEN_LIB_NAME}'" + ) + return UnsafePointer(to=fn_ptr.value()).bitcast[Fn]()[] struct GlobalVar[T: Copyable & ImplicitlyDestructible, //, link: StaticString]: @staticmethod - def _raw() raises -> UnsafePointer[Self.T, MutUntrackedOrigin]: - var opt: Optional[UnsafePointer[Self.T, MutUntrackedOrigin]] = _bindgen_dl().get_symbol[Self.T](StringSlice(Self.link)) + def _raw() -> UnsafePointer[Self.T, MutUntrackedOrigin]: + var opt: Optional[UnsafePointer[Self.T, MutUntrackedOrigin]] = _bindgen_dylib().get_symbol[Self.T](StringSlice(Self.link)) if not opt: - raise Error(String("bindgen: missing C global symbol")) + abort( + t"bindgen: missing C global symbol '{Self.link}' " + t"in dynamic library '{_BINDGEN_LIB_NAME}'" + ) return opt.value() @staticmethod - def ptr() raises -> UnsafePointer[Self.T, MutUntrackedOrigin]: + def ptr() -> UnsafePointer[Self.T, MutUntrackedOrigin]: return rebind[UnsafePointer[Self.T, MutUntrackedOrigin]](Self._raw()) @staticmethod - def load() raises -> Self.T: + def load() -> Self.T: return Self._raw()[].copy() @staticmethod - def store(value: Self.T) raises -> None: + def store(value: Self.T) -> None: var p = rebind[UnsafePointer[Self.T, MutUntrackedOrigin]](Self._raw()) p[] = value.copy() struct GlobalConst[T: Copyable & ImplicitlyDestructible, //, link: StaticString]: @staticmethod - def _raw() raises -> UnsafePointer[Self.T, MutUntrackedOrigin]: - var opt: Optional[UnsafePointer[Self.T, MutUntrackedOrigin]] = _bindgen_dl().get_symbol[Self.T](StringSlice(Self.link)) + def _raw() -> UnsafePointer[Self.T, MutUntrackedOrigin]: + var opt: Optional[UnsafePointer[Self.T, MutUntrackedOrigin]] = _bindgen_dylib().get_symbol[Self.T](StringSlice(Self.link)) if not opt: - raise Error(String("bindgen: missing C global symbol")) + abort( + t"bindgen: missing C global symbol '{Self.link}' " + t"in dynamic library '{_BINDGEN_LIB_NAME}'" + ) return opt.value() @staticmethod - def ptr() raises -> UnsafePointer[Self.T, ImmutUntrackedOrigin]: + def ptr() -> UnsafePointer[Self.T, ImmutUntrackedOrigin]: return rebind[UnsafePointer[Self.T, ImmutUntrackedOrigin]](Self._raw()) @staticmethod - def load() raises -> Self.T: + def load() -> Self.T: return Self._raw()[].copy() struct gscp_cfg(Copyable, Movable): diff --git a/tests/surface/fixtures/globals_and_consts/expect.external.mojo b/tests/surface/fixtures/globals_and_consts/expect.external.mojo index fcc1a1a..ff5f1a5 100644 --- a/tests/surface/fixtures/globals_and_consts/expect.external.mojo +++ b/tests/surface/fixtures/globals_and_consts/expect.external.mojo @@ -3,47 +3,83 @@ # library: surface_globals link_name: surface_globals # FFI mode: external_call -from std.ffi import external_call, DEFAULT_RTLD, OwnedDLHandle, c_int, c_uint +from std.ffi import external_call, DEFAULT_RTLD, OwnedDLHandle, _DLHandle, _Global, _get_global, c_int, c_uint +from std.memory.unsafe_pointer import unsafe_cast +from std.os import abort -# Resolve symbols from libraries already linked into this process. -def _bindgen_dl() raises -> OwnedDLHandle: - return OwnedDLHandle(DEFAULT_RTLD) +comptime _BINDGEN_LIB_NAME = "surface_globals" +comptime _BINDGEN_LINK_NAME = "surface_globals" + +def _bindgen_init_dylib() -> OwnedDLHandle: + try: + return OwnedDLHandle(DEFAULT_RTLD) + except e: + abort(t"bindgen: failed to open process dynamic symbol table: {e}") + +comptime _BINDGEN_DYLIB = _Global["mojo_bindgen/surface_globals", _bindgen_init_dylib] + +# Returns a borrowed process-lifetime dynamic library handle; do not close it. +def _bindgen_dylib() -> _DLHandle: + var dylib_ptr = _get_global[ + _BINDGEN_DYLIB.name, + _BINDGEN_DYLIB._init_wrapper, + _BINDGEN_DYLIB._deinit_wrapper, + ]() + var dylib = unsafe_cast[Type=_BINDGEN_DYLIB.StorageType](dylib_ptr).value()[].borrow() + if not dylib: + abort(t"bindgen: failed to load dynamic library '{_BINDGEN_LIB_NAME}'") + return dylib + +def _bindgen_function[Fn: TrivialRegisterPassable](symbol: StringSlice) -> Fn: + var fn_ptr = _bindgen_dylib().get_symbol[NoneType](symbol) + if not fn_ptr: + abort( + t"bindgen: missing C function symbol '{symbol}' " + t"in dynamic library '{_BINDGEN_LIB_NAME}'" + ) + return UnsafePointer(to=fn_ptr.value()).bitcast[Fn]()[] struct GlobalVar[T: Copyable & ImplicitlyDestructible, //, link: StaticString]: @staticmethod - def _raw() raises -> UnsafePointer[Self.T, MutUntrackedOrigin]: - var opt: Optional[UnsafePointer[Self.T, MutUntrackedOrigin]] = _bindgen_dl().get_symbol[Self.T](StringSlice(Self.link)) + def _raw() -> UnsafePointer[Self.T, MutUntrackedOrigin]: + var opt: Optional[UnsafePointer[Self.T, MutUntrackedOrigin]] = _bindgen_dylib().get_symbol[Self.T](StringSlice(Self.link)) if not opt: - raise Error(String("bindgen: missing C global symbol")) + abort( + t"bindgen: missing C global symbol '{Self.link}' " + t"in dynamic library '{_BINDGEN_LIB_NAME}'" + ) return opt.value() @staticmethod - def ptr() raises -> UnsafePointer[Self.T, MutUntrackedOrigin]: + def ptr() -> UnsafePointer[Self.T, MutUntrackedOrigin]: return rebind[UnsafePointer[Self.T, MutUntrackedOrigin]](Self._raw()) @staticmethod - def load() raises -> Self.T: + def load() -> Self.T: return Self._raw()[].copy() @staticmethod - def store(value: Self.T) raises -> None: + def store(value: Self.T) -> None: var p = rebind[UnsafePointer[Self.T, MutUntrackedOrigin]](Self._raw()) p[] = value.copy() struct GlobalConst[T: Copyable & ImplicitlyDestructible, //, link: StaticString]: @staticmethod - def _raw() raises -> UnsafePointer[Self.T, MutUntrackedOrigin]: - var opt: Optional[UnsafePointer[Self.T, MutUntrackedOrigin]] = _bindgen_dl().get_symbol[Self.T](StringSlice(Self.link)) + def _raw() -> UnsafePointer[Self.T, MutUntrackedOrigin]: + var opt: Optional[UnsafePointer[Self.T, MutUntrackedOrigin]] = _bindgen_dylib().get_symbol[Self.T](StringSlice(Self.link)) if not opt: - raise Error(String("bindgen: missing C global symbol")) + abort( + t"bindgen: missing C global symbol '{Self.link}' " + t"in dynamic library '{_BINDGEN_LIB_NAME}'" + ) return opt.value() @staticmethod - def ptr() raises -> UnsafePointer[Self.T, ImmutUntrackedOrigin]: + def ptr() -> UnsafePointer[Self.T, ImmutUntrackedOrigin]: return rebind[UnsafePointer[Self.T, ImmutUntrackedOrigin]](Self._raw()) @staticmethod - def load() raises -> Self.T: + def load() -> Self.T: return Self._raw()[].copy() comptime DEFAULT_LIMIT = c_uint(42) diff --git a/tests/unit/test_ir_codegen_edges.py b/tests/unit/test_ir_codegen_edges.py index 8f636ac..5e7f0be 100644 --- a/tests/unit/test_ir_codegen_edges.py +++ b/tests/unit/test_ir_codegen_edges.py @@ -509,7 +509,7 @@ def test_generator_renders_global_var_stub_and_macro_comments() -> None: assert ( "external_call" in import_line and "OwnedDLHandle" in import_line and "c_int" in import_line ) - assert "def _bindgen_dl() raises -> OwnedDLHandle:" in out + assert "def _bindgen_dylib() -> _DLHandle:" in out assert "struct GlobalVar[T: Copyable & ImplicitlyDestructible, //, link: StaticString]:" in out assert ( "struct GlobalConst[T: Copyable & ImplicitlyDestructible, //, link: StaticString]:" in out @@ -870,17 +870,21 @@ def test_generator_emits_function_pointer_return_wrappers_for_both_link_modes() ) ).generate(unit) assert 'comptime pfr_binary_op_t = def (a: c_int, b: c_int) thin abi("C") -> c_int' in dl_out - assert "def pfr_select_add() raises -> pfr_binary_op_t:" in dl_out - assert ("def pfr_select_add_direct() raises -> pfr_select_add_direct_return_cb:") in dl_out - assert 'return _bindgen_dl().call["pfr_select_add", pfr_binary_op_t]()' in dl_out + assert "def pfr_select_add() -> pfr_binary_op_t:" in dl_out + assert ("def pfr_select_add_direct() -> pfr_select_add_direct_return_cb:") in dl_out assert ( - 'return _bindgen_dl().call["pfr_select_add_direct", pfr_select_add_direct_return_cb]()' - in dl_out + 'var fn_ = _bindgen_function[def() thin abi("C") -> pfr_binary_op_t](' + 'StringSlice("pfr_select_add"))' + ) in dl_out + assert ( + 'var fn_ = _bindgen_function[def() thin abi("C") -> ' + 'pfr_select_add_direct_return_cb](StringSlice("pfr_select_add_direct"))' in dl_out ) assert ( - 'return _bindgen_dl().call["pfr_call", c_int, pfr_binary_op_t, c_int, c_int](op, lhs, rhs)' - in dl_out + 'var fn_ = _bindgen_function[def(pfr_binary_op_t, c_int, c_int) thin abi("C") -> ' + 'c_int](StringSlice("pfr_call"))' in dl_out ) + assert "return fn_(op, lhs, rhs)" in dl_out def test_generator_emits_struct_field_callback_aliases() -> None: diff --git a/tests/unit/test_mojo_ir_printer.py b/tests/unit/test_mojo_ir_printer.py index 1a51de2..c7e6ac6 100644 --- a/tests/unit/test_mojo_ir_printer.py +++ b/tests/unit/test_mojo_ir_printer.py @@ -508,8 +508,10 @@ def test_normalize_mojo_module_makes_callback_hoisting_and_imports_explicit() -> assert normalized.dependencies.imports == [ ModuleImport( module="std.ffi", - names=["DEFAULT_RTLD", "OwnedDLHandle", "c_int"], - ) + names=["OwnedDLHandle", "_DLHandle", "_Global", "_find_dylib", "_get_global", "c_int"], + ), + ModuleImport(module="std.memory.unsafe_pointer", names=["unsafe_cast"]), + ModuleImport(module="std.os", names=["abort"]), ] assert normalized.dependencies.support_decls == [ SupportDecl(SupportDeclKind.DL_HANDLE_HELPERS), @@ -554,9 +556,19 @@ def test_normalize_mojo_module_coalesces_seeded_and_discovered_dependencies() -> assert normalized.dependencies.imports == [ ModuleImport( module="std.ffi", - names=["external_call", "DEFAULT_RTLD", "OwnedDLHandle", "c_int"], + names=[ + "external_call", + "DEFAULT_RTLD", + "OwnedDLHandle", + "_DLHandle", + "_Global", + "_get_global", + "c_int", + ], ), ModuleImport(module="std.sys.info", names=["size_of"]), + ModuleImport(module="std.memory.unsafe_pointer", names=["unsafe_cast"]), + ModuleImport(module="std.os", names=["abort"]), ] assert normalized.dependencies.support_decls == [ SupportDecl(SupportDeclKind.DL_HANDLE_HELPERS), @@ -588,7 +600,8 @@ def test_render_mojo_module_uses_owned_dl_handle_library_path_hint() -> None: ) assert 'comptime _BINDGEN_LIB_PATH: String = "/tmp/libdemo.so"' in rendered - assert "return OwnedDLHandle(_BINDGEN_LIB_PATH)" in rendered + assert "return _find_dylib[_BINDGEN_LIB_NAME](_BINDGEN_LIB_PATH)" in rendered + assert "def _bindgen_dylib() -> _DLHandle:" in rendered def test_render_mojo_module_does_not_normalize_implicitly(monkeypatch) -> None: @@ -944,10 +957,10 @@ def test_rendered_mojo_module_compiles_with_mixed_decl_kinds(tmp_path: Path) -> ) assert proc.returncode == 0, proc.stderr - assert "def _bindgen_dl() raises -> OwnedDLHandle:" in rendered + assert "def _bindgen_dylib() -> _DLHandle:" in rendered assert ( "struct GlobalVar[T: Copyable & ImplicitlyDestructible, //, link: StaticString]:" in rendered ) assert 'def install(cb: binary_cb_t) abi("C") -> None:' in rendered - assert "def load_widget() raises -> UnsafePointer[Widget, MutUntrackedOrigin]:" in rendered + assert "def load_widget() -> UnsafePointer[Widget, MutUntrackedOrigin]:" in rendered From ac4156d4c8804b57578f1844f7b9ef6872bc463d Mon Sep 17 00:00:00 2001 From: MoSafi2 Date: Fri, 19 Jun 2026 18:20:36 +0200 Subject: [PATCH 4/4] simplified example --- examples/cairo/generate.sh | 68 ++------- examples/common.sh | 136 ++++++++++++++---- .../global_consts_bindings_test.mojo | 33 ----- examples/libpng/generate.sh | 110 ++------------ examples/sqlite/generate.sh | 105 ++------------ examples/zlib/generate.sh | 114 ++------------- examples/zlib/zlib_dl_smoke.mojo | 5 +- pixi.toml | 1 - 8 files changed, 148 insertions(+), 424 deletions(-) mode change 100755 => 100644 examples/cairo/generate.sh delete mode 100644 examples/global_consts/global_consts_bindings_test.mojo mode change 100755 => 100644 examples/libpng/generate.sh mode change 100755 => 100644 examples/sqlite/generate.sh mode change 100755 => 100644 examples/zlib/generate.sh diff --git a/examples/cairo/generate.sh b/examples/cairo/generate.sh old mode 100755 new mode 100644 index f784ef3..2639542 --- a/examples/cairo/generate.sh +++ b/examples/cairo/generate.sh @@ -1,67 +1,15 @@ #!/usr/bin/env bash -# Example driver for the system Cairo header. -# It finds the real primary `cairo.h`, generates `cairo_bindings.mojo`, and -# builds/runs `cairo_smoke.mojo` to prove the emitted bindings link and work. -# -# Expects: -# - mojo-bindgen on PATH (e.g. `pixi shell` from the repository root), or Pixi -# at the repo root so this script can run `pixi run mojo-bindgen`. -# - Development headers for Cairo (e.g. libcairo2-dev on Debian/Ubuntu). -# -# Notes: -# - mojo-bindgen emits declarations from the primary header only, so this -# script locates `cairo/cairo.h` directly instead of using a wrapper. -# - The shared-library link name is `cairo`. +# Generate and run the Cairo owned-dl-handle example. set -euo pipefail -HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -REPO_ROOT="$(cd "$HERE/../.." && pwd)" -cd "$HERE" +source "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/common.sh" +example_init "${BASH_SOURCE[0]}" -source "$REPO_ROOT/examples/common.sh" -set_mojo_bindgen_cmd BG "$REPO_ROOT" -set_mojo_cmd MOJO "$REPO_ROOT" +HEADER="$(pkg_header cairo cairo/cairo.h)" || die "cairo/cairo.h not found; install Cairo development headers." +DYLIB="$(find_dylib cairo cairo)" || die "libcairo shared library not found." -find_cairo_h() { - local d - if command -v pkg-config >/dev/null 2>&1; then - while read -r -a flags; do - for flag in "${flags[@]}"; do - if [[ "$flag" == -I* ]]; then - d="${flag#-I}" - if [[ -f "$d/cairo/cairo.h" ]]; then - echo "$d/cairo/cairo.h" - return 0 - fi - if [[ "$d" == */cairo && -f "$d/cairo.h" ]]; then - echo "$d/cairo.h" - return 0 - fi - fi - done - done < <(pkg-config --cflags-only-I cairo 2>/dev/null || true) - fi - for d in /usr/include /usr/local/include /opt/homebrew/include; do - if [[ -f "$d/cairo/cairo.h" ]]; then - echo "$d/cairo/cairo.h" - return 0 - fi - done - return 1 -} +generate_owned_bindings "$HEADER" cairo cairo "$DYLIB" cairo_bindings.mojo +build_smoke cairo_smoke.mojo cairo_smoke -CAIRO_H="$(find_cairo_h)" || { - echo "mojo-bindgen cairo example: could not find cairo/cairo.h (install Cairo development headers)." >&2 - exit 1 -} - -generate_bindings "$CAIRO_H" cairo cairo cairo_bindings.mojo - -OBJ="$(mktemp "${TMPDIR:-/tmp}/cairo-bindings-XXXXXX.o")" -trap 'rm -f "$OBJ"' EXIT -build_bindings_object cairo_bindings.mojo "$OBJ" -"${MOJO[@]}" build cairo_smoke.mojo -I "$HERE" -Xlinker -lcairo -o cairo_smoke - -echo "Wrote $HERE/cairo_bindings.mojo and cairo_bindings_layout_tests.mojo (from $CAIRO_H)" -echo "Running cairo_smoke (runtime render + file round-trip proof)" +echo "Wrote $HERE/cairo_bindings.mojo (dlopen: $DYLIB)" "$HERE/cairo_smoke" diff --git a/examples/common.sh b/examples/common.sh index 891796c..51014e4 100644 --- a/examples/common.sh +++ b/examples/common.sh @@ -1,58 +1,136 @@ #!/usr/bin/env bash -# Shared helpers for repository example generation scripts. +# Shared helpers for example generation scripts. set -euo pipefail -example_repo_root() { - local here="$1" - cd "$here/../.." && pwd +example_init() { + HERE="$(cd "$(dirname "$1")" && pwd)" + REPO_ROOT="$(cd "$HERE/../.." && pwd)" + BG=(pixi run --manifest-path "$REPO_ROOT/pixi.toml" mojo-bindgen) + MOJO=(pixi run --manifest-path "$REPO_ROOT/pixi.toml" mojo) + cd "$HERE" } -set_mojo_bindgen_cmd() { - local -n out="$1" - local repo_root="$2" - if command -v mojo-bindgen >/dev/null 2>&1; then - out=(mojo-bindgen) - return 0 +die() { + echo "$*" >&2 + exit 1 +} + +first_existing() { + local path + for path in "$@"; do + if [[ -f "$path" ]]; then + if command -v realpath >/dev/null 2>&1; then + realpath "$path" + else + echo "$path" + fi + return 0 + fi + done + return 1 +} + +pkg_header() { + local pkg="$1" + local relative="$2" + shift 2 + + local flag dir + if command -v pkg-config >/dev/null 2>&1; then + while read -r -a flags; do + for flag in "${flags[@]}"; do + if [[ "$flag" == -I* ]]; then + dir="${flag#-I}" + first_existing "$dir/$relative" "$dir/$(basename "$relative")" && return 0 + fi + done + done < <(pkg-config --cflags-only-I "$pkg" 2>/dev/null || true) fi - out=(pixi run --manifest-path "$repo_root/pixi.toml" mojo-bindgen) + + first_existing "$@" \ + "/usr/include/$relative" \ + "/usr/local/include/$relative" \ + "/opt/homebrew/include/$relative" } -set_mojo_cmd() { - local -n out="$1" - local repo_root="$2" - if command -v mojo >/dev/null 2>&1; then - out=(mojo) - return 0 +pkg_link_name() { + local pkg="$1" + local fallback="$2" + local flag + if command -v pkg-config >/dev/null 2>&1; then + while read -r -a flags; do + for flag in "${flags[@]}"; do + if [[ "$flag" == -l* ]]; then + echo "${flag#-l}" + return 0 + fi + done + done < <(pkg-config --libs "$pkg" 2>/dev/null || true) fi - out=(pixi run --manifest-path "$repo_root/pixi.toml" mojo) + echo "$fallback" } -set_repo_mojo_cmd() { - local -n out="$1" - local repo_root="$2" - out=(pixi run --manifest-path "$repo_root/pixi.toml" mojo) +find_dylib() { + local link_name="$1" + local pkg="${2:-}" + local name path flag dir + local names=("lib${link_name}.so" "lib${link_name}.so.1" "lib${link_name}.dylib") + + if [[ -n "$pkg" ]] && command -v pkg-config >/dev/null 2>&1; then + while read -r -a flags; do + for flag in "${flags[@]}"; do + if [[ "$flag" == -L* ]]; then + dir="${flag#-L}" + for name in "${names[@]}"; do + first_existing "$dir/$name" && return 0 + done + fi + done + done < <(pkg-config --libs-only-L "$pkg" 2>/dev/null || true) + fi + + if command -v gcc >/dev/null 2>&1; then + for name in "${names[@]}"; do + path="$(gcc -print-file-name="$name" 2>/dev/null || true)" + first_existing "$path" && return 0 + done + fi + + first_existing \ + "$REPO_ROOT/.pixi/envs/default/lib/lib${link_name}.so" \ + "$REPO_ROOT/.pixi/envs/default/lib/lib${link_name}.dylib" \ + "/lib/x86_64-linux-gnu/lib${link_name}.so" \ + "/lib/x86_64-linux-gnu/lib${link_name}.so.1" \ + "/usr/lib/x86_64-linux-gnu/lib${link_name}.so" \ + "/usr/lib/x86_64-linux-gnu/lib${link_name}.so.1" \ + "/usr/lib/lib${link_name}.so" \ + "/usr/lib/lib${link_name}.so.1" \ + "/opt/homebrew/lib/lib${link_name}.dylib" \ + "/usr/lib/lib${link_name}.dylib" } -generate_bindings() { +generate_owned_bindings() { local header="$1" local library="$2" local link_name="$3" - local output="$4" - shift 4 + local dylib="$4" + local output="$5" + shift 5 "${BG[@]}" "$header" \ --library "$library" \ --link-name "$link_name" \ + --link-mode owned-dl-handle \ + --library-path "$dylib" \ --emit-layout-tests \ --layout-test-output "${output%.mojo}_layout_tests.mojo" \ "$@" \ --output "$output" } -build_bindings_object() { +build_smoke() { local source="$1" - local object="$2" - shift 2 - "${MOJO[@]}" build "$source" --emit object -o "$object" "$@" + local output="${2:-${source%.mojo}}" + "${MOJO[@]}" build "$source" -I "$HERE" -o "$output" } diff --git a/examples/global_consts/global_consts_bindings_test.mojo b/examples/global_consts/global_consts_bindings_test.mojo deleted file mode 100644 index da6906b..0000000 --- a/examples/global_consts/global_consts_bindings_test.mojo +++ /dev/null @@ -1,33 +0,0 @@ -# Generated by mojo_bindgen - do not edit by hand. -# layout tests for: global_consts_bindings - -from std.sys.info import align_of, size_of -from std.reflection import reflect -from global_consts_bindings import point, region - - -def _check_eq(label: String, got: Int, expected: Int) raises: - if got != expected: - raise Error(label + ": got " + String(got) + ", expected " + String(expected)) - - -def test_layout_point() raises: - comptime r = reflect[point] - _check_eq("point.size", Int(size_of[point]()), 8) - _check_eq("point.align", Int(align_of[point]()), 4) - _check_eq("point.x.offset", Int(r.field_offset[name="x"]()), 0) - _check_eq("point.y.offset", Int(r.field_offset[name="y"]()), 4) - - -def test_layout_region() raises: - comptime r = reflect[region] - _check_eq("region.size", Int(size_of[region]()), 24) - _check_eq("region.align", Int(align_of[region]()), 8) - _check_eq("region.origin.offset", Int(r.field_offset[name="origin"]()), 0) - _check_eq("region.extent.offset", Int(r.field_offset[name="extent"]()), 8) - _check_eq("region.label.offset", Int(r.field_offset[name="label"]()), 16) - - -def main() raises: - test_layout_point() - test_layout_region() diff --git a/examples/libpng/generate.sh b/examples/libpng/generate.sh old mode 100755 new mode 100644 index 719bfc1..fbf1807 --- a/examples/libpng/generate.sh +++ b/examples/libpng/generate.sh @@ -1,106 +1,22 @@ #!/usr/bin/env bash -# Example driver for the system libpng header. -# It finds the real primary `png.h`, generates `libpng_bindings.mojo`, and -# builds/runs `libpng_smoke.mojo` to verify the bindings link and execute. -# -# Expects: -# - mojo-bindgen on PATH (e.g. `pixi shell` from the repository root), or Pixi -# at the repo root so this script can run `pixi run mojo-bindgen`. -# - Development headers for libpng (e.g. libpng-dev on Debian/Ubuntu). -# -# Notes: -# - mojo-bindgen emits declarations from the primary header only, so this -# script locates `png.h` directly instead of using a wrapper header. -# - The link name may be `png16` or a similar system-specific variant; this -# script derives it from `pkg-config` when possible. +# Generate and run the libpng owned-dl-handle example. set -euo pipefail -HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -REPO_ROOT="$(cd "$HERE/../.." && pwd)" -cd "$HERE" +source "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/common.sh" +example_init "${BASH_SOURCE[0]}" -source "$REPO_ROOT/examples/common.sh" -set_mojo_bindgen_cmd BG "$REPO_ROOT" -set_mojo_cmd MOJO "$REPO_ROOT" - -detect_png_pkg() { - local module - for module in libpng libpng16; do - if command -v pkg-config >/dev/null 2>&1 && pkg-config --exists "$module" 2>/dev/null; then - echo "$module" - return 0 - fi - done - return 1 -} - -find_png_h() { - local module="$1" - local d - if command -v pkg-config >/dev/null 2>&1; then - while read -r -a flags; do - for flag in "${flags[@]}"; do - if [[ "$flag" == -I* ]]; then - d="${flag#-I}" - if [[ -f "$d/png.h" ]]; then - echo "$d/png.h" - return 0 - fi - if [[ -f "$d/libpng16/png.h" ]]; then - echo "$d/libpng16/png.h" - return 0 - fi - fi - done - done < <(pkg-config --cflags-only-I "$module" 2>/dev/null || true) - fi - for d in /usr/include /usr/local/include /opt/homebrew/include; do - if [[ -f "$d/png.h" ]]; then - echo "$d/png.h" - return 0 - fi - if [[ -f "$d/libpng16/png.h" ]]; then - echo "$d/libpng16/png.h" - return 0 - fi - done - return 1 -} - -find_link_name() { - local module="$1" - local token - if command -v pkg-config >/dev/null 2>&1; then - while read -r -a flags; do - for token in "${flags[@]}"; do - if [[ "$token" == -lpng* ]]; then - echo "${token#-l}" - return 0 - fi - done - done < <(pkg-config --libs "$module" 2>/dev/null || true) - fi - echo "png16" -} - -PNG_PKG="$(detect_png_pkg || true)" -if [[ -z "${PNG_PKG:-}" ]]; then - PNG_PKG="libpng" +PKG="libpng" +if command -v pkg-config >/dev/null 2>&1 && pkg-config --exists libpng16; then + PKG="libpng16" fi -PNG_H="$(find_png_h "$PNG_PKG")" || { - echo "mojo-bindgen libpng example: could not find png.h (install libpng development headers)." >&2 - exit 1 -} -LINK_NAME="$(find_link_name "$PNG_PKG")" - -generate_bindings "$PNG_H" "$LINK_NAME" "$LINK_NAME" libpng_bindings.mojo +HEADER="$(pkg_header "$PKG" png.h /usr/include/libpng16/png.h)" || + die "png.h not found; install libpng development headers." +LINK_NAME="$(pkg_link_name "$PKG" png16)" +DYLIB="$(find_dylib "$LINK_NAME" "$PKG")" || die "lib$LINK_NAME shared library not found." -OBJ="$(mktemp "${TMPDIR:-/tmp}/libpng-bindings-XXXXXX.o")" -trap 'rm -f "$OBJ"' EXIT -build_bindings_object libpng_bindings.mojo "$OBJ" -Xlinker "-l$LINK_NAME" -"${MOJO[@]}" build libpng_smoke.mojo -I "$HERE" -Xlinker "-l$LINK_NAME" -o libpng_smoke +generate_owned_bindings "$HEADER" "$LINK_NAME" "$LINK_NAME" "$DYLIB" libpng_bindings.mojo +build_smoke libpng_smoke.mojo libpng_smoke -echo "Wrote $HERE/libpng_bindings.mojo and libpng_bindings_layout_tests.mojo (from $PNG_H)" -echo "Running libpng_smoke (runtime version probe proof)" +echo "Wrote $HERE/libpng_bindings.mojo (dlopen: $DYLIB)" "$HERE/libpng_smoke" diff --git a/examples/sqlite/generate.sh b/examples/sqlite/generate.sh old mode 100755 new mode 100644 index 885e7f9..d964e4d --- a/examples/sqlite/generate.sh +++ b/examples/sqlite/generate.sh @@ -1,103 +1,16 @@ #!/usr/bin/env bash -# Example driver for SQLite. -# It uses the vendored `sqlite3.h` when present, otherwise a system header, -# generates `sqlite3_bindings.mojo`, and builds/runs `sqlite_smoke.mojo`. -# -# Expects: -# - mojo-bindgen on PATH (e.g. `pixi shell` from the repository root), or Pixi -# at the repo root so this script can run `pixi run mojo-bindgen`. -# - Development headers for SQLite (e.g. libsqlite3-dev on Debian/Ubuntu), or use -# the vendored examples/sqlite/sqlite3.h in this repository. -# -# Notes: -# - mojo-bindgen emits declarations from the primary header only, so this -# script passes `sqlite3.h` directly. -# - `sqlite_smoke.mojo` links against `-lsqlite3`; the script also adds an -# extra `-L...` when SQLite lives in a non-default environment path. +# Generate and run the SQLite owned-dl-handle example. set -euo pipefail -HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -REPO_ROOT="$(cd "$HERE/../.." && pwd)" -cd "$HERE" +source "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/common.sh" +example_init "${BASH_SOURCE[0]}" -source "$REPO_ROOT/examples/common.sh" -set_mojo_bindgen_cmd BG "$REPO_ROOT" -# Use the repository Pixi environment so Mojo resolves `std` consistently. -set_repo_mojo_cmd MOJO "$REPO_ROOT" +HEADER="$(pkg_header sqlite3 sqlite3.h "$HERE/sqlite3.h")" || + die "sqlite3.h not found; install SQLite development headers or keep examples/sqlite/sqlite3.h." +DYLIB="$(find_dylib sqlite3 sqlite3)" || die "libsqlite3 shared library not found." -find_sqlite3_h() { - if [[ -f "$HERE/sqlite3.h" ]]; then - echo "$HERE/sqlite3.h" - return 0 - fi - local d - if command -v pkg-config >/dev/null 2>&1; then - while read -r -a flags; do - for flag in "${flags[@]}"; do - if [[ "$flag" == -I* ]]; then - d="${flag#-I}" - if [[ -f "$d/sqlite3.h" ]]; then - echo "$d/sqlite3.h" - return 0 - fi - fi - done - done < <(pkg-config --cflags-only-I sqlite3 2>/dev/null || true) - fi - for d in /usr/include /usr/local/include /opt/homebrew/include; do - if [[ -f "$d/sqlite3.h" ]]; then - echo "$d/sqlite3.h" - return 0 - fi - done - return 1 -} +generate_owned_bindings "$HEADER" sqlite3 sqlite3 "$DYLIB" sqlite3_bindings.mojo +build_smoke sqlite_smoke.mojo sqlite_smoke -# Extra linker search path when SQLite is installed outside the default system path. -sqlite_link_extra() { - local p - if command -v pkg-config >/dev/null 2>&1; then - while read -r -a flags; do - for p in "${flags[@]}"; do - if [[ "$p" == -L* ]]; then - echo "$p" - return 0 - fi - done - done < <(pkg-config --libs-only-L sqlite3 2>/dev/null || true) - fi - for p in "${CONDA_PREFIX:-}" "${PIXI_ENVIRONMENT:-}"; do - if [[ -n "$p" && ( -f "$p/lib/libsqlite3.so" || -f "$p/lib/libsqlite3.dylib" ) ]]; then - echo "-L$p/lib" - return 0 - fi - done - if [[ -f "$REPO_ROOT/.pixi/envs/default/lib/libsqlite3.so" || -f "$REPO_ROOT/.pixi/envs/default/lib/libsqlite3.dylib" ]]; then - echo "-L$REPO_ROOT/.pixi/envs/default/lib" - return 0 - fi - return 0 -} - -SQLITE_H="$(find_sqlite3_h)" || { - echo "mojo-bindgen sqlite example: could not find sqlite3.h (install SQLite development headers or keep vendored sqlite3.h in examples/sqlite)." >&2 - exit 1 -} - -generate_bindings "$SQLITE_H" sqlite3 sqlite3 sqlite3_bindings.mojo - -LINK_EXTRA="$(sqlite_link_extra || true)" -OBJ="$(mktemp "${TMPDIR:-/tmp}/sqlite-bindings-XXXXXX.o")" -trap 'rm -f "$OBJ"' EXIT -build_bindings_object sqlite3_bindings.mojo "$OBJ" -if [[ -n "$LINK_EXTRA" ]]; then - # shellcheck disable=SC2206 - EXTRA=(-Xlinker "$LINK_EXTRA") -else - EXTRA=() -fi -"${MOJO[@]}" build sqlite_smoke.mojo -I "$HERE" "${EXTRA[@]}" -Xlinker -lsqlite3 -o sqlite_smoke - -echo "Wrote $HERE/sqlite3_bindings.mojo and sqlite3_bindings_layout_tests.mojo (from $SQLITE_H)" -echo "Running sqlite_smoke (composite runtime proof)" +echo "Wrote $HERE/sqlite3_bindings.mojo (dlopen: $DYLIB)" "$HERE/sqlite_smoke" diff --git a/examples/zlib/generate.sh b/examples/zlib/generate.sh old mode 100755 new mode 100644 index bf9decc..29eb182 --- a/examples/zlib/generate.sh +++ b/examples/zlib/generate.sh @@ -1,111 +1,15 @@ #!/usr/bin/env bash -# Example driver for the system zlib header. -# It generates both: -# - `zlib_bindings.mojo` for `external_call` -# - `zlib_bindings_dl.mojo` for `owned_dl_handle` when a shared library path is found -# and then builds/runs `zlib_dl_smoke.mojo` for the runtime-loaded path. -# -# Expects: -# - mojo-bindgen on PATH (e.g. `pixi shell` from the repository root), or Pixi -# at the repo root so this script can run `pixi run mojo-bindgen`. -# - Development headers for zlib (e.g. zlib1g-dev on Debian/Ubuntu). -# -# Notes: -# - mojo-bindgen emits declarations from the primary header only, so this -# script locates `zlib.h` directly instead of using a wrapper. -# - The short link name is `z`, not `zlib`. -# - The owned-dl-handle variant is skipped if no shared-library path can be found. +# Generate and run the zlib owned-dl-handle example. set -euo pipefail -HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -REPO_ROOT="$(cd "$HERE/../.." && pwd)" -cd "$HERE" +source "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/common.sh" +example_init "${BASH_SOURCE[0]}" -source "$REPO_ROOT/examples/common.sh" -set_mojo_bindgen_cmd BG "$REPO_ROOT" -set_mojo_cmd MOJO "$REPO_ROOT" +HEADER="$(pkg_header zlib zlib.h)" || die "zlib.h not found; install zlib development headers." +DYLIB="$(find_dylib z zlib)" || die "libz shared library not found." -find_zlib_h() { - local d - if command -v pkg-config >/dev/null 2>&1; then - while read -r -a flags; do - for flag in "${flags[@]}"; do - if [[ "$flag" == -I* ]]; then - d="${flag#-I}" - if [[ -f "$d/zlib.h" ]]; then - echo "$d/zlib.h" - return 0 - fi - fi - done - done < <(pkg-config --cflags-only-I zlib 2>/dev/null || true) - fi - for d in /usr/include /usr/local/include /opt/homebrew/include; do - if [[ -f "$d/zlib.h" ]]; then - echo "$d/zlib.h" - return 0 - fi - done - return 1 -} +generate_owned_bindings "$HEADER" z z "$DYLIB" zlib_bindings.mojo +build_smoke zlib_dl_smoke.mojo zlib_dl_smoke -# Path to the zlib shared library used as `--library-path`. -find_libz_so() { - local p - if command -v gcc >/dev/null 2>&1; then - for name in libz.so libz.dylib; do - p="$(gcc -print-file-name="$name" 2>/dev/null || true)" - if [[ -n "$p" ]]; then - if command -v realpath >/dev/null 2>&1; then - p="$(realpath "$p" 2>/dev/null || echo "$p")" - fi - if [[ -f "$p" ]]; then - echo "$p" - return 0 - fi - fi - done - fi - for p in \ - /lib/x86_64-linux-gnu/libz.so.1 \ - /usr/lib/x86_64-linux-gnu/libz.so.1 \ - /usr/lib/libz.so \ - /lib/libz.so.1 \ - /opt/homebrew/lib/libz.dylib \ - /usr/lib/libz.dylib - do - if [[ -f "$p" ]]; then - if command -v realpath >/dev/null 2>&1; then - realpath "$p" - else - echo "$p" - fi - return 0 - fi - done - return 1 -} - -ZLIB_H="$(find_zlib_h)" || { - echo "mojo-bindgen zlib example: could not find zlib.h (install zlib development headers)." >&2 - exit 1 -} - - -generate_bindings "$ZLIB_H" z z zlib_bindings.mojo -build_bindings_object zlib_bindings.mojo zlib_bindings.o -Xlinker -lz - -echo "Wrote $HERE/zlib_bindings.mojo, zlib_bindings_layout_tests.mojo, and zlib_bindings.o (from $ZLIB_H)" - -LIBZ_SO="$(find_libz_so)" || true -if [[ -n "${LIBZ_SO:-}" ]]; then - generate_bindings "$ZLIB_H" z z zlib_bindings_dl.mojo \ - --link-mode owned-dl-handle --library-path "$LIBZ_SO" - "${MOJO[@]}" build zlib_dl_smoke.mojo -I "$HERE" -o zlib_dl_smoke - echo "Wrote $HERE/zlib_bindings_dl.mojo (dlopen: $LIBZ_SO) and built zlib_dl_smoke" - echo "Running zlib_dl_smoke (owned_dl_handle runtime proof)" - "$HERE/zlib_dl_smoke" -else - echo "mojo-bindgen zlib example: could not locate libz shared library; skipping OwnedDLHandle output." >&2 - echo " (Install zlib and ensure gcc -print-file-name=libz.so resolves.)" >&2 -fi +echo "Wrote $HERE/zlib_bindings.mojo (dlopen: $DYLIB)" +"$HERE/zlib_dl_smoke" diff --git a/examples/zlib/zlib_dl_smoke.mojo b/examples/zlib/zlib_dl_smoke.mojo index 4d2315b..8faa438 100644 --- a/examples/zlib/zlib_dl_smoke.mojo +++ b/examples/zlib/zlib_dl_smoke.mojo @@ -1,6 +1,5 @@ -# Smoke test for OwnedDLHandle bindings: dynamic load of libz and runtime FFI calls. -# Requires zlib_bindings_dl.mojo from generate.sh (--linking owned_dl_handle). -from zlib_bindings_dl import ( +# Smoke test for owned-dl-handle bindings: dynamic load of libz and runtime FFI calls. +from zlib_bindings import ( Z_OK, compressBound, gzclose, diff --git a/pixi.toml b/pixi.toml index 40c3df2..157f0b8 100644 --- a/pixi.toml +++ b/pixi.toml @@ -26,7 +26,6 @@ example-zlib = "bash examples/zlib/generate.sh" example-cairo = "bash examples/cairo/generate.sh" example-libpng = "bash examples/libpng/generate.sh" example-sqlite = "bash examples/sqlite/generate.sh" -example-global-consts = "bash examples/global_consts/generate.sh" [dependencies] mojo = ">=1.0.0b2,<2"