Skip to content

Commit 980d063

Browse files
lukasstadlerfangerer
authored andcommitted
use lenient CPython behavior for uint CAPI members
1 parent 978145f commit 980d063

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_member.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,8 @@ def test_member(self):
228228
val = getattr(obj, m)
229229
assert val != min_values[i], "was: %r" % getattr(obj, m)
230230
assert_raises(TypeError, setattr, obj, m, "hello")
231+
assert_raises(OverflowError, setattr, obj, m, int(-1e40))
232+
assert_raises(OverflowError, setattr, obj, m, int(1e40))
231233

232234
# T_LONG, T_ULONG, T_PYSSIZET
233235
max_values = (0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiMemberAccessNodes.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
import com.oracle.graal.python.nodes.object.GetClassNode;
9090
import com.oracle.graal.python.nodes.object.IsBuiltinClassProfile;
9191
import com.oracle.graal.python.runtime.exception.PException;
92+
import com.oracle.graal.python.runtime.exception.PythonErrorType;
9293
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
9394
import com.oracle.truffle.api.CompilerAsserts;
9495
import com.oracle.truffle.api.CompilerDirectives;
@@ -437,8 +438,23 @@ abstract static class WriteUIntNode extends WriteTypeNode {
437438
@Specialization
438439
static void write(Object pointer, Object newValue,
439440
@Cached AsNativePrimitiveNode asLong,
440-
@Cached CStructAccess.WriteIntNode write) {
441-
write.write(pointer, (int) asLong.toUInt64(newValue, true));
441+
@Cached CStructAccess.WriteIntNode write,
442+
@Cached PRaiseNode raiseNode,
443+
@Cached IsBuiltinClassProfile exceptionProfile) {
444+
/*
445+
* This emulates the arguably buggy behavior from CPython where it accepts MIN_LONG to
446+
* MAX_ULONG values.
447+
*/
448+
try {
449+
write.write(pointer, (int) asLong.toUInt64(newValue, true));
450+
} catch (PException e) {
451+
/*
452+
* Special case: accept signed long as well.
453+
*/
454+
e.expectOverflowError(exceptionProfile);
455+
write.write(pointer, (int) asLong.toInt64(newValue, true));
456+
// swallowing the exception
457+
}
442458
}
443459
}
444460

0 commit comments

Comments
 (0)