Skip to content

Commit 0837052

Browse files
committed
Add Type.create, newIntFlag and newIntEnum
1 parent 953d8ae commit 0837052

File tree

1 file changed

+63
-3
lines changed

1 file changed

+63
-3
lines changed

py.zig

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ pub inline fn clear(obj: anytype) void {
168168
} else if (comptime canCastToObjectPtr(T)) {
169169
setref(@ptrCast(obj), undefined);
170170
} else {
171-
@compileError(std.fmt.comptimePrint("py.clear argument must be castable to **Object or *?*Object, got: {s}", .{T}));
171+
@compileError(std.fmt.comptimePrint("py.clear argument must be castable to **Object or *?*Object, got: {s}", .{@typeName(T)}));
172172
}
173173
}
174174

@@ -299,6 +299,58 @@ pub inline fn parseTupleAndKeywords(args: *Tuple, kwargs: ?*Dict, format: [:0]co
299299
}
300300
}
301301

302+
// Create a python enum.IntFlag for the given enum
303+
// Returns new reference
304+
pub fn newIntEnum(comptime T: type) !*Object {
305+
const fields = @typeInfo(T).Enum.fields;
306+
const enum_mod = try importModule("enum");
307+
defer enum_mod.decref();
308+
309+
const cls = try enum_mod.getAttrString("IntEnum");
310+
defer cls.decref();
311+
if (!Type.check(cls)) {
312+
try typeError("enum.IntEnum is not a valid type", .{});
313+
}
314+
const items = try Tuple.new(fields.len);
315+
defer items.decref();
316+
inline for (fields, 0..) |f, i| {
317+
const entry = try Tuple.packStolen(.{
318+
try Str.fromSlice(f.name),
319+
try Int.new(f.value),
320+
});
321+
items.setUnsafe(i, @ptrCast(entry)); // steals
322+
}
323+
const name = try Str.fromSlice(@typeName(T));
324+
defer name.decref();
325+
return cls.callArgs(.{ name, items });
326+
}
327+
328+
// Create a python enum.IntFlag for the given enum
329+
// Returns new reference
330+
pub fn newIntFlag(comptime T: type) !*Object {
331+
const fields = @typeInfo(T).Enum.fields;
332+
const enum_mod = try importModule("enum");
333+
defer enum_mod.decref();
334+
335+
const cls = try enum_mod.getAttrString("IntFlag");
336+
defer cls.decref();
337+
if (!Type.check(cls)) {
338+
try typeError("enum.IntFlag is not a valid type", .{});
339+
}
340+
const items = try Tuple.new(fields.len);
341+
defer items.decref();
342+
inline for (fields, 0..) |f, i| {
343+
const entry = try Tuple.packStolen(.{
344+
try Str.fromSlice(f.name),
345+
try Int.new(f.value),
346+
});
347+
items.setUnsafe(i, @ptrCast(entry)); // steals
348+
}
349+
const name = try Str.fromSlice(@typeName(T));
350+
defer name.decref();
351+
return cls.callArgs(.{ name, items });
352+
}
353+
302354
// Check that the given type can be safely casted to a *Object
303355
pub inline fn canCastToObject(comptime T: type) bool {
304356
return switch (@typeInfo(T)) {
@@ -910,7 +962,7 @@ pub const Type = extern struct {
910962
// Import the object protocol
911963
pub usingnamespace ObjectProtocol(@This());
912964

913-
// Create a new type.
965+
// Create a new type using a metaclass.
914966
// This is equivalent to the Python expression: type.__new__(self, name, bases, dict)
915967
// Returns new reference
916968
pub inline fn new(meta: *Type, name: *Str, bases: *Tuple, dict: *Dict) !*Object {
@@ -919,6 +971,14 @@ pub const Type = extern struct {
919971
return try builtin_type.callMethod(new_str, .{ meta, name, bases, dict });
920972
}
921973

974+
// Create a new type by calling the builtin type function
975+
// This is equivalent to the Python expression: type(name, bases, dict)
976+
// Returns new reference
977+
pub inline fn create(name: *Str, bases: *Tuple, dict: *Dict) !*Object {
978+
const builtin_type: *Object = @ptrCast(&c.PyType_Type);
979+
return try builtin_type.callArgs(.{ name, bases, dict });
980+
}
981+
922982
// Generic handler for the tp_new slot of a type object.
923983
// Calls PyType_GenericNew.
924984
// Create a new instance using the type’s tp_alloc slot.
@@ -1408,7 +1468,7 @@ pub const Tuple = extern struct {
14081468
if (!comptime canCastToObject(ArgType)) {
14091469
@compileError("Cannot pack tuple with non *Object type: " ++ @typeName(ArgType));
14101470
}
1411-
tuple.setUnsafe(i, arg);
1471+
tuple.setUnsafe(i, @ptrCast(arg));
14121472
}
14131473
return tuple;
14141474
}

0 commit comments

Comments
 (0)