Skip to content

Commit 72ed223

Browse files
committed
[GR-66462] Implement warnings.warn skip_file_prefixes argument
PullRequest: graalpython/3857
2 parents 04af035 + 99721de commit 72ed223

36 files changed

+407
-268
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
2+
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3+
#
4+
# The Universal Permissive License (UPL), Version 1.0
5+
#
6+
# Subject to the condition set forth below, permission is hereby granted to any
7+
# person obtaining a copy of this software, associated documentation and/or
8+
# data (collectively the "Software"), free of charge and under any and all
9+
# copyright rights in the Software, and any and all patent rights owned or
10+
# freely licensable by each licensor hereunder covering either (i) the
11+
# unmodified Software as contributed to or provided by such licensor, or (ii)
12+
# the Larger Works (as defined below), to deal in both
13+
#
14+
# (a) the Software, and
15+
#
16+
# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
17+
# one is included with the Software each a "Larger Work" to which the Software
18+
# is contributed by such licensors),
19+
#
20+
# without restriction, including without limitation the rights to copy, create
21+
# derivative works of, display, perform, and distribute the Software and make,
22+
# use, sell, offer for sale, import, export, have made, and have sold the
23+
# Software and the Larger Work(s), and to sublicense the foregoing rights on
24+
# either these or other terms.
25+
#
26+
# This license is subject to the following condition:
27+
#
28+
# The above copyright notice and either this complete permission notice or at a
29+
# minimum a reference to the UPL must be included in all copies or substantial
30+
# portions of the Software.
31+
#
32+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38+
# SOFTWARE.
39+
40+
import os
41+
import unittest
42+
import warnings
43+
from tests import warntest
44+
45+
46+
class TestWarnings(unittest.TestCase):
47+
def test_skip_file_prefixes(self):
48+
with warnings.catch_warnings(record=True) as w:
49+
# First check that the stacklevels behave as expected for the test module
50+
warntest.warn_indirect("Some warning")
51+
self.assertEqual(w[-1].filename, warntest.__file__)
52+
warntest.warn_indirect("Some warning", stacklevel=1)
53+
self.assertEqual(w[-1].filename, warntest.__file__)
54+
warntest.warn_indirect("Some warning", stacklevel=2)
55+
self.assertEqual(w[-1].filename, warntest.__file__)
56+
warntest.warn_indirect("Some warning", stacklevel=3)
57+
self.assertEqual(w[-1].filename, __file__)
58+
# Now test skip_file_prefixes
59+
warntest.warn_indirect("Some warning", skip_file_prefixes=(os.path.dirname(warntest.__file__),))
60+
self.assertEqual(w[-1].filename, __file__)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
2+
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3+
#
4+
# The Universal Permissive License (UPL), Version 1.0
5+
#
6+
# Subject to the condition set forth below, permission is hereby granted to any
7+
# person obtaining a copy of this software, associated documentation and/or
8+
# data (collectively the "Software"), free of charge and under any and all
9+
# copyright rights in the Software, and any and all patent rights owned or
10+
# freely licensable by each licensor hereunder covering either (i) the
11+
# unmodified Software as contributed to or provided by such licensor, or (ii)
12+
# the Larger Works (as defined below), to deal in both
13+
#
14+
# (a) the Software, and
15+
#
16+
# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
17+
# one is included with the Software each a "Larger Work" to which the Software
18+
# is contributed by such licensors),
19+
#
20+
# without restriction, including without limitation the rights to copy, create
21+
# derivative works of, display, perform, and distribute the Software and make,
22+
# use, sell, offer for sale, import, export, have made, and have sold the
23+
# Software and the Larger Work(s), and to sublicense the foregoing rights on
24+
# either these or other terms.
25+
#
26+
# This license is subject to the following condition:
27+
#
28+
# The above copyright notice and either this complete permission notice or at a
29+
# minimum a reference to the UPL must be included in all copies or substantial
30+
# portions of the Software.
31+
#
32+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38+
# SOFTWARE.
39+
40+
import warnings
41+
42+
def warn(*args, **kwargs):
43+
warnings.warn(*args, **kwargs)
44+
45+
46+
def warn_indirect(*args, **kwarg):
47+
warn(*args, **kwarg)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1209,7 +1209,7 @@ public static IndirectCallData lookupIndirectCallData(Node node) {
12091209

12101210
public static IndirectCallData createIndirectCallData(Node node) {
12111211
CompilerAsserts.neverPartOfCompilation();
1212-
return get(node).indirectCallDataMap.computeIfAbsent(node, n -> new IndirectCallData(node));
1212+
return get(node).indirectCallDataMap.computeIfAbsent(node, n -> new IndirectCallData());
12131213
}
12141214

12151215
public Source getOrCreateSource(Function<Object, Source> rootNodeFunction, Object key) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ public enum PythonBuiltinClassType implements TruffleObject {
310310
When called, it accepts no arguments and returns a new featureless
311311
instance that has no instance attributes and cannot be given any.
312312
""")),
313-
PythonClass("type", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(TypeBuiltins.SLOTS).doc("""
313+
PythonClass("type", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().addDict(264).slots(TypeBuiltins.SLOTS).doc("""
314314
type(object) -> the object's type
315315
type(name, bases, dict, **kwds) -> a new type""")),
316316
PArray("array", PythonObject, newBuilder().publishInModule("array").basetype().slots(ArrayBuiltins.SLOTS)),
@@ -361,7 +361,7 @@ public enum PythonBuiltinClassType implements TruffleObject {
361361
- any object implementing the buffer API.
362362
- an integer""")),
363363
PCell("cell", PythonObject, newBuilder().slots(CellBuiltins.SLOTS)),
364-
PSimpleNamespace("SimpleNamespace", PythonObject, newBuilder().publishInModule("types").basetype().addDict().slots(SimpleNamespaceBuiltins.SLOTS).doc("""
364+
PSimpleNamespace("SimpleNamespace", PythonObject, newBuilder().publishInModule("types").basetype().addDict(16).slots(SimpleNamespaceBuiltins.SLOTS).doc("""
365365
A simple attribute-based namespace.
366366
367367
SimpleNamespace(**kwargs)""")),
@@ -405,7 +405,7 @@ This is equivalent to (real + imag*1j) where imag defaults to 0.""")),
405405
dict(**kwargs) -> new dictionary initialized with the name=value pairs
406406
in the keyword argument list. For example: dict(one=1, two=2)""")),
407407
PDefaultDict(J_DEFAULTDICT, PDict, newBuilder().moduleName("collections").publishInModule("_collections").basetype().slots(DefaultDictBuiltins.SLOTS)),
408-
POrderedDict(J_ORDERED_DICT, PDict, newBuilder().publishInModule("_collections").basetype().addDict().slots(OrderedDictBuiltins.SLOTS)),
408+
POrderedDict(J_ORDERED_DICT, PDict, newBuilder().publishInModule("_collections").basetype().addDict(96).slots(OrderedDictBuiltins.SLOTS)),
409409
PDictItemIterator(J_DICT_ITEMITERATOR, PythonObject, newBuilder().disallowInstantiation().slots(IteratorBuiltins.SLOTS)),
410410
PDictReverseItemIterator(J_DICT_REVERSE_ITEMITERATOR, PythonObject, newBuilder().slots(IteratorBuiltins.SLOTS)),
411411
PDictItemsView(J_DICT_ITEMS, PythonObject, newBuilder().disallowInstantiation().slots(DictViewBuiltins.SLOTS, DictReprBuiltin.SLOTS)),
@@ -579,7 +579,7 @@ or repr(object).
579579
If iterable is specified the tuple is initialized from iterable's items.
580580
581581
If the argument is a tuple, the return value is the same object.""")),
582-
PythonModule("module", PythonObject, newBuilder().basetype().addDict().slots(ModuleBuiltins.SLOTS).doc("""
582+
PythonModule("module", PythonObject, newBuilder().basetype().addDict(16).slots(ModuleBuiltins.SLOTS).doc("""
583583
Create a module object.
584584
585585
The name must be a string; the optional doc argument can have any type.""")),
@@ -624,7 +624,7 @@ passed as positional arguments to zip(). The i-th element in every tuple
624624
PSemLock("SemLock", PythonObject, newBuilder().publishInModule("_multiprocessing").basetype().slots(SemLockBuiltins.SLOTS)),
625625
PGraalPySemLock("SemLock", PythonObject, newBuilder().publishInModule("_multiprocessing_graalpy").basetype().slots(GraalPySemLockBuiltins.SLOTS)),
626626
PSocket("socket", PythonObject, newBuilder().publishInModule(J__SOCKET).basetype().slots(SocketBuiltins.SLOTS)),
627-
PStaticmethod("staticmethod", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(StaticmethodBuiltins.SLOTS).doc("""
627+
PStaticmethod("staticmethod", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().addDict(24).slots(StaticmethodBuiltins.SLOTS).doc("""
628628
staticmethod(function) -> method
629629
630630
Convert a function to be a static method.
@@ -643,7 +643,7 @@ It can be called either on the class (e.g. C.f()) or on an instance
643643
644644
Static methods in Python are similar to those found in Java or C++.
645645
For a more advanced concept, see the classmethod builtin.""")),
646-
PClassmethod("classmethod", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(ClassmethodCommonBuiltins.SLOTS, ClassmethodBuiltins.SLOTS).doc("""
646+
PClassmethod("classmethod", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().addDict(24).slots(ClassmethodCommonBuiltins.SLOTS, ClassmethodBuiltins.SLOTS).doc("""
647647
classmethod(function) -> method
648648
649649
Convert a function to be a class method.
@@ -715,7 +715,7 @@ It can be called either on the class (e.g. C.f()) or on an instance
715715
// Errors and exceptions:
716716

717717
// everything after BaseException is considered to be an exception
718-
PBaseException("BaseException", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(BaseExceptionBuiltins.SLOTS).doc("""
718+
PBaseException("BaseException", PythonObject, newBuilder().publishInModule(J_BUILTINS).basetype().addDict(16).slots(BaseExceptionBuiltins.SLOTS).doc("""
719719
Common base class for all exceptions""")),
720720
PBaseExceptionGroup("BaseExceptionGroup", PBaseException, newBuilder().publishInModule(J_BUILTINS).basetype().addDict().slots(BaseExceptionGroupBuiltins.SLOTS).doc("""
721721
A combination of multiple unrelated exceptions.""")),
@@ -1440,6 +1440,7 @@ private static final class TypeBuilder {
14401440
private boolean basetype;
14411441
private boolean heaptype;
14421442
private boolean addDict;
1443+
private int dictoffset;
14431444
private boolean disallowInstantiation;
14441445
private TpSlots slots;
14451446
private String doc;
@@ -1472,6 +1473,12 @@ public TypeBuilder addDict() {
14721473
return this;
14731474
}
14741475

1476+
public TypeBuilder addDict(int dictoffset) {
1477+
this.addDict = true;
1478+
this.dictoffset = dictoffset;
1479+
return this;
1480+
}
1481+
14751482
public TypeBuilder disallowInstantiation() {
14761483
this.disallowInstantiation = true;
14771484
return this;
@@ -1507,6 +1514,7 @@ public TypeBuilder doc(String doc) {
15071514
private final TruffleString printName;
15081515
private final boolean basetype;
15091516
private final boolean isBuiltinWithDict;
1517+
private final int dictoffset;
15101518
private final boolean disallowInstantiation;
15111519
private final TruffleString doc;
15121520

@@ -1536,6 +1544,13 @@ public TypeBuilder doc(String doc) {
15361544
}
15371545
this.basetype = builder.basetype;
15381546
this.isBuiltinWithDict = builder.addDict;
1547+
int dictoffset = 0;
1548+
if (builder.dictoffset != 0) {
1549+
dictoffset = builder.dictoffset;
1550+
} else if (base != null) {
1551+
dictoffset = base.dictoffset;
1552+
}
1553+
this.dictoffset = dictoffset;
15391554
this.weaklistoffset = -1;
15401555
this.declaredSlots = builder.slots != null ? builder.slots : TpSlots.createEmpty();
15411556
boolean disallowInstantiation = builder.disallowInstantiation;
@@ -1582,6 +1597,10 @@ public boolean isBuiltinWithDict() {
15821597
return isBuiltinWithDict;
15831598
}
15841599

1600+
public int getDictoffset() {
1601+
return dictoffset;
1602+
}
1603+
15851604
public boolean disallowInstantiation() {
15861605
return disallowInstantiation;
15871606
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2514,12 +2514,12 @@ class InitializeBuildClass {
25142514
// will use the explicitly given object as it is
25152515
}
25162516
}
2517-
Object savedState = IndirectCallContext.enter(frame, indirectCallData);
2517+
Object savedState = IndirectCallContext.enter(frame, inliningTarget, indirectCallData);
25182518
InitializeBuildClass init;
25192519
try {
25202520
init = new InitializeBuildClass(ctx);
25212521
} finally {
2522-
IndirectCallContext.exit(frame, indirectCallData, savedState);
2522+
IndirectCallContext.exit(frame, inliningTarget, indirectCallData, savedState);
25232523
}
25242524

25252525
Object ns;

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
@@ -159,7 +159,7 @@ static boolean compare(VirtualFrame frame, Object left, Object right,
159159
if (!bufferAcquireLib.hasBuffer(left) || !bufferAcquireLib.hasBuffer(right)) {
160160
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_OR_COMBINATION_OF_TYPES, left, right);
161161
}
162-
Object savedState = IndirectCallContext.enter(frame, indirectCallData);
162+
Object savedState = IndirectCallContext.enter(frame, inliningTarget, indirectCallData);
163163
Object leftBuffer = bufferAcquireLib.acquireReadonly(left);
164164
try {
165165
Object rightBuffer = bufferAcquireLib.acquireReadonly(right);
@@ -170,7 +170,7 @@ static boolean compare(VirtualFrame frame, Object left, Object right,
170170
}
171171
} finally {
172172
bufferLib.release(leftBuffer);
173-
IndirectCallContext.exit(frame, indirectCallData, savedState);
173+
IndirectCallContext.exit(frame, inliningTarget, indirectCallData, savedState);
174174
}
175175
}
176176
}

0 commit comments

Comments
 (0)