Skip to content

Commit f262e4b

Browse files
committed
raise warning when __index__ returns int subtype
1 parent f856bf8 commit f262e4b

File tree

5 files changed

+57
-14
lines changed

5 files changed

+57
-14
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,9 @@ public boolean doString(String arg1, String arg2) {
185185
@GenerateNodeFactory
186186
abstract static class IndexNode extends PythonUnaryBuiltinNode {
187187
@Specialization(limit = "getCallSiteInlineCacheMaxDepth()")
188-
Object asIndex(Object value,
188+
Object asIndex(VirtualFrame frame, Object value,
189189
@CachedLibrary(value = "value") PythonObjectLibrary pol) {
190-
return pol.asIndex(value);
190+
return pol.asIndexWithFrame(value, frame);
191191
}
192192
}
193193
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
7979
import com.oracle.graal.python.builtins.modules.BuiltinFunctions;
8080
import com.oracle.graal.python.builtins.modules.MathGuards;
81+
import com.oracle.graal.python.builtins.modules.WarningsModuleBuiltins.WarnNode;
8182
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
8283
import com.oracle.graal.python.builtins.objects.cext.capi.CApiGuards;
8384
import com.oracle.graal.python.builtins.objects.cext.capi.DynamicObjectNativeWrapper;
@@ -238,7 +239,7 @@ public void writeMember(String key, Object value,
238239
@Exclusive @Cached KeyForAttributeAccess getAttributeKey,
239240
@Exclusive @Cached KeyForItemAccess getItemKey,
240241
@Cached PInteropSetAttributeNode writeNode,
241-
@Exclusive @Cached IsBuiltinClassProfile attrErrorProfile) throws UnsupportedMessageException, UnknownIdentifierException {
242+
@Shared("attributeErrorProfile") @Cached IsBuiltinClassProfile attrErrorProfile) throws UnsupportedMessageException, UnknownIdentifierException {
242243
try {
243244
String attrKey = getAttributeKey.execute(key);
244245
if (attrKey != null) {
@@ -490,7 +491,7 @@ public Object invokeMember(String member, Object[] arguments,
490491
@Exclusive @Cached PExecuteNode executeNode,
491492
@Exclusive @Cached ConditionProfile profileGetattribute,
492493
@Exclusive @Cached ConditionProfile profileMember,
493-
@Exclusive @Cached IsBuiltinClassProfile attributeErrorProfile) throws UnknownIdentifierException, UnsupportedMessageException {
494+
@Shared("attributeErrorProfile") @Cached IsBuiltinClassProfile attributeErrorProfile) throws UnknownIdentifierException, UnsupportedMessageException {
494495
Object memberObj;
495496
try {
496497
Object attrGetattribute = lookupGetattributeNode.execute(this, __GETATTRIBUTE__);
@@ -569,7 +570,7 @@ public void removeMember(String member,
569570
@Exclusive @Cached LookupInheritedAttributeNode.Dynamic getDelItemNode,
570571
@Cached PInteropDeleteAttributeNode deleteAttributeNode,
571572
@Exclusive @Cached PInteropDeleteItemNode delItemNode,
572-
@Exclusive @Cached IsBuiltinClassProfile attrErrorProfile) throws UnsupportedMessageException, UnknownIdentifierException {
573+
@Shared("attributeErrorProfile") @Cached IsBuiltinClassProfile attrErrorProfile) throws UnsupportedMessageException, UnknownIdentifierException {
573574
try {
574575
String attrKey = getAttributeKey.execute(member);
575576
if (attrKey != null) {
@@ -825,7 +826,10 @@ public Object asIndexWithState(ThreadState state,
825826
@Shared("raise") @Cached PRaiseNode raise,
826827
@Shared("isSubtypeNode") @Cached IsSubtypeNode isSubtype,
827828
@Exclusive @Cached ConditionProfile noIndex,
828-
@Exclusive @Cached ConditionProfile resultProfile) {
829+
@Exclusive @Cached ConditionProfile resultProfile,
830+
@Shared("gotState") @Cached ConditionProfile gotState,
831+
@Shared("intProfile") @Cached IsBuiltinClassProfile isInt,
832+
@Cached WarnNode warnNode) {
829833
// n.b.: the CPython shortcut "if (PyLong_Check(item)) return item;" is
830834
// implemented in the specific Java classes PInt, PythonNativeVoidPtr,
831835
// and PythonAbstractNativeObject and dispatched polymorphically
@@ -835,10 +839,18 @@ public Object asIndexWithState(ThreadState state,
835839
}
836840

837841
Object result = methodLib.callUnboundMethodWithState(indexMethod, state, this);
838-
839842
if (resultProfile.profile(!isSubtype.execute(resultLib.getLazyPythonClass(result), PythonBuiltinClassType.PInt))) {
840843
throw raise.raise(PythonBuiltinClassType.TypeError, ErrorMessages.INDEX_RETURNED_NON_INT, result);
841844
}
845+
if (!isInt.profileObject(result, PythonBuiltinClassType.PInt)){
846+
VirtualFrame frame = null;
847+
if (gotState.profile(state != null)) {
848+
frame = PArguments.frameForCall(state);
849+
}
850+
warnNode.warnFormat(frame, null, PythonBuiltinClassType.DeprecationWarning, 1,
851+
ErrorMessages.P_RETURNED_NON_P,
852+
this, "__index__", "int", result, "int");
853+
}
842854
return result;
843855
}
844856

@@ -884,10 +896,9 @@ public static Object asPString(PythonObjectLibrary lib, Object receiver, ThreadS
884896
public int asFileDescriptorWithState(ThreadState state,
885897
@CachedLibrary("this") PythonObjectLibrary lib,
886898
@Shared("methodLib") @CachedLibrary(limit = "2") PythonObjectLibrary methodLib,
887-
@CachedLibrary(limit = "1") PythonObjectLibrary libResult,
888899
@Shared("raise") @Cached PRaiseNode raiseNode,
889900
@Exclusive @Cached BranchProfile noFilenoMethodProfile,
890-
@Exclusive @Cached IsBuiltinClassProfile isIntProfile,
901+
@Shared("intProfile") @Cached IsBuiltinClassProfile isIntProfile,
891902
@Exclusive @Cached CastToJavaIntExactNode castToJavaIntNode,
892903
@Exclusive @Cached IsBuiltinClassProfile isAttrError) {
893904

@@ -898,7 +909,7 @@ public int asFileDescriptorWithState(ThreadState state,
898909
}
899910

900911
Object result = methodLib.callObjectWithState(filenoFunc, state);
901-
if (isIntProfile.profileClass(libResult.getLazyPythonClass(result), PythonBuiltinClassType.PInt)) {
912+
if (isIntProfile.profileObject(result, PythonBuiltinClassType.PInt)) {
902913
try {
903914
return castToJavaIntNode.execute(result);
904915
} catch (PException e) {

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747

4848
import com.oracle.graal.python.PythonLanguage;
4949
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
50+
import com.oracle.graal.python.builtins.modules.WarningsModuleBuiltins.WarnNode;
5051
import com.oracle.graal.python.builtins.objects.PNone;
5152
import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
5253
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.AsPythonObjectNode;
@@ -57,6 +58,7 @@
5758
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodesFactory.AsPythonObjectNodeGen;
5859
import com.oracle.graal.python.builtins.objects.cext.capi.NativeMember;
5960
import com.oracle.graal.python.builtins.objects.dict.PDict;
61+
import com.oracle.graal.python.builtins.objects.function.PArguments;
6062
import com.oracle.graal.python.builtins.objects.function.PArguments.ThreadState;
6163
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
6264
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
@@ -65,6 +67,7 @@
6567
import com.oracle.graal.python.nodes.ErrorMessages;
6668
import com.oracle.graal.python.nodes.PRaiseNode;
6769
import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
70+
import com.oracle.graal.python.nodes.object.IsBuiltinClassProfile;
6871
import com.oracle.truffle.api.Assumption;
6972
import com.oracle.truffle.api.CompilerAsserts;
7073
import com.oracle.truffle.api.CompilerDirectives;
@@ -75,6 +78,7 @@
7578
import com.oracle.truffle.api.dsl.Fallback;
7679
import com.oracle.truffle.api.dsl.GenerateUncached;
7780
import com.oracle.truffle.api.dsl.Specialization;
81+
import com.oracle.truffle.api.frame.VirtualFrame;
7882
import com.oracle.truffle.api.interop.InteropLibrary;
7983
import com.oracle.truffle.api.interop.TruffleObject;
8084
import com.oracle.truffle.api.interop.UnknownIdentifierException;
@@ -175,11 +179,23 @@ public Object asIndexWithState(ThreadState threadState,
175179
@CachedLibrary(limit = "5") PythonObjectLibrary resultLib,
176180
@Exclusive @Cached PRaiseNode raise,
177181
@Exclusive @Cached ConditionProfile noIndex,
178-
@Exclusive @Cached ConditionProfile resultProfile) {
182+
@Exclusive @Cached ConditionProfile resultProfile,
183+
@Exclusive @Cached ConditionProfile gotState,
184+
@Cached IsBuiltinClassProfile isInt,
185+
@Cached WarnNode warnNode) {
179186
if (isSubtypeNode.execute(plib.getLazyPythonClass(this), PythonBuiltinClassType.PInt)) {
187+
if (!isInt.profileObject(this, PythonBuiltinClassType.PInt)){
188+
VirtualFrame frame = null;
189+
if (gotState.profile(threadState != null)) {
190+
frame = PArguments.frameForCall(threadState);
191+
}
192+
warnNode.warnFormat(frame, null, PythonBuiltinClassType.DeprecationWarning, 1,
193+
ErrorMessages.P_RETURNED_NON_P,
194+
this, "__index__", "int", this, "int");
195+
}
180196
return this; // subclasses of 'int' should do early return
181197
} else {
182-
return asIndexWithState(threadState, plib, methodLib, resultLib, raise, isSubtypeNode, noIndex, resultProfile);
198+
return asIndexWithState(threadState, plib, methodLib, resultLib, raise, isSubtypeNode, noIndex, resultProfile, gotState, isInt, warnNode);
183199
}
184200
}
185201

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ints/PInt.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,15 @@
3232
import com.oracle.graal.python.PythonLanguage;
3333
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
3434
import com.oracle.graal.python.builtins.modules.SysModuleBuiltins;
35+
import com.oracle.graal.python.builtins.modules.WarningsModuleBuiltins.WarnNode;
3536
import com.oracle.graal.python.builtins.objects.cext.capi.PythonNativeWrapperLibrary;
37+
import com.oracle.graal.python.builtins.objects.function.PArguments;
3638
import com.oracle.graal.python.builtins.objects.function.PArguments.ThreadState;
3739
import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject;
3840
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
3941
import com.oracle.graal.python.nodes.ErrorMessages;
4042
import com.oracle.graal.python.nodes.PRaiseNode;
43+
import com.oracle.graal.python.nodes.object.IsBuiltinClassProfile;
4144
import com.oracle.graal.python.nodes.util.CastToJavaDoubleNode;
4245
import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode;
4346
import com.oracle.graal.python.nodes.util.CastToJavaLongLossyNode;
@@ -50,13 +53,15 @@
5053
import com.oracle.truffle.api.dsl.Cached.Exclusive;
5154
import com.oracle.truffle.api.dsl.Cached.Shared;
5255
import com.oracle.truffle.api.dsl.CachedContext;
56+
import com.oracle.truffle.api.frame.VirtualFrame;
5357
import com.oracle.truffle.api.interop.InteropLibrary;
5458
import com.oracle.truffle.api.interop.UnsupportedMessageException;
5559
import com.oracle.truffle.api.library.CachedLibrary;
5660
import com.oracle.truffle.api.library.ExportLibrary;
5761
import com.oracle.truffle.api.library.ExportMessage;
5862
import com.oracle.truffle.api.library.ExportMessage.Ignore;
5963
import com.oracle.truffle.api.object.Shape;
64+
import com.oracle.truffle.api.profiles.ConditionProfile;
6065

6166
@ExportLibrary(InteropLibrary.class)
6267
public final class PInt extends PythonBuiltinObject {
@@ -224,7 +229,19 @@ public boolean canBeIndex() {
224229
}
225230

226231
@ExportMessage
227-
public Object asIndexWithState(@SuppressWarnings("unused") ThreadState threadState) {
232+
public Object asIndexWithState(@SuppressWarnings("unused") ThreadState threadState,
233+
@Cached ConditionProfile gotState,
234+
@Cached IsBuiltinClassProfile isInt,
235+
@Cached WarnNode warnNode) {
236+
if (!isInt.profileObject(this, PythonBuiltinClassType.PInt)){
237+
VirtualFrame frame = null;
238+
if (gotState.profile(threadState != null)) {
239+
frame = PArguments.frameForCall(threadState);
240+
}
241+
warnNode.warnFormat(frame, null, PythonBuiltinClassType.DeprecationWarning, 1,
242+
ErrorMessages.P_RETURNED_NON_P,
243+
this, "__index__", "int", this, "int");
244+
}
228245
return this;
229246
}
230247

graalpython/lib-python/3/test/test_index.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ def __index__(self):
7171
self.assertIs(type(direct_index), int)
7272
#self.assertIs(type(operator_index), int)
7373

74-
@support.impl_detail("missing _warnings support", graalvm=False)
7574
def test_index_returns_int_subclass(self):
7675
class BadInt:
7776
def __index__(self):

0 commit comments

Comments
 (0)