From 0fd044f0c4e4d5e174770c4ed6a0834b0f506473 Mon Sep 17 00:00:00 2001 From: "cc.wr" <47033353+cc-wr@users.noreply> Date: Wed, 13 Oct 2021 16:19:24 -0400 Subject: [PATCH 1/2] Stop redefining Throw and Catch, and use a different method to handle uncaught tagless Throw statements --- .../Resources/EvaluationUtilities.wl | 59 +++---------------- .../Resources/RequestHandlers.wl | 27 +++++---- 2 files changed, 22 insertions(+), 64 deletions(-) diff --git a/WolframLanguageForJupyter/Resources/EvaluationUtilities.wl b/WolframLanguageForJupyter/Resources/EvaluationUtilities.wl index ca3c13a..541773c 100644 --- a/WolframLanguageForJupyter/Resources/EvaluationUtilities.wl +++ b/WolframLanguageForJupyter/Resources/EvaluationUtilities.wl @@ -7,8 +7,6 @@ Description: the Mathematica REPL Symbols defined: Print, - Throw, - Catch, redirectPrint, redirectMessages, simulatedEvaluate @@ -226,28 +224,6 @@ If[ ); Protect[Exit]; -(************************************ - versions of Throw and - Catch that we can - more easily intercept -*************************************) - - Unprotect[Throw]; - Throw[value_] := - Throw[ - value, - WolframLanguageForJupyter`Private`$ThrowLabel - ]; - Protect[Throw]; - - Unprotect[Catch]; - Catch[expr_] := - Catch[ - expr, - WolframLanguageForJupyter`Private`$ThrowLabel - ]; - Protect[Catch]; - (************************************ redirection utilities *************************************) @@ -288,7 +264,7 @@ If[ messageTextString }, (* generate string forms of the arguments *) - messageNameString = ToString[messageName]; + messageNameString = ToString[HoldForm[messageName]]; messageTextString = ToString[messageText]; (* send a frame *) sendFrame[ @@ -319,7 +295,7 @@ If[ (* use only the message text here if dropMessageName is True *) messageTextString, (* otherwise, combine the message name and message text *) - ToString[System`ColonForm[messageName, messageText]] + ToString[System`ColonForm[HoldForm[messageName], messageText]] ], (* if addNewline, add a newline *) If[addNewline, "\n", ""], @@ -337,6 +313,7 @@ If[ (* ... and return an empty string to the Wolfram Language message system *) Return[""]; ]; + SetAttributes[redirectMessages, HoldAll]; (************************************ utilities for splitting @@ -488,9 +465,6 @@ If[ (* the result of evaluation *) evaluationResult, - (* for storing intermediate results *) - intermediate, - (* for storing final results *) result, @@ -550,35 +524,16 @@ If[ Protect[InString]; ]; - (* catch any Throws that were not handled by the input itself *) - intermediate = - Catch[ - (* evaluate the expression string *) + (* evaluate the expression string *) + result = + Internal`AllowExceptions[ ToExpression[ exprStr, InputForm, uninteract - ], - _, - WolframLanguageForJupyter`Private`$ThrowNoCatch[#1, #2] & + ] ]; - If[ - Head[intermediate] =!= WolframLanguageForJupyter`Private`$ThrowNoCatch, - (* if we did not catch anything, set result to intermediate *) - result = intermediate;, - (* if we did catch something, obtain the correct held form of the Throw to return, and message *) - If[intermediate[[2]] === WolframLanguageForJupyter`Private`$ThrowLabel, - result = Replace[Hold[Throw[placeHolder]], {placeHolder -> intermediate[[1]]}, {2}];, - result = Replace[Hold[Throw[placeHolder1, placeHolder2]], {placeHolder1 -> intermediate[[1]], placeHolder2 -> intermediate[[2]]}, {2}]; - ]; - (* message *) - Message[ - Throw::nocatch, - StringTrim[ToString[result, OutputForm], "Hold[" | "]"] - ]; - ]; - If[ !parseTracker["SyntaxError"], (* set the In[] for this expression *) diff --git a/WolframLanguageForJupyter/Resources/RequestHandlers.wl b/WolframLanguageForJupyter/Resources/RequestHandlers.wl index 155ced1..4782277 100644 --- a/WolframLanguageForJupyter/Resources/RequestHandlers.wl +++ b/WolframLanguageForJupyter/Resources/RequestHandlers.wl @@ -99,6 +99,9 @@ If[ executeRequestHandler[] := Module[ { + (* message formatter function *) + messageFormatter, + (* content of the desired frame to send on the IO Publish socket *) ioPubReplyContent, @@ -142,17 +145,16 @@ If[ update Jupyter explicitly with any errors that occur DURING the execution of the input *) If[ loopState["redirectMessages"], - Internal`$MessageFormatter = - ( - redirectMessages[ - loopState["frameAssoc"], - #1, - #2, - (* add a newline if loopState["isCompleteRequestSent"] *) - loopState["isCompleteRequestSent"] - ] - & - ); + messageFormatter[messageName_, messageText_] := + redirectMessages[ + loopState["frameAssoc"], + messageName, + messageText, + (* add a newline if loopState["isCompleteRequestSent"] *) + loopState["isCompleteRequestSent"] + ]; + SetAttributes[messageFormatter, HoldAll]; + Internal`$MessageFormatter = messageFormatter; ]; (* evaluate the input, and store the total result in totalResult *) @@ -161,7 +163,8 @@ If[ (* restore printFunction to False *) loopState["printFunction"] = False; - (* unset Internal`$MessageFormatter *) + (* unset messageFormatter and Internal`$MessageFormatter *) + Unset[messageFormatter]; Unset[Internal`$MessageFormatter]; (* set the appropriate reply type *) From 8208cbc746800e0a4d2f2dbfe6ab9c4ecf1b44b2 Mon Sep 17 00:00:00 2001 From: "cc.wr" <47033353+cc-wr@users.noreply> Date: Wed, 13 Oct 2021 17:15:50 -0400 Subject: [PATCH 2/2] Add a comment attempting to explain the use of Internal`AllowExceptions --- WolframLanguageForJupyter/Resources/EvaluationUtilities.wl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/WolframLanguageForJupyter/Resources/EvaluationUtilities.wl b/WolframLanguageForJupyter/Resources/EvaluationUtilities.wl index 541773c..a0c63cd 100644 --- a/WolframLanguageForJupyter/Resources/EvaluationUtilities.wl +++ b/WolframLanguageForJupyter/Resources/EvaluationUtilities.wl @@ -525,6 +525,11 @@ If[ ]; (* evaluate the expression string *) + (* regarding Internal`AllowExceptions, we need to generate the results and messages that + are expected when a user evaluation is interrupted by behavior such as an uncaught Throw + statement, while making sure that the simulated evaluation loop is not interrupted by the + same behavior; my hope is that we can achieve this by using Internal`AllowExceptions as + essentially a version of CheckAll that does not silence messages such as Throw::nocatch *) result = Internal`AllowExceptions[ ToExpression[