Merge pull request #79 from WolframResearch/bugfix/WriteString-Write-stdout

Redirect all string references to the stdout stream to a new WolframLanguageForJupyter-stdout stream
This commit is contained in:
cc-wr 2020-02-04 17:52:33 -05:00 committed by GitHub
commit a96cd3e345
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 113 additions and 1 deletions

View File

@ -71,8 +71,9 @@ If[
sends output to Jupyter
*************************************)
(* redirect Print calls into a message to Jupyter, in order to print in the Jupyter notebook *)
(* redirect Print calls into a message to Jupyter, in order to print in Jupyter *)
(* TODO: review other methods: through EvaluationData or WSTP so we don't redefine Print *)
(* TODO: remove this and just permanently set $Output to {..., loopState["WolframLanguageForJupyter-stdout"], ...} *)
Unprotect[Print];
Print[ourArgs___, opts:OptionsPattern[]] :=
Block[
@ -95,6 +96,76 @@ If[
] /; !TrueQ[$inPrint];
Protect[Print];
(************************************
version of Write that
sends output to Jupyter
*************************************)
(* redirect Write["stdout", ourArgs___] calls to Write[loopState["WolframLanguageForJupyter-stdout"], ourArgs___],
in order to print in Jupyter *)
Unprotect[Write];
Write["stdout", ourArgs___, opts:OptionsPattern[]] :=
Block[
{
$inWrite = True
},
If[
loopState["WolframLanguageForJupyter-stdout"] =!= False,
Write[loopState["WolframLanguageForJupyter-stdout"], ourArgs]
];
] /; !TrueQ[$inWrite];
Protect[Write];
(* redirect Write[{before___, "stdout", after___}, ourArgs___] calls to
Write[{before___, "WolframLanguageForJupyter-stdout", after___}, ourArgs___],
in order to print in Jupyter *)
Unprotect[Write];
Write[{before___, "stdout", after___}, ourArgs___, opts:OptionsPattern[]] :=
Block[
{
$inWrite = True
},
If[
loopState["WolframLanguageForJupyter-stdout"] =!= False,
Write[{before, loopState["WolframLanguageForJupyter-stdout"], after}, ourArgs]
];
] /; !TrueQ[$inWrite];
Protect[Write];
(************************************
version of WriteString that
sends output to Jupyter
*************************************)
(* redirect WriteString["stdout", ourArgs___] calls to WriteString[loopState["WolframLanguageForJupyter-stdout"], ourArgs___],
in order to print in Jupyter *)
Unprotect[WriteString];
WriteString["stdout", ourArgs___, opts:OptionsPattern[]] :=
Block[
{
$inWriteString = True
},
If[
loopState["WolframLanguageForJupyter-stdout"] =!= False,
WriteString[loopState["WolframLanguageForJupyter-stdout"], ourArgs]
];
] /; !TrueQ[$inWriteString];
Protect[WriteString];
(* redirect WriteString[{before___, "stdout", after___}, ourArgs___] calls to
WriteString[{before___, "WolframLanguageForJupyter-stdout", after___}, ourArgs___],
in order to print in Jupyter *)
Unprotect[WriteString];
WriteString[{before___, "stdout", after___}, ourArgs___, opts:OptionsPattern[]] :=
Block[
{
$inWriteString = True
},
If[
loopState["WolframLanguageForJupyter-stdout"] =!= False,
WriteString[{before, loopState["WolframLanguageForJupyter-stdout"], after}, ourArgs]
];
] /; !TrueQ[$inWriteString];
Protect[WriteString];
(************************************
versions of Quit and Exit that
ask the Jupyter console

View File

@ -195,6 +195,9 @@ If[
(* flag for if an is_complete_request has ever been sent to the kernel *)
"isCompleteRequestSent" -> False,
(* OutputStream for Jupyter's stdout *)
"WolframLanguageForJupyter-stdout" -> False,
(* local to an iteration *)
(* a received frame as an Association *)
"frameAssoc" -> Null,
@ -263,6 +266,44 @@ If[
inputString = StringJoin[baseString, connectionAssoc["stdin_port"]];
shellString = StringJoin[baseString, connectionAssoc["shell_port"]];
Block[
{
(* for storing the result of defining a new OutputStream method *)
customOutputStreamMethod
},
(* define an OutputStream method that will allow writing to Jupyter's stdout *)
customOutputStreamMethod =
DefineOutputStreamMethod[
"for-WolframLanguageForJupyter-stdout",
{
"ConstructorFunction" -> Function[{name, isAppend, caller, opts}, {True, {}}],
"WriteFunction" ->
Function[
{state, bytes},
If[
loopState["frameAssoc"] =!= Null,
redirectPrint[loopState["frameAssoc"], FromCharacterCode[bytes]];
];
{Length[bytes], {}}
]
}
];
(* if defining a new OutputStream method did not fail,
open an OutputStream using the new method, and store it in loopState *)
If[
!FailureQ[customOutputStreamMethod],
loopState["WolframLanguageForJupyter-stdout"] =
OpenWrite["WolframLanguageForJupyter-stdout", Method -> "for-WolframLanguageForJupyter-stdout"];
(* -- also, if opening the OutputStream failed, reset loopState["WolframLanguageForJupyter-stdout"] back to False *)
If[
FailureQ[loopState["WolframLanguageForJupyter-stdout"]],
loopState["WolframLanguageForJupyter-stdout"] = False;
];
];
];
(************************************
open all the non-heartbeat
sockets