From 2e5967d2cd5dfbea2c62e05753eb7586964362d5 Mon Sep 17 00:00:00 2001 From: Nicholas Gates Date: Mon, 30 Oct 2023 09:27:41 +0000 Subject: [PATCH] CallArgs struct --- pydust/src/pytypes.zig | 8 ++++---- pydust/src/trampoline.zig | 43 ++++++++++++++++++++++++--------------- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/pydust/src/pytypes.zig b/pydust/src/pytypes.zig index 421955a3..c60eaa1e 100644 --- a/pydust/src/pytypes.zig +++ b/pydust/src/pytypes.zig @@ -272,9 +272,9 @@ fn Slots(comptime definition: type, comptime name: [:0]const u8) type { const kwargs = if (pykwargs) |pk| py.PyDict.unchecked(.{ .py = pk }) else null; const init_args = tramp.Trampoline(Args).unwrapCallArgs(args, kwargs) catch return -1; - defer funcs.deinitArgs(Args, init_args); + defer init_args.deinit(); - tramp.coerceError(definition.__init__(self, init_args)) catch return -1; + tramp.coerceError(definition.__init__(self, init_args.argsStruct)) catch return -1; } else if (sig.selfParam) |_| { tramp.coerceError(definition.__init__(self)) catch return -1; } else { @@ -364,9 +364,9 @@ fn Slots(comptime definition: type, comptime name: [:0]const u8) type { const self = tramp.Trampoline(sig.selfParam.?).unwrap(py.PyObject{ .py = pyself }) catch return null; const call_args = tramp.Trampoline(sig.argsParam.?).unwrapCallArgs(args, kwargs) catch return null; - defer funcs.deinitArgs(sig.argsParam.?, call_args); + defer call_args.deinit(); - const result = tramp.coerceError(definition.__call__(self, call_args)) catch return null; + const result = tramp.coerceError(definition.__call__(self, call_args.argsStruct)) catch return null; return (py.createOwned(result) catch return null).py; } }; diff --git a/pydust/src/trampoline.zig b/pydust/src/trampoline.zig index dc308988..3e877466 100644 --- a/pydust/src/trampoline.zig +++ b/pydust/src/trampoline.zig @@ -275,27 +275,38 @@ pub fn Trampoline(comptime T: type) type { // Unwrap the call args into a Pydust argument struct, borrowing references to the Python objects // but instantiating the args slice and kwargs map containers. - // The caller is responsible for invoking funcs.deinitArgs on the returned struct. - pub inline fn unwrapCallArgs(pyargs: ?py.PyTuple, pykwargs: ?py.PyDict) PyError!T { - var kwargs = py.Kwargs.init(py.allocator); - if (pykwargs) |kw| { - var iter = kw.itemsIterator(); - while (iter.next()) |item| { - const key: []const u8 = try (try py.PyString.checked(item.k)).asSlice(); - try kwargs.put(key, item.v); + // The caller is responsible for invoking deinit on the returned struct. + pub inline fn unwrapCallArgs(pyargs: ?py.PyTuple, pykwargs: ?py.PyDict) PyError!ZigCallArgs { + return ZigCallArgs.unwrap(pyargs, pykwargs); + } + + const ZigCallArgs = struct { + argsStruct: T, + + pub fn unwrap(pyargs: ?py.PyTuple, pykwargs: ?py.PyDict) PyError!T { + var kwargs = py.Kwargs.init(py.allocator); + if (pykwargs) |kw| { + var iter = kw.itemsIterator(); + while (iter.next()) |item| { + const key: []const u8 = try (try py.PyString.checked(item.k)).asSlice(); + try kwargs.put(key, item.v); + } } - } - const args = try py.allocator.alloc(py.PyObject, if (pyargs) |a| a.length() else 0); - defer py.allocator.free(args); - if (pyargs) |a| { - for (0..a.length()) |i| { - args[i] = try a.getItem(py.PyObject, i); + const args = try py.allocator.alloc(py.PyObject, if (pyargs) |a| a.length() else 0); + if (pyargs) |a| { + for (0..a.length()) |i| { + args[i] = try a.getItem(py.PyObject, i); + } } + + return .{ .argsStruct = funcs.unwrapArgs(T, args, kwargs) }; } - return funcs.unwrapArgs(T, args, kwargs); - } + pub fn deinit(self: @This()) void { + funcs.deinitArgs(self.argsStruct); + } + }; }; }