@@ -144,6 +144,16 @@ pub inline fn attributeErrorObject(comptime value: anytype, msg: [:0]const u8, a
144144 return value ;
145145}
146146
147+ // Helper that is the equivalent to `KeyError(msg)`
148+ pub inline fn keyError (msg : [:0 ]const u8 , args : anytype ) ! void {
149+ return errorFormat (@ptrCast (c .PyExc_KeyError ), msg , args );
150+ }
151+
152+ pub inline fn keyErrorObject (comptime value : anytype , msg : [:0 ]const u8 , args : anytype ) @TypeOf (value ) {
153+ keyError (msg , args ) catch {};
154+ return value ;
155+ }
156+
147157pub inline fn memoryError () ! void {
148158 _ = c .PyErr_NoMemory ();
149159 return error .PyError ;
@@ -1030,19 +1040,20 @@ pub const Int = extern struct {
10301040 return c .PyIndex_Check (@as ([* c ]c .PyObject , @constCast (@ptrCast (obj )))) != 0 ;
10311041 }
10321042
1033- // Convert to the given zig type
1043+ // Convert to the given zig type. If it cannot be safely casted it
1044+ // will raise a ValueError("int out of range for T")
10341045 pub inline fn as (self : * Int , comptime T : type ) ! T {
10351046 comptime var error_value = -1 ;
10361047 const n = @bitSizeOf (c_long );
1037- const r : T = switch (@typeInfo (T )) {
1048+ const r : ? T = switch (@typeInfo (T )) {
10381049 .Int = > | info | switch (info .bits ) {
1039- 0... n = > @intCast ( if (info .signedness == .signed )
1050+ 0... n = > std . math . cast ( T , if (info .signedness == .signed )
10401051 c .PyLong_AsLong (@ptrCast (self ))
10411052 else blk : {
10421053 error_value = std .math .maxInt (c_ulong ); // Update error value
10431054 break :blk c .PyLong_AsUnsignedLong (@ptrCast (self ));
10441055 }),
1045- else = > @intCast ( if (info .signedness == .signed )
1056+ else = > std . math . cast ( T , if (info .signedness == .signed )
10461057 c .PyLong_AsLongLong (@ptrCast (self ))
10471058 else blk : {
10481059 error_value = std .math .maxInt (c_ulonglong ); // Update error value
@@ -1052,11 +1063,14 @@ pub const Int = extern struct {
10521063 .Float = > @floatCast (c .PyLong_AsDouble (@ptrCast (self ))),
10531064 else = > @compileError ("Cannot convert python in to " ++ @typeName (T )),
10541065 };
1055-
1056- if (r == error_value and errorOccurred () != null ) {
1057- return error .PyError ;
1066+ if (r ) | value | {
1067+ if (value == error_value and errorOccurred () != null ) {
1068+ return error .PyError ;
1069+ }
1070+ return value ;
10581071 }
1059- return r ;
1072+ try valueError ("int out of range for {s}" , .{@typeName (T )});
1073+ unreachable ;
10601074 }
10611075
10621076 // Create a pyton Int from any zig integer or float type. This will
0 commit comments