86
86
import com .oracle .graal .python .builtins .objects .function .PArguments ;
87
87
import com .oracle .graal .python .builtins .objects .list .PList ;
88
88
import com .oracle .graal .python .builtins .objects .module .PythonModule ;
89
+ import com .oracle .graal .python .builtins .objects .str .StringNodes ;
89
90
import com .oracle .graal .python .builtins .objects .tuple .PTuple ;
90
91
import com .oracle .graal .python .builtins .objects .type .TypeNodes ;
91
92
import com .oracle .graal .python .lib .PyCallableCheckNode ;
137
138
import com .oracle .truffle .api .frame .Frame ;
138
139
import com .oracle .truffle .api .frame .VirtualFrame ;
139
140
import com .oracle .truffle .api .nodes .Node ;
141
+ import com .oracle .truffle .api .nodes .RootNode ;
140
142
import com .oracle .truffle .api .profiles .BranchProfile ;
141
143
import com .oracle .truffle .api .strings .TruffleString ;
142
144
@@ -402,13 +404,37 @@ private PDict getGlobalsDict(Object globals) {
402
404
return getDictFromGlobalsNode .executeCached (globals );
403
405
}
404
406
405
- private PFrame getCallerFrame (VirtualFrame frame , int stackLevel ) {
407
+ private PFrame getCallerFrame (VirtualFrame frame , int stackLevel , TruffleString [] skipFilePrefixes ) {
406
408
if (readCallerNode == null ) {
407
409
CompilerDirectives .transferToInterpreterAndInvalidate ();
408
410
reportPolymorphicSpecialize ();
409
411
readCallerNode = insert (ReadCallerFrameNode .create ());
410
412
}
411
- return readCallerNode .executeWith (PArguments .getCurrentFrameInfo (frame ), ReadCallerFrameNode .FrameSelector .SKIP_INTERNAL , stackLevel );
413
+ PFrame .Reference ref = PArguments .getCurrentFrameInfo (frame );
414
+ ReadCallerFrameNode .FrameSelector selector = ReadCallerFrameNode .SkipInternalFramesSelector .INSTANCE ;
415
+ if (skipFilePrefixes != null ) {
416
+ /*
417
+ * CPython would always count the first frame into the stacklevel even if it is
418
+ * supposed to be skipped. We do that too, but our code is one off because of the
419
+ * builtin frame. Let's just assume the common case where the first python frame is
420
+ * always skipped by the filter.
421
+ */
422
+ stackLevel --;
423
+ selector = rootNode -> ReadCallerFrameNode .SkipInternalFramesSelector .INSTANCE .skip (rootNode ) || isFilenameToSkip (skipFilePrefixes , rootNode );
424
+ }
425
+ return readCallerNode .executeWith (ref , selector , stackLevel );
426
+ }
427
+
428
+ @ TruffleBoundary
429
+ private static boolean isFilenameToSkip (TruffleString [] skipFilePrefixes , RootNode rootNode ) {
430
+ TruffleString fileName = PCode .extractFileName (rootNode );
431
+ for (TruffleString prefix : skipFilePrefixes ) {
432
+ if (fileName .byteLength (TS_ENCODING ) >= prefix .byteLength (TS_ENCODING ) &&
433
+ prefix .regionEqualByteIndexUncached (0 , fileName , 0 , prefix .byteLength (TS_ENCODING ), TS_ENCODING )) {
434
+ return true ;
435
+ }
436
+ }
437
+ return false ;
412
438
}
413
439
414
440
// _Warnings_GetState split up
@@ -852,10 +878,10 @@ private void warnExplicitPart2(PythonContext context, PythonModule warnings, Tru
852
878
/**
853
879
* Used from doWarn. On the fast path.
854
880
*/
855
- private void setupContext (VirtualFrame frame , int stackLevel , TruffleString [] filename , int [] lineno , TruffleString [] module , Object [] registry ) {
881
+ private void setupContext (VirtualFrame frame , int stackLevel , TruffleString [] skipFilePrefixes , TruffleString [] filename , int [] lineno , TruffleString [] module , Object [] registry ) {
856
882
// the stack level for the intrinsified version is off-by-one compared to the Python
857
883
// version
858
- PFrame f = frame == null ? null : getCallerFrame (frame , stackLevel - 1 );
884
+ PFrame f = frame == null ? null : getCallerFrame (frame , stackLevel - 1 , skipFilePrefixes );
859
885
PDict globals ;
860
886
if (f == null || f .getGlobals () == null ) {
861
887
globals = getSysDict ();
@@ -910,12 +936,12 @@ private Object getCategory(VirtualFrame frame, Object message, Object category)
910
936
*/
911
937
private void doWarn (VirtualFrame frame , PythonModule warnings ,
912
938
Object message , Object category , int stackLevel , Object source ,
913
- IndirectCallData indirectCallData ) {
939
+ IndirectCallData indirectCallData , TruffleString [] skipFilePrefixes ) {
914
940
TruffleString [] filename = new TruffleString [1 ];
915
941
int [] lineno = new int [1 ];
916
942
TruffleString [] module = new TruffleString [1 ];
917
943
Object [] registry = new Object [1 ];
918
- setupContext (frame , stackLevel , filename , lineno , module , registry );
944
+ setupContext (frame , stackLevel , skipFilePrefixes , filename , lineno , module , registry );
919
945
warnExplicit (frame , warnings , category , message , filename [0 ], lineno [0 ], module [0 ], registry [0 ], null , source , indirectCallData );
920
946
}
921
947
@@ -956,7 +982,8 @@ private static TruffleString getSourceLine(Node node, PDict globals, int lineno)
956
982
}
957
983
}
958
984
959
- @ Builtin (name = J_WARN , minNumOfPositionalArgs = 2 , parameterNames = {"$mod" , "message" , "category" , "stacklevel" , "source" }, declaresExplicitSelf = true , alwaysNeedsCallerFrame = true )
985
+ @ Builtin (name = J_WARN , minNumOfPositionalArgs = 2 , parameterNames = {"$mod" , "message" , "category" , "stacklevel" , "source" ,
986
+ "skip_file_prefixes" }, declaresExplicitSelf = true , alwaysNeedsCallerFrame = true )
960
987
@ ArgumentClinic (name = "category" , defaultValue = "PNone.NONE" )
961
988
@ ArgumentClinic (name = "stacklevel" , conversion = ClinicConversion .Int , defaultValue = "1" )
962
989
@ ArgumentClinic (name = "source" , defaultValue = "PNone.NONE" )
@@ -967,14 +994,34 @@ protected ArgumentClinicProvider getArgumentClinic() {
967
994
return WarnBuiltinNodeClinicProviderGen .INSTANCE ;
968
995
}
969
996
970
- public abstract Object execute (VirtualFrame frame , PythonModule mod , Object message , Object category , int stacklevel , Object source );
997
+ public abstract Object execute (VirtualFrame frame , PythonModule mod , Object message , Object category , int stacklevel , Object source , Object skipFilePrefixes );
971
998
972
999
@ Specialization
973
- Object doWarn (VirtualFrame frame , PythonModule mod , Object message , Object category , int stacklevel , Object source ,
1000
+ Object doWarn (VirtualFrame frame , PythonModule mod , Object message , Object category , int stacklevel , Object source , Object skipFilePrefixesObj ,
1001
+ @ Bind Node inliningTarget ,
974
1002
@ Cached ("createFor(this)" ) IndirectCallData indirectCallData ,
1003
+ @ Cached SequenceStorageNodes .GetItemScalarNode getItemScalarNode ,
1004
+ @ Cached StringNodes .CastToTruffleStringCheckedNode castToStringChecked ,
1005
+ @ Cached PRaiseNode raiseNode ,
975
1006
@ Cached WarningsModuleNode moduleFunctionsNode ) {
976
1007
// warnings_warn_impl
977
- moduleFunctionsNode .doWarn (frame , mod , message , moduleFunctionsNode .getCategory (frame , message , category ), stacklevel , source , indirectCallData );
1008
+ TruffleString [] skipFilePrefixes = null ;
1009
+ if (skipFilePrefixesObj instanceof PTuple tuple ) {
1010
+ SequenceStorage storage = tuple .getSequenceStorage ();
1011
+ if (storage .length () > 0 ) {
1012
+ skipFilePrefixes = new TruffleString [storage .length ()];
1013
+ for (int i = 0 ; i < storage .length (); i ++) {
1014
+ Object item = getItemScalarNode .execute (inliningTarget , storage , i );
1015
+ skipFilePrefixes [i ] = castToStringChecked .cast (inliningTarget , item , ErrorMessages .FOUND_NON_STR_S_IN_SKIP_FILE_PREFIXES , item );
1016
+ }
1017
+ if (stacklevel < 2 ) {
1018
+ stacklevel = 2 ;
1019
+ }
1020
+ }
1021
+ } else if (skipFilePrefixesObj != PNone .NO_VALUE ) {
1022
+ throw raiseNode .raise (inliningTarget , PythonBuiltinClassType .TypeError );
1023
+ }
1024
+ moduleFunctionsNode .doWarn (frame , mod , message , moduleFunctionsNode .getCategory (frame , message , category ), stacklevel , source , indirectCallData , skipFilePrefixes );
978
1025
return PNone .NONE ;
979
1026
}
980
1027
@@ -1105,7 +1152,7 @@ protected void execute(Frame frame, Object source, Object category, TruffleStrin
1105
1152
CompilerDirectives .transferToInterpreterAndInvalidate ();
1106
1153
moduleFunctionsNode = insert (WarningsModuleNode .create ());
1107
1154
}
1108
- moduleFunctionsNode .doWarn ((VirtualFrame ) frame , _warnings , message , category , stackLevel , source , indirectCallData );
1155
+ moduleFunctionsNode .doWarn ((VirtualFrame ) frame , _warnings , message , category , stackLevel , source , indirectCallData , null );
1109
1156
}
1110
1157
1111
1158
/*
0 commit comments