Skip to content

Commit 1c6243e

Browse files
committed
[GR-34617] intrinsify sys.excepthook
PullRequest: graalpython/2010
2 parents 7f6eaba + a40775b commit 1c6243e

File tree

7 files changed

+640
-75
lines changed

7 files changed

+640
-75
lines changed

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

Lines changed: 543 additions & 7 deletions
Large diffs are not rendered by default.

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/traceback/LazyTraceback.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,16 @@
4040
*/
4141
package com.oracle.graal.python.builtins.objects.traceback;
4242

43+
import static com.oracle.graal.python.builtins.objects.traceback.PTraceback.UNKNOWN_LINE_NUMBER;
44+
4345
import com.oracle.graal.python.builtins.objects.frame.PFrame;
4446
import com.oracle.graal.python.builtins.objects.function.PArguments;
4547
import com.oracle.graal.python.runtime.exception.PException;
48+
import com.oracle.truffle.api.CompilerDirectives;
4649
import com.oracle.truffle.api.TruffleStackTraceElement;
4750
import com.oracle.truffle.api.frame.Frame;
4851
import com.oracle.truffle.api.nodes.Node;
52+
import com.oracle.truffle.api.source.SourceSection;
4953

5054
/**
5155
* A lazy representation of an exception traceback that can be evaluated to a python object by
@@ -111,6 +115,25 @@ public void setTraceback(PTraceback traceback) {
111115
this.materialized = true;
112116
}
113117

118+
@CompilerDirectives.TruffleBoundary
119+
public static int getSourceLineNoOrDefault(PException exception, int defaultValue) {
120+
final Node location = exception.getLocation();
121+
if (location != null) {
122+
final SourceSection sourceSection = location.getSourceSection();
123+
if (sourceSection != null) {
124+
return sourceSection.getStartLine();
125+
}
126+
}
127+
return defaultValue;
128+
}
129+
130+
public int getLineNo() {
131+
if (exception != null) {
132+
return getSourceLineNoOrDefault(exception, UNKNOWN_LINE_NUMBER);
133+
}
134+
return UNKNOWN_LINE_NUMBER;
135+
}
136+
114137
public boolean isMaterialized() {
115138
return materialized;
116139
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/traceback/PTraceback.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,11 @@
4747
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
4848

4949
public final class PTraceback extends PythonBuiltinObject {
50+
public static final int UNKNOWN_LINE_NUMBER = -2;
5051

5152
private PFrame frame;
5253
private PFrame.Reference frameInfo;
53-
private int lineno = -2;
54+
private int lineno = UNKNOWN_LINE_NUMBER;
5455
private int lasti;
5556
private PTraceback next;
5657
private LazyTraceback lazyTraceback;
@@ -72,6 +73,7 @@ public PTraceback(PythonLanguage lang, LazyTraceback lazyTraceback) {
7273
this.lazyTraceback = lazyTraceback;
7374
this.frameInfo = lazyTraceback.getFrameInfo();
7475
this.frame = lazyTraceback.getFrame();
76+
this.lineno = lazyTraceback.getLineNo();
7577
}
7678

7779
public PFrame getFrame() {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/traceback/TracebackBuiltins.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public Object dir(@SuppressWarnings("unused") PTraceback self) {
8484
*
8585
* @see GetTracebackNode
8686
*/
87-
abstract static class MaterializeTruffleStacktraceNode extends Node {
87+
public abstract static class MaterializeTruffleStacktraceNode extends Node {
8888
public abstract void execute(PTraceback tb);
8989

9090
@Specialization(guards = "tb.isMaterialized()")
@@ -186,6 +186,12 @@ private static PFrame materializeFrame(TruffleStackTraceElement element, Materia
186186
@Builtin(name = TB_FRAME, minNumOfPositionalArgs = 1, isGetter = true)
187187
@GenerateNodeFactory
188188
public abstract static class GetTracebackFrameNode extends PythonBuiltinNode {
189+
public abstract PFrame execute(VirtualFrame frame, Object traceback);
190+
191+
public static GetTracebackFrameNode create() {
192+
return TracebackBuiltinsFactory.GetTracebackFrameNodeFactory.create(null);
193+
}
194+
189195
@Specialization(guards = "hasPFrame(tb)")
190196
PFrame getExisting(PTraceback tb) {
191197
return tb.getFrame();

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/BuiltinNames.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,21 @@ public abstract class BuiltinNames {
5656
public static final String __DEBUG__ = "__debug__";
5757

5858
// sys
59+
public static final String TRACEBACKLIMIT = "tracebacklimit";
5960
public static final String DISPLAYHOOK = "displayhook";
6061
public static final String BREAKPOINTHOOK = "breakpointhook";
6162
public static final String EXCEPTHOOK = "excepthook";
6263
public static final String UNRAISABLEHOOK = "unraisablehook";
6364
public static final String LAST_TYPE = "last_type";
6465
public static final String LAST_VALUE = "last_value";
6566
public static final String LAST_TRACEBACK = "last_traceback";
67+
public static final String __EXCEPTHOOK__ = "__excepthook__";
68+
public static final String __STDERR__ = "__stderr__";
69+
public static final String STDERR = "stderr";
70+
public static final String __STDIN__ = "__stdin__";
71+
public static final String STDIN = "stdin";
72+
public static final String __STDOUT__ = "__stdout__";
73+
public static final String STDOUT = "stdout";
6674

6775
// builtin functions
6876
public static final String ABS = "abs";

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/util/PythonUtils.java

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,16 +412,44 @@ public static int indexOf(StringBuilder sb, String str, int start) {
412412
return sb.indexOf(str, start);
413413
}
414414

415+
@TruffleBoundary(allowInlining = true)
416+
public static String substring(String s, int start, int end) {
417+
return s.substring(start, end);
418+
}
419+
420+
@TruffleBoundary(allowInlining = true)
421+
public static String substring(String s, int start) {
422+
return s.substring(start);
423+
}
424+
425+
@TruffleBoundary(allowInlining = true)
426+
public static int lastIndexOf(String s, char chr) {
427+
return s.lastIndexOf(chr);
428+
}
429+
415430
@TruffleBoundary(allowInlining = true)
416431
public static StringBuilder append(StringBuilder sb, char c) {
417432
return sb.append(c);
418433
}
419434

435+
@TruffleBoundary(allowInlining = true)
436+
public static StringBuilder append(StringBuilder sb, Object... args) {
437+
for (Object arg : args) {
438+
sb.append(arg);
439+
}
440+
return sb;
441+
}
442+
420443
@TruffleBoundary(allowInlining = true)
421444
public static StringBuilder append(StringBuilder sb, String s) {
422445
return sb.append(s);
423446
}
424447

448+
@TruffleBoundary(allowInlining = true)
449+
public static StringBuilder append(StringBuilder sb, int i) {
450+
return sb.append(i);
451+
}
452+
425453
@TruffleBoundary(allowInlining = true)
426454
public static StringBuilder append(StringBuilder sb, String s, int start, int end) {
427455
return sb.append(s, start, end);
@@ -437,6 +465,34 @@ public static StringBuilder appendCodePoint(StringBuilder sb, int codePoint) {
437465
return sb.appendCodePoint(codePoint);
438466
}
439467

468+
@TruffleBoundary(allowInlining = true)
469+
public static String toString(CharSequence sequence) {
470+
return sequence.toString();
471+
}
472+
473+
@TruffleBoundary(allowInlining = true)
474+
public static String trim(String s) {
475+
return s.trim();
476+
}
477+
478+
@TruffleBoundary(allowInlining = true)
479+
public static String trim(CharSequence sequence) {
480+
return sequence.toString().trim();
481+
}
482+
483+
@TruffleBoundary(allowInlining = true)
484+
public static String trimLeft(CharSequence sequence) {
485+
int len = sequence.length();
486+
int st = 0;
487+
488+
while ((st < len) && (sequence.charAt(st) <= ' ')) {
489+
st++;
490+
}
491+
492+
final String s = sequence.toString();
493+
return (st > 0) ? substring(s, st, len) : s;
494+
}
495+
440496
@TruffleBoundary(allowInlining = true)
441497
public static int sbLength(StringBuilder sb) {
442498
return sb.length();

graalpython/lib-graalpython/sys.py

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -60,72 +60,6 @@ def exit(arg=None):
6060
raise SystemExit(code)
6161

6262

63-
def make_excepthook():
64-
def simple_print_traceback(e):
65-
print("Traceback (most recent call last):", file=stderr);
66-
tb = e.__traceback__
67-
while tb is not None:
68-
print(' File "%s", line %d, in %s' % (
69-
tb.tb_frame.f_code.co_filename,
70-
tb.tb_lineno,
71-
tb.tb_frame.f_code.co_name
72-
), file=stderr)
73-
tb = tb.tb_next
74-
msg = str(e)
75-
if msg:
76-
print("%s: %s" % (type(e).__qualname__, msg), file=stderr)
77-
else:
78-
print(type(e).__qualname__, file=stderr)
79-
80-
def __print_traceback__(typ, value, tb):
81-
if not isinstance(value, BaseException):
82-
msg = "TypeError: print_exception(): Exception expected for value, {} found\n".format(type(value).__name__)
83-
print(msg, file=stderr, end="")
84-
return
85-
try:
86-
# CPython's C traceback printer diverges from traceback.print_exception in some details marked as (*)
87-
import sys
88-
import traceback
89-
no_traceback = False
90-
limit = getattr(sys, 'tracebacklimit', None)
91-
if isinstance(limit, int):
92-
if limit <= 0:
93-
# (*) the C traceback printer does nothing if the limit is <= 0,
94-
# but the exception message is still printed
95-
limit = 0
96-
no_traceback = True
97-
else:
98-
# (*) CPython convert 'limit' to C long and if it overflows, it uses 'LONG_MAX'; we use Java int
99-
if limit > sys.maxsize:
100-
limit = sys.maxsize
101-
# (*) in the C printer limit is interpreted as -limit in format_exception
102-
limit = -limit
103-
else:
104-
# (*) non integer values of limit are interpreted as the default limit
105-
limit = None
106-
lines = traceback.format_exception(typ, value, tb, limit=limit)
107-
# (*) if the exception cannot be printed, then the message differs between the C driver and format_exception
108-
# We'd like to contribute to CPython to fix the divergence, but for now we do just a string substitution
109-
# to pass the tests
110-
lines[-1] = lines[-1].replace(f'<unprintable {typ.__name__} object>', f'<exception str() failed>')
111-
if no_traceback:
112-
lines = lines[-1:]
113-
for line in lines:
114-
print(line, file=stderr, end="")
115-
except BaseException as exc:
116-
print("Error in sys.excepthook:\n", file=stderr)
117-
simple_print_traceback(exc)
118-
print("\nOriginal exception was:\n", file=stderr)
119-
simple_print_traceback(value)
120-
121-
return __print_traceback__
122-
123-
124-
__excepthook__ = make_excepthook()
125-
excepthook = __excepthook__
126-
del make_excepthook
127-
128-
12963
def make_unraisablehook():
13064
def __unraisablehook__(unraisable, /):
13165
try:

0 commit comments

Comments
 (0)