-
-
Notifications
You must be signed in to change notification settings - Fork 40
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
Debugger not working for environments with different Python versions #468
Comments
Hey @rhkarls, thanks for reporting. I think this is a problem with IPython 8.15, so could you downgrade to 8.14 and try again? |
@impact27, could you take a look at this one? I was able to reproduce point 2) above and it only affects master. |
Indeed, downgrading to 8.14 works for spyder_env. However, for the custom env downgrading to 8.14 does not work. In the case of 1) above: same CommsErrorWrapper as in the initial report. |
The "TypeError: unsupported operand type(s) for +: 'int' and 'str'" should be fixed by #467 so point 2) should not happen in master? |
for point 1) #476 will send the correct error which is maybe a cloud pickle issue |
@rhkarls, Spyder alpha3 will be released in a couple of days, so let us know if this error persists with that version. |
In case it helps: as far as I can see this error remains on 6.0.0a5 and spyder-kernels 3.0.0b5 if Spyder is installed in an env with python 3.10. When Spyder 6.0.0a5 is installed with Python 3.11 the examples above work as expected with Spyders own environment and with custom environments with python 3.10, 3.11 and 3.12. |
Could you try with #492 ? |
@impact27, I was able to reproduce this. And after applying your patch in #492, now I'm seeing this error: Exception in comms call get_current_frames:
File "/home/carlos/Projects/spyder/spyder/external-deps/spyder-kernels/spyder_kernels/comms/commbase.py", line 298, in _comm_message
buffer = cloudpickle.loads(msg['buffers'][0])
AttributeError: Can't get attribute '_class_setstate' on <module 'cloudpickle.cloudpickle' from '/home/carlos/miniconda3/envs/py310-pip/lib/python3.10/site-packages/cloudpickle/cloudpickle.py'> This happens after clicking in the Interrupt execution button because the debugger also hangs in this case. |
That is not an helpful error :/ is this only an issue when you cross python versions correct? @ccordoba12 what versions os python did you use? |
Sorry, that's what I'm seeing but I can get more info if you need it.
Yep, I confirmed it is.
Python 3.10 in the frontend (i.e. for Spyder) and 3.12 for the kernel. |
I assume |
After making the Exception in comms call get_current_frames:
File "/home/carlos/Projects/spyder/spyder/external-deps/spyder-kernels/spyder_kernels/comms/commbase.py", line 298, in _comm_message
buffer = cloudpickle.loads(msg['buffers'][0])
TypeError: code expected at most 16 arguments, got 18 which a quick googling pointed to this issue: cloudpipe/cloudpickle#451. And this cloudpipe/cloudpickle#451 (comment) on that issue mentions that, according to Cloudpickle's Readme
which is still present in it. But after taking a closer look at Cloudpickle's code, I found the If I understand it correctly, it means that:
I tested the second case and it's working as expected (without the changes in PR #492). I'll test the first one next week, unless @rhkarls beats me to it. |
That is not ideal. I guess the problem is that if named tuple is not the same between versions of python then you can't do anything? I tried to change the definition of SpyderFrameSummary to a custom frame but this will be a problem more generally. |
Most comms send and receive basic objects (strings, list, dict, float) but some are more general and this will be a problem. (get/set_value for example) |
@ccordoba12 with a few adjustments we can replace cloudpickle with json so this class of problem disappears |
Ok, I saw your PRs about it. But I'd like to know how get/set_value is going to work without Cloudpickle because I think we need it to serialize arbitrary Python objects. And I doubt serializing them with json is enough for all objects. Is it not possible to send the frame info back to Spyder using a dict to avoid doing removing Cloudpickle? |
The problem here is that cloudpickle only works for the exact same version of python, and we use in general different versions of python, and therefore can not use cloudpickle. I tried replacing cloudpickle with json and all the tests are passing. In general if this is a problem we just need to encode in the calling function whatever object we want to send between the kernel and frontend. But I think we need to be careful about doing that. The current solution hides this complexity and introduces hard to detect and debug bugs. Do you know of any example where this might be a problem? |
What we could do is to use cloudpickle only in get/set_value? |
Sure, I understand that. But we haven't had any serious issues so far (as far as I recall this is the first one).
Yeah, but we're testing simple objects (Numpy arrays and dataframes) which (I guess) are easily serializable with json.
Ok, that seems quite reasonable.
No, but I doubt our users wouldn't take long to find problems with this new approach because they're using it to view all kind of objects. However, I wouldn't like to discard what you've done but complement it, if possible, by sending objects with Cloudpickle and Jsonpickle to be able to display objects created with libraries not available on the Spyder side. That would be a significant improvement for users of our installers because it's not easy to install other libraries on them. |
I guess most users are using the same interpreter for the kernel and frontend, so the issue with cloudpickle doesn’t show up that much. If the only use for cloudpickle is the variable explorer, then it should be used only there. This will greatly simplify the handling of errors. We could for example serialise with cloudpickle and then send the base64 representation by comms so there is no need to have more complexity in the comms the more general question I have because I am not that much knowledgeable with the variable explorer is: how do we edit a generic python object? Don’t we need a specific editor for each class? |
I tried that in spyder-ide/spyder#22120 |
We have one editor called ObjectExplorer (IIRC) which works on arbitrary objects, but it can only be used to view objects, not to edit them. We have separate editors for list/set/tuple, numpy arrays and pandas dataframe. Actually, the use of cloudpickle in the variable explorer is also problematic,
I don't understand this. How can we unpickle an object if its class is not installed on the Spyder side? |
from cloud pickle doc:
One advantage of my approach in the PR is that it makes it easy to find a new solution for this in the future. Indeed cloud pickle is only used in get/set_value so another solution can easily be deployed without affecting the rest of the comms. |
By using Jsonpickle, which creates a Json representation of a Python object that we can display in a Json tree viewer. So, the object wouldn't be editable but at least users would be able to check its internals. |
Got it, we don't unpickle but read the json directly. That sounds like a good approach. |
I think this is a spyder-kernels issue, apologies if not!
Using Spyder 6 alpha 2 and spyder-kernels 3.0.0b2, with a simple .py file with one line
1/0
.Spyder is installed using mamba following the instructions on https://github.com/spyder-ide/spyder/releases
Two different ways to attempt debugging
%debug
magic in consoleWith two different environments,
spyder-env
where Spyder is installed (3.10) andcustom_env
running Python 3.11.For 1) Spyder crashes with
TypeError: 'CommsErrorWrapper' object is not subscriptable
using the custom conda environment (custom_env
). It does not crash when using the same environment as Spyder (spyder-env
).For 2), running the file, then %debug in ipython console raises TypeError below both with custom environment and using the
spyder-env
where Spyder 6a2 is installed.Versions
Dependencies
The text was updated successfully, but these errors were encountered: