-
Notifications
You must be signed in to change notification settings - Fork 86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error method is noncompliant to Jupyter protocol #149
Comments
Thanks for the report! Can you give a bit more detail on your suggested fix? What do you mean by renaming "what you are already returning"? Any chance of actually making a PR? |
See also fixes and discussion here: #147 |
Oops, I saw that #147 was actually closed, but please take a look at the comments there. TL;DR Metakernel needs to either modify pexpect some more, or use the fd oriented class of pexpects. This is really really breaking to me, pls help. |
Ok, let's try to nail down exactly what the issue is, and what should be done. Are you saying that if a kernel prints on stderr, should that be interpreted and returned as an error reply? |
This is a fundamental limitation of using |
That's the idea. At least add that option to Metakernel and flag octave_kernel to use that option. I can't exactly ensure that if any kernel prints to stderr, that it will always be a halting error, but octave at the very least will print r".+ error: .+" if there is a halting error. (sorry that regex may be a little wrong). |
And it's not a use case. It's a fundamental feature of being a Jupyter kernel. (that also happens to be my use case.) |
I understand, but it is also a fundamental limitation of talking to a spawned process from python. The bash kernel has the same limitation. |
It seems like we could at least make any pexpect kernel print out a special identifier that would signal that an error has occurred, right? |
Can Pexpect be modified to distinguish between the two (at least optionally)? |
I've thought about some kind of API that would allow pexpect send back image data direct through some kind of mark-up codes. Seems like the same could be done to signal an error. |
And I guess the problem is that Metakernel at the moment can't even distinguish if there was an error because it's using Pexpect that presently doesn't give information about which stream some info came from. If it did that, I think the proper place for the rest of the necessary modifications would be in Metakernel. |
@dsblank, it could be possible to thread something like that through. @JMurph2015, the pty module in core |
hmmm, but Popen processes can have their streams distinguished iirc. Of course you might not be remotely based on it, but how do they do it? |
Yes, it is easy to read it after the fact. Reading from both |
Also, without a |
So this may be a python core issue (assuming pty is an absolute dependency) but there shouldn't be a super good reason something generically communicating with another process shouldn't expose all streams (since they are all just file descriptors anyway) |
/ the cpython pty module is like 170 lines long. It wouldn't be incredibly difficult for someone (that someone might be me today) modify it and make a new module, perhaps superpty (or maybe pity 😆 ) that supports segregating stdout and stderr. |
Hi! |
That would mean that |
It might perhaps depend on how much code we'd have to rely on that was outside of the standard libraries. But like @blink1073 suggests, it would not be good to fork a big chunk of code. Can be done by subclassing? Is it smallish in size? Is it something that python standard library would want to include? |
200 lines of code presently. It's unclear how much of Pexpect would need refactoring. The options I put in are entirely optional arguments, but to actually use segregated streams would definitely change at least a few things on Pexpect's side. |
The pty core module itself is relatively tiny at 170 lines total because it is at could be described as some convenience functions that just garble the stdin, stdout, and stderr file descriptors together. |
I'd say make a PR and let's check it out. |
@blink1073 what are the odds something like a |
/ sorry for the continued discussion here, but I'm still formulating who, what, and where these changes are going to be made (best to go in with a plan, right?). I think I can even enable |
Or you could have it read from the unified stream and check if each chunk it reads is the next thing on the top of a stream-specific fd. |
|
@JMurph2015 Are you sure that this is the right approach? What about a pexpect-based kernel that doesn't write to stderr? It still needs a method to signal an error. I'm still wondering about a special text signal that could signal an error, and even an API for routing text to stderr in a jupyter frontend, even if it didn't come from stderr in the external process. |
@dsblank, I like the idea, but I just don't know how one would be able to get that inserted into a runtime's error processing loop. For example, how would you be able to direct Octave that it should print some special characters every time it hits an error so that Metakernel and/or Octave kernel can pick that up? |
Or, what happens if the REPL segfaults and Octave stops altogether? ( this one may be easier because Pexpect should know if the process crashes altogether.) |
Octave prints |
@blink1073 Not to get too idealist here, but you technically lose some functionality there because you would then prohibit the first thing a user prints from being something matching the regex That's been exactly my workaround for my project so far, but my whole team agrees that it isn't great to have to tell users "Specific kernels don't process errors out of band, so please refer to our compatibility table and follow those rules whenever using those kernels" edit: readability |
I had a pretty decent idea just a few minutes ago that might help us all out. If we called the repl in question with a bash pipe that padded stderr with somewhat long sequences of unprintable characters (that we know), then we could just regex on those sequences later and if they were long, uncommon, and unprintable, then it's extremely unlikely to be something a user cared about seeing, and I can feel confident in calling it an actual error. |
That sounds reasonable. |
@JMurph2015 Yes, I was thinking along those lines. If we can make it an API (of sorts) that would be very useful in other situations. |
So the train has kinda left the station for me to do this on my internship time, but I can probably hack around a little and talk about what this should look like on my free time. Maybe we should make an empty PR or something to talk out how this should look? |
I posted this issue on the octave_kernel repo, but after digging into the source, I discovered it may be generic to all kernels based on Metakernel.
So here's the issue description again:
So when a kernel errors out, you should be sending back an execute-reply like this:
That way Jupyter can process that as a proper error and not just assume it is any old STDOUT.
Right now it would be a the easiest (?) fix to just rename what you are already returning to 'traceback' and insert some dummy values for the fields that you can't get easily.
It would be really awesome if this were fixed because it's breaking my use case!
The text was updated successfully, but these errors were encountered: