Skip to content

Commit 9cb4645

Browse files
committed
Accept buffer objects as input to int()
1 parent bf8f474 commit 9cb4645

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinConstructors.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,7 @@ private HashingCollectionNodes.SetItemNode getSetItemNode() {
11401140
// int(x, base=10)
11411141
@Builtin(name = INT, minNumOfPositionalArgs = 1, parameterNames = {"cls", "x", "base"}, numOfPositionalOnlyArgs = 2, constructsClass = PythonBuiltinClassType.PInt)
11421142
@GenerateNodeFactory
1143+
@ReportPolymorphism
11431144
public abstract static class IntNode extends PythonTernaryBuiltinNode {
11441145

11451146
private final ConditionProfile invalidBase = ConditionProfile.createBinaryProfile();
@@ -1528,8 +1529,9 @@ Object fail(Object cls, Object arg, Object base) {
15281529
throw raise(TypeError, ErrorMessages.INT_CANT_CONVERT_STRING_WITH_EXPL_BASE);
15291530
}
15301531

1531-
@Specialization(guards = {"isNoValue(base)", "!isNoValue(obj)", "!isHandledType(obj)"})
1532-
Object createIntGeneric(VirtualFrame frame, Object cls, Object obj, @SuppressWarnings("unused") PNone base) {
1532+
@Specialization(guards = {"isNoValue(base)", "!isNoValue(obj)", "!isHandledType(obj)"}, limit = "2")
1533+
Object createIntGeneric(VirtualFrame frame, Object cls, Object obj, @SuppressWarnings("unused") PNone base,
1534+
@CachedLibrary("obj") PythonObjectLibrary lib) {
15331535
// This method (together with callInt and callIndex) reflects the logic of PyNumber_Long
15341536
// in CPython. We don't use PythonObjectLibrary here since the original CPython function
15351537
// does not use any of the conversion functions (such as _PyLong_AsInt or
@@ -1545,7 +1547,17 @@ Object createIntGeneric(VirtualFrame frame, Object cls, Object obj, @SuppressWar
15451547
if (result == PNone.NO_VALUE) {
15461548
Object truncResult = callTrunc(frame, obj);
15471549
if (truncResult == PNone.NO_VALUE) {
1548-
throw raise(TypeError, ErrorMessages.ARG_MUST_BE_STRING_OR_BYTELIKE_OR_NUMBER, "int()", obj);
1550+
if (lib.isBuffer(obj)) {
1551+
try {
1552+
byte[] bytes = lib.getBufferBytes(obj);
1553+
return stringToInt(frame, cls, toString(bytes), 10, obj);
1554+
} catch (UnsupportedMessageException e) {
1555+
CompilerDirectives.transferToInterpreterAndInvalidate();
1556+
throw new IllegalStateException("Object claims to be a buffer but does not support getBufferBytes()");
1557+
}
1558+
} else {
1559+
throw raise(TypeError, ErrorMessages.ARG_MUST_BE_STRING_OR_BYTELIKE_OR_NUMBER, "int()", obj);
1560+
}
15491561
}
15501562
if (isIntegerType(truncResult)) {
15511563
result = truncResult;

0 commit comments

Comments
 (0)