spyder-ide / spyder

Official repository for Spyder - The Scientific Python Development Environment
https://www.spyder-ide.org
MIT License
8.22k stars 1.59k forks source link

Couple of tracebacks when launching Spyder 6.0.0a4 for the first time #21856

Open dalthviz opened 6 months ago

dalthviz commented 6 months ago

Issue Report Checklist

Problem Description

Installed Spyder 6.0.0a4 in a new env and in the first launch I got a couple of tracebacks printed in the Anaconda prompt instance from where I launched Spyder. Also, I think I had a custom interpreter selected which didn't comply with the minimum spyder-kernels version required for Spyder 6.0.0a4

What steps reproduce the problem?

  1. Run the following to create a new env:
conda create -n spyder6_test -c conda-forge python=3.11
conda activate spyder6_test
conda install -c conda-forge/label/spyder_dev -c conda-forge/label/spyder_kernels_rc -c conda-forge spyder=6.0.0a4
  1. Launch Spyder

What is the expected output? What do you see instead?

No tracebacks when launching Spyder. Couple of tracebacks are shown over the Anaconda prompt instance used to launch Spyder

Paste Traceback/Error Below (if applicable)

fromIccProfile: failed minimal tag size sanity
Traceback (most recent call last):
  File "C:\Users\dalth\anaconda3\envs\spyder6_test\Lib\site-packages\spyder\plugins\debugger\widgets\main_widget.py", line 736, in showEvent
    self._update_splitter_widths(self.width())
  File "C:\Users\dalth\anaconda3\envs\spyder6_test\Lib\site-packages\spyder\plugins\debugger\widgets\main_widget.py", line 759, in _update_splitter_widths
    self.splitter.setSizes([base_width - table_width, table_width])
