From 964ceacb1108e784f13094b34e320adbec9fe665 Mon Sep 17 00:00:00 2001 From: Virgil Calvez Date: Tue, 10 Feb 2026 12:13:14 +0100 Subject: [PATCH 1/3] Add thread._excepthook and _ExceptHookArgs builtins --- .../builtins/PythonBuiltinClassType.java | 2 + .../modules/ThreadModuleBuiltins.java | 60 ++++++++++++ .../objects/thread/PExceptHookArgs.java | 26 ++++++ .../thread/PExceptHookArgsBuiltins.java | 93 +++++++++++++++++++ 4 files changed, 181 insertions(+) create mode 100644 graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/PExceptHookArgs.java create mode 100644 graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/PExceptHookArgsBuiltins.java diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java index 86e67d02c2..3d59771829 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java @@ -265,6 +265,7 @@ import com.oracle.graal.python.builtins.objects.superobject.SuperBuiltins; import com.oracle.graal.python.builtins.objects.thread.CommonLockBuiltins; import com.oracle.graal.python.builtins.objects.thread.LockTypeBuiltins; +import com.oracle.graal.python.builtins.objects.thread.PExceptHookArgsBuiltins; import com.oracle.graal.python.builtins.objects.thread.RLockBuiltins; import com.oracle.graal.python.builtins.objects.thread.ThreadLocalBuiltins; import com.oracle.graal.python.builtins.objects.tokenize.TokenizerIterBuiltins; @@ -628,6 +629,7 @@ passed as positional arguments to zip(). The i-th element in every tuple If strict is true and one of the arguments is exhausted before the others, raise a ValueError.""")), PThreadLocal("_local", PythonObject, newBuilder().publishInModule(J__THREAD).basetype().slots(ThreadLocalBuiltins.SLOTS)), + PExceptHookArgs("_ExceptHookArgs", PythonObject, newBuilder().publishInModule(J__THREAD).slots(PExceptHookArgsBuiltins.SLOTS)), PLock("LockType", PythonObject, newBuilder().publishInModule(J__THREAD).disallowInstantiation().slots(CommonLockBuiltins.SLOTS, LockTypeBuiltins.SLOTS)), PRLock("RLock", PythonObject, newBuilder().publishInModule(J__THREAD).basetype().slots(CommonLockBuiltins.SLOTS, RLockBuiltins.SLOTS)), PSemLock("SemLock", PythonObject, newBuilder().publishInModule("_multiprocessing").basetype().slots(SemLockBuiltins.SLOTS)), diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ThreadModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ThreadModuleBuiltins.java index 82dfdce7dd..d1a59ce1c6 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ThreadModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ThreadModuleBuiltins.java @@ -46,6 +46,8 @@ import static com.oracle.graal.python.nodes.BuiltinNames.T__THREAD; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; +import java.io.IOException; +import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.util.List; @@ -57,8 +59,11 @@ import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.exception.PBaseException; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.module.PythonModule; +import com.oracle.graal.python.builtins.objects.object.PythonObject; +import com.oracle.graal.python.builtins.objects.thread.PExceptHookArgs; import com.oracle.graal.python.builtins.objects.thread.PLock; import com.oracle.graal.python.builtins.objects.thread.PThread; import com.oracle.graal.python.lib.PyNumberAsSizeNode; @@ -78,6 +83,7 @@ import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.runtime.GilNode; import com.oracle.graal.python.runtime.PythonContext; +import com.oracle.graal.python.runtime.exception.ExceptionUtils; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonThreadKillException; import com.oracle.graal.python.runtime.object.PFactory; @@ -106,6 +112,7 @@ protected List> getNodeFa public void initialize(Python3Core core) { addBuiltinConstant("error", core.lookupType(PythonBuiltinClassType.RuntimeError)); addBuiltinConstant("TIMEOUT_MAX", TIMEOUT_MAX); + addBuiltinConstant("_ExceptHookArgs", core.lookupType(PythonBuiltinClassType.PExceptHookArgs)); core.lookupBuiltinModule(T__THREAD).setModuleState(0); super.initialize(core); } @@ -173,6 +180,59 @@ static long getStackSize(VirtualFrame frame, Object stackSizeObj, } } + @Builtin(name = "_excepthook", minNumOfPositionalArgs = 2, declaresExplicitSelf = true) + @GenerateNodeFactory + abstract static class GetThreadExceptHookNode extends PythonBinaryBuiltinNode { + @Specialization + @TruffleBoundary + Object getExceptHook(PythonModule self, + Object exceptHookArgs, + @Cached PRaiseNode raiseNode) { + if (!(exceptHookArgs instanceof PExceptHookArgs args)) + throw PRaiseNode.getUncached().raise(raiseNode, PythonBuiltinClassType.TypeError, ErrorMessages.ARG_TYPE_MUST_BE, "_thread.excepthook", "ExceptHookArgs"); + + Object excType = args.getExcType(); + + if (excType == PythonBuiltinClassType.SystemExit) + return PNone.NONE; + + Object excValue = args.getExcValue(); + Object excTraceback = args.getExcTraceback(); + Object thread = args.getThread(); + + CallNode callNode = CallNode.create(); + Object name = null; + + Object nameAttr = ((PythonObject) thread).getAttribute(tsLiteral("_name")); + if (nameAttr != null && nameAttr != PNone.NONE && nameAttr != PNone.NO_VALUE) { + name = nameAttr.toString(); + } + + if (name == null) { + Object getIdentBuiltin = self.getAttribute(tsLiteral("get_ident")); + Object ident = callNode.executeWithoutFrame(getIdentBuiltin); + name = ident != null ? ident.toString() : ""; + } + + PrintWriter pw = new PrintWriter(getContext().getEnv().err(), true); + pw.printf("Exception in thread %s:\n", name); + + PException pException; + if (excValue instanceof PException) + pException = (PException) excValue; + else if (excValue instanceof PBaseException base) { + pException = PException.fromObject(base, base.getException().getLocation(), false); + pException.materializeMessage(); + } else { + pw.println(excTraceback.toString()); + return PNone.NONE; + } + + ExceptionUtils.printPythonLikeStackTrace(getContext(), pException); + return PNone.NONE; + } + } + @Builtin(name = "start_new_thread", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 3) @Builtin(name = "start_new", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 3) @GenerateNodeFactory diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/PExceptHookArgs.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/PExceptHookArgs.java new file mode 100644 index 0000000000..000332a248 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/PExceptHookArgs.java @@ -0,0 +1,26 @@ +package com.oracle.graal.python.builtins.objects.thread; + +import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject; +import com.oracle.truffle.api.object.Shape; + +public class PExceptHookArgs extends PythonBuiltinObject { + + private final Object excType; + private final Object excValue; + private final Object excTraceback; + private final Object thread; + + public PExceptHookArgs(Object cls, Shape instanceShape, Object excType, Object excValue, Object excTraceback, Object thread) { + super(cls, instanceShape); + this.excType = excType; + this.excValue = excValue; + this.excTraceback = excTraceback; + this.thread = thread; + } + + public Object getExcType() { return excType; } + public Object getExcValue() { return excValue; } + public Object getExcTraceback() { return excTraceback; } + public Object getThread() { return thread; } + +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/PExceptHookArgsBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/PExceptHookArgsBuiltins.java new file mode 100644 index 0000000000..92748275bc --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/PExceptHookArgsBuiltins.java @@ -0,0 +1,93 @@ +package com.oracle.graal.python.builtins.objects.thread; + +import com.oracle.graal.python.annotations.Builtin; +import com.oracle.graal.python.annotations.Slot; +import com.oracle.graal.python.builtins.PythonBuiltinClassType; +import com.oracle.graal.python.builtins.CoreFunctions; +import com.oracle.graal.python.builtins.PythonBuiltins; +import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; +import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; +import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; +import com.oracle.graal.python.runtime.sequence.PSequence; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.GenerateNodeFactory; +import com.oracle.truffle.api.dsl.NodeFactory; +import com.oracle.truffle.api.dsl.Specialization; + +import java.util.List; + +@CoreFunctions(extendClasses = PythonBuiltinClassType.PExceptHookArgs) +public class PExceptHookArgsBuiltins extends PythonBuiltins { + + public static final TpSlots SLOTS = PExceptHookArgsBuiltinsSlotsGen.SLOTS; + + @Override + protected List> getNodeFactories() { + return PExceptHookArgsBuiltinsFactory.getFactories(); + } + + @Slot(value = Slot.SlotKind.tp_new, isComplex = true) + @Slot.SlotSignature(name = "_ExceptHookArgs", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 2) + @GenerateNodeFactory + public abstract static class ExceptHookArgsNewNode extends PythonBinaryBuiltinNode { + @Specialization + static Object doNew(Object cls, Object args, + @Cached TypeNodes.GetInstanceShape getInstanceShape, + @Cached PRaiseNode raiseNode) { + if (!(args instanceof PSequence)) + throw PRaiseNode.getUncached().raise(raiseNode, PythonBuiltinClassType.TypeError, + ErrorMessages.ARG_S_MUST_BE_A_LIST_OR_TUPLE, "_thread.ExceptHookArgs(args)"); + + Object[] items = SequenceStorageNodes.ToArrayNode.executeUncached(((PSequence) args).getSequenceStorage()); + + if (items.length != 4) + throw PRaiseNode.getUncached().raise(raiseNode, PythonBuiltinClassType.TypeError, + ErrorMessages.TAKES_EXACTLY_D_ARGUMENTS_D_GIVEN, 4, items.length); + + return new PExceptHookArgs(cls, getInstanceShape.execute(cls), items[0], items[1], items[2], items[3]); + } + } + + @Builtin(name = "exc_type", minNumOfPositionalArgs = 1, isGetter = true) + @GenerateNodeFactory + public abstract static class ExcTypeNode extends PythonUnaryBuiltinNode { + @Specialization + static Object getExcType(PExceptHookArgs self) { + return self.getExcType(); + } + } + + + @Builtin(name = "exc_traceback", minNumOfPositionalArgs = 1, isGetter = true) + @GenerateNodeFactory + public abstract static class ExcTracebackNode extends PythonUnaryBuiltinNode { + @Specialization + static Object getExcTraceback(PExceptHookArgs self) { + return self.getExcTraceback(); + } + } + + + @Builtin(name = "exc_value", minNumOfPositionalArgs = 1, isGetter = true) + @GenerateNodeFactory + public abstract static class ExcValueNode extends PythonUnaryBuiltinNode { + @Specialization + static Object getExcValue(PExceptHookArgs self) { + return self.getExcValue(); + } + } + + @Builtin(name = "thread", minNumOfPositionalArgs = 1, isGetter = true) + @GenerateNodeFactory + public abstract static class ThreadNode extends PythonUnaryBuiltinNode { + @Specialization + static Object getThread(PExceptHookArgs self) { + return self.getThread(); + } + } +} \ No newline at end of file From 0c0ae32cf682ed92683723214b2df0ef6532c1f1 Mon Sep 17 00:00:00 2001 From: Virgil Calvez Date: Thu, 19 Feb 2026 17:23:24 +0100 Subject: [PATCH 2/3] Set _ExceptHookArgs as a PTuple/Seq --- .../builtins/PythonBuiltinClassType.java | 8 +- .../modules/ThreadModuleBuiltins.java | 42 ++++++--- .../objects/thread/PExceptHookArgs.java | 26 ------ .../thread/PExceptHookArgsBuiltins.java | 93 ------------------- .../InstantiableStructSequenceBuiltins.java | 3 +- .../objects/tuple/StructSequenceBuiltins.java | 3 +- .../builtins/objects/type/TypeNodes.java | 2 +- 7 files changed, 42 insertions(+), 135 deletions(-) delete mode 100644 graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/PExceptHookArgs.java delete mode 100644 graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/PExceptHookArgsBuiltins.java diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java index 3d59771829..dc55e24c32 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java @@ -265,7 +265,6 @@ import com.oracle.graal.python.builtins.objects.superobject.SuperBuiltins; import com.oracle.graal.python.builtins.objects.thread.CommonLockBuiltins; import com.oracle.graal.python.builtins.objects.thread.LockTypeBuiltins; -import com.oracle.graal.python.builtins.objects.thread.PExceptHookArgsBuiltins; import com.oracle.graal.python.builtins.objects.thread.RLockBuiltins; import com.oracle.graal.python.builtins.objects.thread.ThreadLocalBuiltins; import com.oracle.graal.python.builtins.objects.tokenize.TokenizerIterBuiltins; @@ -629,7 +628,6 @@ passed as positional arguments to zip(). The i-th element in every tuple If strict is true and one of the arguments is exhausted before the others, raise a ValueError.""")), PThreadLocal("_local", PythonObject, newBuilder().publishInModule(J__THREAD).basetype().slots(ThreadLocalBuiltins.SLOTS)), - PExceptHookArgs("_ExceptHookArgs", PythonObject, newBuilder().publishInModule(J__THREAD).slots(PExceptHookArgsBuiltins.SLOTS)), PLock("LockType", PythonObject, newBuilder().publishInModule(J__THREAD).disallowInstantiation().slots(CommonLockBuiltins.SLOTS, LockTypeBuiltins.SLOTS)), PRLock("RLock", PythonObject, newBuilder().publishInModule(J__THREAD).basetype().slots(CommonLockBuiltins.SLOTS, RLockBuiltins.SLOTS)), PSemLock("SemLock", PythonObject, newBuilder().publishInModule("_multiprocessing").basetype().slots(SemLockBuiltins.SLOTS)), @@ -989,7 +987,13 @@ accepted by asctime(), mktime() and strftime(). May be considered as a UnraisableHookArgs Type used to pass arguments to sys.unraisablehook.""")), + PExceptHookArgs( + "_ExceptHookArgs", + PTuple, + newBuilder().publishInModule(J__THREAD).slots(StructSequenceBuiltins.SLOTS, InstantiableStructSequenceBuiltins.SLOTS).doc(""" + _ExceptHookArgs + Type used to pass arguments to _thread._excepthook.""")), PSSLSession("SSLSession", PythonObject, newBuilder().publishInModule(J__SSL).disallowInstantiation()), PSSLContext("_SSLContext", PythonObject, newBuilder().publishInModule(J__SSL).basetype().slots(SSLContextBuiltins.SLOTS)), PSSLSocket("_SSLSocket", PythonObject, newBuilder().publishInModule(J__SSL).basetype()), diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ThreadModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ThreadModuleBuiltins.java index d1a59ce1c6..679632740a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ThreadModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ThreadModuleBuiltins.java @@ -46,7 +46,6 @@ import static com.oracle.graal.python.nodes.BuiltinNames.T__THREAD; import static com.oracle.graal.python.util.PythonUtils.tsLiteral; -import java.io.IOException; import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.util.List; @@ -59,14 +58,18 @@ import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; import com.oracle.graal.python.builtins.objects.exception.PBaseException; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.builtins.objects.object.PythonObject; -import com.oracle.graal.python.builtins.objects.thread.PExceptHookArgs; import com.oracle.graal.python.builtins.objects.thread.PLock; import com.oracle.graal.python.builtins.objects.thread.PThread; +import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.builtins.objects.tuple.StructSequence; +import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyNumberAsSizeNode; +import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.WriteUnraisableNode; @@ -81,12 +84,14 @@ import com.oracle.graal.python.nodes.function.builtins.PythonUnaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; +import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.GilNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.ExceptionUtils; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonThreadKillException; import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.TruffleThreadBuilder; @@ -103,6 +108,15 @@ @CoreFunctions(defineModule = J__THREAD) public final class ThreadModuleBuiltins extends PythonBuiltins { + public static final StructSequence.BuiltinTypeDescriptor EXCEPTHOOK_ARGS_DESC = new StructSequence.BuiltinTypeDescriptor( + PythonBuiltinClassType.PExceptHookArgs, + 4, + new String[]{ + "exc_type", "exc_value", "exc_traceback", "thread"}, + new String[]{ + "Exception type", "Exception value", "Exception traceback", + "Exception thread"}); + @Override protected List> getNodeFactories() { return ThreadModuleBuiltinsFactory.getFactories(); @@ -112,7 +126,7 @@ protected List> getNodeFa public void initialize(Python3Core core) { addBuiltinConstant("error", core.lookupType(PythonBuiltinClassType.RuntimeError)); addBuiltinConstant("TIMEOUT_MAX", TIMEOUT_MAX); - addBuiltinConstant("_ExceptHookArgs", core.lookupType(PythonBuiltinClassType.PExceptHookArgs)); + StructSequence.initType(core, EXCEPTHOOK_ARGS_DESC); core.lookupBuiltinModule(T__THREAD).setModuleState(0); super.initialize(core); } @@ -188,28 +202,34 @@ abstract static class GetThreadExceptHookNode extends PythonBinaryBuiltinNode { Object getExceptHook(PythonModule self, Object exceptHookArgs, @Cached PRaiseNode raiseNode) { - if (!(exceptHookArgs instanceof PExceptHookArgs args)) + + Object argsType = GetClassNode.GetPythonObjectClassNode.executeUncached((PythonObject) exceptHookArgs); + if (!TypeNodes.IsSameTypeNode.executeUncached(argsType, PythonBuiltinClassType.PExceptHookArgs)) throw PRaiseNode.getUncached().raise(raiseNode, PythonBuiltinClassType.TypeError, ErrorMessages.ARG_TYPE_MUST_BE, "_thread.excepthook", "ExceptHookArgs"); - Object excType = args.getExcType(); + SequenceStorage seq = ((PTuple) exceptHookArgs).getSequenceStorage(); + if (seq.length() != 4) + throw PRaiseNode.getUncached().raise(raiseNode, PythonBuiltinClassType.TypeError, ErrorMessages.TAKES_EXACTLY_D_ARGUMENTS_D_GIVEN, 4, seq.length()); + + Object excType = SequenceStorageNodes.GetItemScalarNode.executeUncached(seq, 0); - if (excType == PythonBuiltinClassType.SystemExit) + if (TypeNodes.IsSameTypeNode.executeUncached(excType, PythonBuiltinClassType.SystemExit)) return PNone.NONE; - Object excValue = args.getExcValue(); - Object excTraceback = args.getExcTraceback(); - Object thread = args.getThread(); + Object excValue = SequenceStorageNodes.GetItemScalarNode.executeUncached(seq, 1); + Object excTraceback = SequenceStorageNodes.GetItemScalarNode.executeUncached(seq, 2); + Object thread = SequenceStorageNodes.GetItemScalarNode.executeUncached(seq, 3); CallNode callNode = CallNode.create(); Object name = null; - Object nameAttr = ((PythonObject) thread).getAttribute(tsLiteral("_name")); + Object nameAttr = PyObjectLookupAttr.executeUncached(thread, tsLiteral("_name")); if (nameAttr != null && nameAttr != PNone.NONE && nameAttr != PNone.NO_VALUE) { name = nameAttr.toString(); } if (name == null) { - Object getIdentBuiltin = self.getAttribute(tsLiteral("get_ident")); + Object getIdentBuiltin = PyObjectLookupAttr.executeUncached(thread, tsLiteral("get_ident")); Object ident = callNode.executeWithoutFrame(getIdentBuiltin); name = ident != null ? ident.toString() : ""; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/PExceptHookArgs.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/PExceptHookArgs.java deleted file mode 100644 index 000332a248..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/PExceptHookArgs.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.oracle.graal.python.builtins.objects.thread; - -import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject; -import com.oracle.truffle.api.object.Shape; - -public class PExceptHookArgs extends PythonBuiltinObject { - - private final Object excType; - private final Object excValue; - private final Object excTraceback; - private final Object thread; - - public PExceptHookArgs(Object cls, Shape instanceShape, Object excType, Object excValue, Object excTraceback, Object thread) { - super(cls, instanceShape); - this.excType = excType; - this.excValue = excValue; - this.excTraceback = excTraceback; - this.thread = thread; - } - - public Object getExcType() { return excType; } - public Object getExcValue() { return excValue; } - public Object getExcTraceback() { return excTraceback; } - public Object getThread() { return thread; } - -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/PExceptHookArgsBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/PExceptHookArgsBuiltins.java deleted file mode 100644 index 92748275bc..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/PExceptHookArgsBuiltins.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.oracle.graal.python.builtins.objects.thread; - -import com.oracle.graal.python.annotations.Builtin; -import com.oracle.graal.python.annotations.Slot; -import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.CoreFunctions; -import com.oracle.graal.python.builtins.PythonBuiltins; -import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; -import com.oracle.graal.python.builtins.objects.type.TpSlots; -import com.oracle.graal.python.builtins.objects.type.TypeNodes; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; -import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.runtime.sequence.PSequence; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.GenerateNodeFactory; -import com.oracle.truffle.api.dsl.NodeFactory; -import com.oracle.truffle.api.dsl.Specialization; - -import java.util.List; - -@CoreFunctions(extendClasses = PythonBuiltinClassType.PExceptHookArgs) -public class PExceptHookArgsBuiltins extends PythonBuiltins { - - public static final TpSlots SLOTS = PExceptHookArgsBuiltinsSlotsGen.SLOTS; - - @Override - protected List> getNodeFactories() { - return PExceptHookArgsBuiltinsFactory.getFactories(); - } - - @Slot(value = Slot.SlotKind.tp_new, isComplex = true) - @Slot.SlotSignature(name = "_ExceptHookArgs", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 2) - @GenerateNodeFactory - public abstract static class ExceptHookArgsNewNode extends PythonBinaryBuiltinNode { - @Specialization - static Object doNew(Object cls, Object args, - @Cached TypeNodes.GetInstanceShape getInstanceShape, - @Cached PRaiseNode raiseNode) { - if (!(args instanceof PSequence)) - throw PRaiseNode.getUncached().raise(raiseNode, PythonBuiltinClassType.TypeError, - ErrorMessages.ARG_S_MUST_BE_A_LIST_OR_TUPLE, "_thread.ExceptHookArgs(args)"); - - Object[] items = SequenceStorageNodes.ToArrayNode.executeUncached(((PSequence) args).getSequenceStorage()); - - if (items.length != 4) - throw PRaiseNode.getUncached().raise(raiseNode, PythonBuiltinClassType.TypeError, - ErrorMessages.TAKES_EXACTLY_D_ARGUMENTS_D_GIVEN, 4, items.length); - - return new PExceptHookArgs(cls, getInstanceShape.execute(cls), items[0], items[1], items[2], items[3]); - } - } - - @Builtin(name = "exc_type", minNumOfPositionalArgs = 1, isGetter = true) - @GenerateNodeFactory - public abstract static class ExcTypeNode extends PythonUnaryBuiltinNode { - @Specialization - static Object getExcType(PExceptHookArgs self) { - return self.getExcType(); - } - } - - - @Builtin(name = "exc_traceback", minNumOfPositionalArgs = 1, isGetter = true) - @GenerateNodeFactory - public abstract static class ExcTracebackNode extends PythonUnaryBuiltinNode { - @Specialization - static Object getExcTraceback(PExceptHookArgs self) { - return self.getExcTraceback(); - } - } - - - @Builtin(name = "exc_value", minNumOfPositionalArgs = 1, isGetter = true) - @GenerateNodeFactory - public abstract static class ExcValueNode extends PythonUnaryBuiltinNode { - @Specialization - static Object getExcValue(PExceptHookArgs self) { - return self.getExcValue(); - } - } - - @Builtin(name = "thread", minNumOfPositionalArgs = 1, isGetter = true) - @GenerateNodeFactory - public abstract static class ThreadNode extends PythonUnaryBuiltinNode { - @Specialization - static Object getThread(PExceptHookArgs self) { - return self.getThread(); - } - } -} \ No newline at end of file diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/InstantiableStructSequenceBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/InstantiableStructSequenceBuiltins.java index 1f6054487c..b28db538d4 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/InstantiableStructSequenceBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/InstantiableStructSequenceBuiltins.java @@ -90,7 +90,8 @@ PythonBuiltinClassType.PIntInfo, PythonBuiltinClassType.PHashInfo, PythonBuiltinClassType.PThreadInfo, - PythonBuiltinClassType.PUnraisableHookArgs}) + PythonBuiltinClassType.PUnraisableHookArgs, + PythonBuiltinClassType.PExceptHookArgs}) public class InstantiableStructSequenceBuiltins extends PythonBuiltins { public static final TpSlots SLOTS = InstantiableStructSequenceBuiltinsSlotsGen.SLOTS; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/StructSequenceBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/StructSequenceBuiltins.java index 8644f8e07a..449908e3f9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/StructSequenceBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/StructSequenceBuiltins.java @@ -116,7 +116,8 @@ PythonBuiltinClassType.PIntInfo, PythonBuiltinClassType.PHashInfo, PythonBuiltinClassType.PThreadInfo, - PythonBuiltinClassType.PUnraisableHookArgs}) + PythonBuiltinClassType.PUnraisableHookArgs, + PythonBuiltinClassType.PExceptHookArgs}) public final class StructSequenceBuiltins extends PythonBuiltins { public static final TpSlots SLOTS = StructSequenceBuiltinsSlotsGen.SLOTS; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java index 944f037bfa..5d93adacb8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java @@ -2603,7 +2603,7 @@ private static int getBuiltinTypeItemsize(PythonBuiltinClassType cls) { case PInt, Boolean -> 4; case PAsyncGenerator, PFlags, PHashInfo, PTuple, PCoroutine, PGenerator, PThreadInfo, PMemoryView, PStatResult, PUnameResult, PStructTime, PFloatInfo, PStatvfsResult, PIntInfo, PFrame, - PTerminalSize, PUnraisableHookArgs -> 8; + PTerminalSize, PUnraisableHookArgs, PExceptHookArgs -> 8; case PythonClass -> 40; default -> 0; }; From a48a18c43bc2ba4cc4a6975d6a629c5180e898b1 Mon Sep 17 00:00:00 2001 From: Virgil Calvez Date: Thu, 12 Mar 2026 10:06:17 +0100 Subject: [PATCH 3/3] Fix style gate --- .../builtins/PythonBuiltinClassType.java | 6 +++--- .../builtins/modules/ThreadModuleBuiltins.java | 18 +++++++++--------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java index dc55e24c32..2c0da66626 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java @@ -988,9 +988,9 @@ accepted by asctime(), mktime() and strftime(). May be considered as a Type used to pass arguments to sys.unraisablehook.""")), PExceptHookArgs( - "_ExceptHookArgs", - PTuple, - newBuilder().publishInModule(J__THREAD).slots(StructSequenceBuiltins.SLOTS, InstantiableStructSequenceBuiltins.SLOTS).doc(""" + "_ExceptHookArgs", + PTuple, + newBuilder().publishInModule(J__THREAD).slots(StructSequenceBuiltins.SLOTS, InstantiableStructSequenceBuiltins.SLOTS).doc(""" _ExceptHookArgs Type used to pass arguments to _thread._excepthook.""")), diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ThreadModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ThreadModuleBuiltins.java index 679632740a..ac2f70e562 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ThreadModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ThreadModuleBuiltins.java @@ -109,13 +109,13 @@ public final class ThreadModuleBuiltins extends PythonBuiltins { public static final StructSequence.BuiltinTypeDescriptor EXCEPTHOOK_ARGS_DESC = new StructSequence.BuiltinTypeDescriptor( - PythonBuiltinClassType.PExceptHookArgs, - 4, - new String[]{ - "exc_type", "exc_value", "exc_traceback", "thread"}, - new String[]{ - "Exception type", "Exception value", "Exception traceback", - "Exception thread"}); + PythonBuiltinClassType.PExceptHookArgs, + 4, + new String[]{ + "exc_type", "exc_value", "exc_traceback", "thread"}, + new String[]{ + "Exception type", "Exception value", "Exception traceback", + "Exception thread"}); @Override protected List> getNodeFactories() { @@ -200,8 +200,8 @@ abstract static class GetThreadExceptHookNode extends PythonBinaryBuiltinNode { @Specialization @TruffleBoundary Object getExceptHook(PythonModule self, - Object exceptHookArgs, - @Cached PRaiseNode raiseNode) { + Object exceptHookArgs, + @Cached PRaiseNode raiseNode) { Object argsType = GetClassNode.GetPythonObjectClassNode.executeUncached((PythonObject) exceptHookArgs); if (!TypeNodes.IsSameTypeNode.executeUncached(argsType, PythonBuiltinClassType.PExceptHookArgs))