|
| 1 | +const py = @import("py.zig"); |
| 2 | +const std = @import("std"); |
| 3 | +// Import basic objects |
| 4 | +const Object = py.Object; |
| 5 | +const Int = py.Int; |
| 6 | +const Str = py.Str; |
| 7 | +const Module = py.Module; |
| 8 | + |
| 9 | +pub fn add(mod: *Module, args: [*]*Object, n: isize) ?*Object { |
| 10 | + _ = mod; |
| 11 | + if (n != 2) { |
| 12 | + return py.typeError("sum requires 2 arguments"); |
| 13 | + } |
| 14 | + // We can now safely access indexes 0 and 1 |
| 15 | + if (!Int.check(args[0]) or !Int.check(args[1])) { |
| 16 | + return py.typeError("both arguments must be ints!"); |
| 17 | + } |
| 18 | + |
| 19 | + // We can now safely cast to Int objects and access their methods |
| 20 | + const a_obj: *Int = @ptrCast(args[0]); |
| 21 | + const a = a_obj.as(isize) catch return null; |
| 22 | + |
| 23 | + // Or use the method statically and do it in one step |
| 24 | + const b = Int.as(@ptrCast(args[1]), isize) catch return null; |
| 25 | + |
| 26 | + // Add them and create a new Int object |
| 27 | + return @ptrCast(Int.fromNumber(a + b) catch return null); |
| 28 | +} |
| 29 | + |
| 30 | + |
| 31 | +fn modexec(mod: *py.Module) !c_int { |
| 32 | + const stdout = std.io.getStdOut().writer(); |
| 33 | + const s = mod.str() catch return -1; |
| 34 | + defer s.decref(); |
| 35 | + try stdout.print("modexec on {s}!\n", .{s.asString()}); |
| 36 | + |
| 37 | + // Add a str |
| 38 | + const test_str = try Str.fromSlice("test!"); |
| 39 | + defer test_str.decref(); |
| 40 | + try mod.addObjectRef("TEST_STR", @ptrCast(test_str)); |
| 41 | + |
| 42 | + return 0; |
| 43 | +} |
| 44 | + |
| 45 | +pub export fn py_mod_exec(mod: *py.Module) c_int { |
| 46 | + return modexec(mod) catch |err| switch (err) { |
| 47 | + // py.zig uses error.PyError for any error caught from the python c-api |
| 48 | + error.PyError => -1, // Python error |
| 49 | + // Any other errors need to set an error in python |
| 50 | + else => blk: { |
| 51 | + _ = py.systemError("module init failed"); |
| 52 | + break :blk -1; |
| 53 | + }, |
| 54 | + }; |
| 55 | +} |
| 56 | + |
| 57 | +var module_methods = [_]py.MethodDef{ |
| 58 | + .{ |
| 59 | + .ml_name="add", |
| 60 | + .ml_meth=@constCast(@ptrCast(&add)), |
| 61 | + .ml_flags=py.c.METH_FASTCALL, |
| 62 | + .ml_doc="Add two numbers" |
| 63 | + }, |
| 64 | + .{} // sentinel |
| 65 | +}; |
| 66 | + |
| 67 | +var module_slots = [_]py.SlotDef{ |
| 68 | + .{.slot = py.c.Py_mod_exec, .value = @constCast(@ptrCast(&py_mod_exec))}, |
| 69 | + .{} // sentinel |
| 70 | +}; |
| 71 | + |
| 72 | +var moduledef = py.ModuleDef.new(.{ |
| 73 | + .m_name = "pyzigtest", |
| 74 | + .m_doc = "pyzigtest module", |
| 75 | + .m_methods = &module_methods, |
| 76 | + .m_slots = &module_slots, |
| 77 | +}); |
| 78 | + |
| 79 | +pub export fn PyInit_pyzigtest( _:*anyopaque ) [*c]Object { |
| 80 | + return moduledef.init(); |
| 81 | +} |
0 commit comments