TypeError: index 0 has type 'float' but 'int' is expected
Traceback (most recent call last):
  File "C:\Users\dalth\anaconda3\envs\spyder6_test\Lib\site-packages\spyder\plugins\ipythonconsole\plugin.py", line 898, in update_path
    self.get_widget().update_path(path_dict, new_path_dict)
  File "C:\Users\dalth\anaconda3\envs\spyder6_test\Lib\site-packages\spyder\plugins\ipythonconsole\widgets\main_widget.py", line 2206, in update_path
    shell.update_syspath(path_dict, new_path_dict)
  File "C:\Users\dalth\anaconda3\envs\spyder6_test\Lib\site-packages\spyder\plugins\ipythonconsole\widgets\shell.py", line 685, in update_syspath
    self.call_kernel(
  File "C:\Users\dalth\anaconda3\envs\spyder6_test\Lib\site-packages\spyder\plugins\ipythonconsole\widgets\shell.py", line 349, in call_kernel
    return self.kernel_handler.kernel_comm.remote_call(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'kernel_comm'

Versions

Dependencies

# Mandatory:
atomicwrites >=1.2.0              :  1.4.1 (OK)
chardet >=2.0.0                   :  5.2.0 (OK)
cloudpickle >=0.5.0               :  3.0.0 (OK)
cookiecutter >=1.6.0              :  2.6.0 (OK)
diff_match_patch >=20181111       :  20230430 (OK)
intervaltree >=3.0.2              :  3.1.0 (OK)
IPython >=8.13.0,<9.0.0,!=8.17.1  :  8.22.2 (OK)
jedi >=0.17.2,<0.20.0             :  0.19.1 (OK)
jellyfish >=0.7                   :  1.0.3 (OK)
jsonschema >=3.2.0                :  4.21.1 (OK)
keyring >=17.0.0                  :  24.3.1 (OK)
nbconvert >=4.0                   :  7.16.2 (OK)
numpydoc >=0.6.0                  :  1.6.0 (OK)
paramiko >=2.4.0                  :  3.4.0 (OK)
parso >=0.7.0,<0.9.0              :  0.8.3 (OK)
pexpect >=4.4.0                   :  4.9.0 (OK)
pickleshare >=0.4                 :  0.7.5 (OK)
psutil >=5.3                      :  5.9.8 (OK)
pygments >=2.0                    :  2.17.2 (OK)
pylint >=2.5.0,<3.1               :  2.16.2 (OK)
pylint_venv >=3.0.2               :  3.0.3 (OK)
pyls_spyder >=0.4.0               :  0.4.0 (OK)
pylsp >=1.10.0,<1.11.0            :  1.10.0 (OK)
pylsp_black >=2.0.0,<3.0.0        :  2.0.0 (OK)
pyuca >=1.2                       :  1.2 (OK)
qdarkstyle >=3.2.0,<3.3.0         :  3.2.3 (OK)
qstylizer >=0.2.2                 :  0.2.2 (OK)
qtawesome >=1.3.0                 :  1.3.0 (OK)
qtconsole >=5.5.1,<5.6.0          :  5.5.1 (OK)
qtpy >=2.4.0                      :  2.4.1 (OK)
rtree >=0.9.7                     :  1.2.0 (OK)
setuptools >=49.6.0               :  69.1.1 (OK)
sphinx >=0.6.6                    :  7.2.6 (OK)
spyder_kernels >=3.0.0b4,<3.0.0b5 :  3.0.0b4 (OK)
superqt >=0.6.1,<1.0.0            :  0.6.1 (OK)
textdistance >=4.2.0              :  4.5.0 (OK)
three_merge >=0.1.1               :  0.1.1 (OK)
watchdog >=0.10.3                 :  4.0.0 (OK)
zmq >=22.1.0                      :  25.1.2 (OK)

# Optional:
cython >=0.21                     :  None (NOK)
matplotlib >=3.0.0                :  None (NOK)
numpy >=1.7                       :  None (NOK)
pandas >=1.1.1                    :  None (NOK)
scipy >=0.17.0                    :  None (NOK)
sympy >=0.7.3                     :  None (NOK)
ccordoba12 commented 6 months ago

Thanks @dalthviz. I'll take care of this one.

ccordoba12 commented 6 months ago

@impact27, how do you think we should handle this error?

Traceback (most recent call last):
  File "C:\Users\dalth\anaconda3\envs\spyder6_test\Lib\site-packages\spyder\plugins\ipythonconsole\plugin.py", line 898, in update_path
    self.get_widget().update_path(path_dict, new_path_dict)
  File "C:\Users\dalth\anaconda3\envs\spyder6_test\Lib\site-packages\spyder\plugins\ipythonconsole\widgets\main_widget.py", line 2206, in update_path
    shell.update_syspath(path_dict, new_path_dict)
  File "C:\Users\dalth\anaconda3\envs\spyder6_test\Lib\site-packages\spyder\plugins\ipythonconsole\widgets\shell.py", line 685, in update_syspath
    self.call_kernel(
  File "C:\Users\dalth\anaconda3\envs\spyder6_test\Lib\site-packages\spyder\plugins\ipythonconsole\widgets\shell.py", line 349, in call_kernel
    return self.kernel_handler.kernel_comm.remote_call(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'kernel_comm'

It seems the kernel takes too much time to start, so kernel_handler is not available when call_kernel is called.

Of course we could catch that exception and pass. But then all those calls to call_kernel wouldn't have any effect, which would lead to a bad user experience for users. For instance, in this case users would think that the paths they added in our Python path manager were automatically appended to sys.path in the console, but that wouldn't be the case.

impact27 commented 6 months ago

I didn't check the specifics, but in general the initial kernel setup is done in send_spyder_kernel_configuration. It should be able to do a full setup in case of kernel restart. Before this function is called the kernel is not ready anyway. So the path for example should be added there.

impact27 commented 6 months ago

the set_kernel_configuration method allows to set a configuration before the kernel is ready. It also survives a restart.

impact27 commented 6 months ago

What is strange is that both the Shellwidget and the kernel_handler are created in create_new_client, so there shouldn't be a time where kernel_handler is None? unless the eventloop runs while create_new_client is executed?

ccordoba12 commented 6 months ago

What is strange is that both the Shellwidget and the kernel_handler are created in create_new_client, so there shouldn't be a time where kernel_handler is None?

I think that can happen when there's an error starting the kernel:

https://github.com/spyder-ide/spyder/blob/ad17193e2b6c16ad066f9db210116ff0e214a629/spyder/plugins/ipythonconsole/widgets/main_widget.py#L1498-L1506

In that case kernel_handler will remain as None in ShellWidget. So, perhaps catching that error and pass is not a bad idea?

ccordoba12 commented 6 months ago

@impact27, I saw that you opened PR #21895 to address this. Thanks for your help with that!

But could you explain your rationale for that change?

impact27 commented 6 months ago

The sys.path is set in two ways: by setting the "SPY_PYTHONPATH" environment variable and by calling update_path. the first way is problematic because in case of a restart after changing the python path the old python path is restored. The second way is problematic because by calling remote_call directly without checking for the kernel state you can end up with the error in this issue.

impact27 commented 6 months ago

In fact this is true of most of the config that is set by an environment variable, I will change these as well.