diff --git a/pydust/src/functions.zig b/pydust/src/functions.zig index c67befa4..2ccf6496 100644 --- a/pydust/src/functions.zig +++ b/pydust/src/functions.zig @@ -490,6 +490,7 @@ fn sigArgs(comptime sig: Signature) ![]const []const u8 { const fields = @typeInfo(Args).Struct.fields; var inKwargs = false; + var inVarargs = false; for (fields) |field| { if (field.default_value) |def| { // We have a kwarg @@ -503,12 +504,19 @@ fn sigArgs(comptime sig: Signature) ![]const []const u8 { try sigargs.append(std.fmt.comptimePrint("{s}={s}", .{ field.name, valueToStr(field.type, def) })); } else if (field.type == py.Args) { + if (!inVarargs) { + inVarargs = true; + // Marker for end of positional only args + try sigargs.append("/"); + } try sigargs.append(std.fmt.comptimePrint("*{s}", .{field.name})); } else if (field.type == py.Kwargs) { if (!inKwargs) { inKwargs = true; - // Marker for end of positional only args - try sigargs.append("/"); + if (!inVarargs) { + // Marker for end of positional only args unless varargs (*args) is present + try sigargs.append("/"); + } // Note: we don't mark the start of keyword only args since that's implied by **. // See https://bugs.python.org/issue2613 } diff --git a/pydust/src/modules.zig b/pydust/src/modules.zig index 47db6ffa..b1eebd85 100644 --- a/pydust/src/modules.zig +++ b/pydust/src/modules.zig @@ -53,15 +53,7 @@ pub fn Module(comptime name: [:0]const u8, comptime definition: type) type { pub fn init() !py.PyObject { const pyModuleDef = try py.allocator.create(ffi.PyModuleDef); pyModuleDef.* = ffi.PyModuleDef{ - .m_base = ffi.PyModuleDef_Base{ - .ob_base = @bitCast(CPyObject{ - .ob_refcnt = 1, - .ob_type = null, - }), - .m_init = null, - .m_index = 0, - .m_copy = null, - }, + .m_base = std.mem.zeroes(ffi.PyModuleDef_Base), .m_name = name.ptr, .m_doc = if (doc) |d| d.ptr else null, .m_size = @sizeOf(definition), @@ -71,6 +63,11 @@ pub fn Module(comptime name: [:0]const u8, comptime definition: type) type { .m_clear = null, .m_free = if (@hasDecl(definition, "__del__")) &Fns.free else null, }; + + // Set reference count to 1 so that it is not freed. + const local_obj: *CPyObject = @ptrCast(&pyModuleDef.m_base.ob_base); + local_obj.ob_refcnt = 1; + return .{ .py = ffi.PyModuleDef_Init(pyModuleDef) orelse return PyError.PyRaised }; } }; diff --git a/test/test_functions.py b/test/test_functions.py index 5e9d9b36..4df32cc6 100644 --- a/test/test_functions.py +++ b/test/test_functions.py @@ -59,7 +59,7 @@ def test_variadic(): functions.variadic() assert str(exc_info.value) == "Expected 1 arg" - assert functions.variadic.__text_signature__ == "(hello, *args, /, **kwargs)" + assert functions.variadic.__text_signature__ == "(hello, /, *args, **kwargs)" assert inspect.signature(functions.variadic) == inspect.Signature( [ inspect.Parameter("hello", kind=inspect._ParameterKind.POSITIONAL_ONLY),