Repository: spyder-ide/spyder

Issue:
Spyder on Windows 10, remote kernel on RPi Zero, Python script not found
## Description

### What steps will reproduce the problem?

<!--- You can use Markdown here --->

First I did follow steps described on http://docs.spyder-ide.org/current/panes/ipythonconsole.html?highlight=ssh#connect-to-a-remote-kernel

Got remote kernel in Spyder running on W10:
```
[]: !uname -a
Linux zero2 5.10.63-v7+ #1459 SMP Wed Oct 6 16:41:10 BST 2021 armv7l GNU/Linux

[]: import rpi_ws281x as ws

[]:
```
Then attempted to debug code in remote kernel:
```
[]: !ls -l /home/pi/works/deck_cntrl/big_led_strip.py
-rw-r--r-- 1 pi pi 6014 Feb  2 02:22 /home/pi/works/deck_cntrl/big_led_strip.py

[]: debugfile('/home/pi/works/deck_cntrl/big_led_strip.py', wdir='/home/pi/works/deck_cntrl')
This command failed to be executed because an error occurred while trying to get the file code from Spyder's editor. The error was:

An exception has occurred, use %tb to see the full traceback.

FileNotFoundError: [Errno 2] No such file or directory: '/home/pi/works/deck_cntrl/big_led_strip.py'
```
I can run the script after logging to RPi, from command prompt, so the code works fine. 

Is there any chance to use W10 as Spyder execution system and run the code in remote kernel on RPi? The rationale behind this setup is the lack of computing power on RPi (it is Zero W) -- it would run local Spyder with display on remote X Server, but the performance is unacceptable.

--Piotr



## Versions

* Spyder version: 5.2.2 
* Python version: 3.9.10
* Qt version: 5.12.9
* PyQt5 version: 5.12.3
* Operating System: Windows 10

### Dependencies

```
# Mandatory:
atomicwrites >=1.2.0          :  1.4.0 (OK)
chardet >=2.0.0               :  4.0.0 (OK)
cloudpickle >=0.5.0           :  2.0.0 (OK)
cookiecutter >=1.6.0          :  1.7.3 (OK)
diff_match_patch >=20181111   :  20200713 (OK)
intervaltree >=3.0.2          :  3.0.2 (OK)
IPython >=7.6.0;<8.0.0        :  7.31.1 (OK)
jedi >=0.17.2;<0.19.0         :  0.18.1 (OK)
jellyfish >=0.7               :  0.9.0 (OK)
jsonschema >=3.2.0            :  4.4.0 (OK)
keyring >=17.0.0              :  21.2.1 (OK)
nbconvert >=4.0               :  6.4.1 (OK)
numpydoc >=0.6.0              :  1.2 (OK)
paramiko >=2.4.0              :  2.9.2 (OK)
parso >=0.7.0;<0.9.0          :  0.8.3 (OK)
pexpect >=4.4.0               :  4.8.0 (OK)
pickleshare >=0.4             :  0.7.5 (OK)
psutil >=5.3                  :  5.9.0 (OK)
pygments >=2.0                :  2.11.2 (OK)
pylint >=2.5.0                :  2.12.2 (OK)
pyls_spyder >=0.4.0           :  0.4.0 (OK)
pylsp >=1.3.2;<1.4.0          :  1.3.3 (OK)
pylsp_black >=1.0.0           :  1.1.0 (OK)
qdarkstyle =3.0.2             :  3.0.2 (OK)
qstylizer >=0.1.10            :  0.2.1 (OK)
qtawesome >=1.0.2             :  1.1.1 (OK)
qtconsole >=5.2.1;<5.3.0      :  5.2.2 (OK)
qtpy >=1.5.0                  :  2.0.0 (OK)
rtree >=0.9.7                 :  0.9.7 (OK)
setuptools >=49.6.0           :  60.6.0 (OK)
sphinx >=0.6.6                :  3.5.4 (OK)
spyder_kernels >=2.2.1;<2.3.0 :  2.2.1 (OK)
textdistance >=4.2.0          :  4.2.2 (OK)
three_merge >=0.1.1           :  0.1.1 (OK)
watchdog >=0.10.3             :  2.1.6 (OK)
zmq >=17                      :  22.3.0 (OK)

# Optional:
cython >=0.21                 :  None (NOK)
matplotlib >=2.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)
```



Discussion:
Hey @piotr-machowski, thanks for reporting. How did you run this command?

    debugfile('/home/pi/works/deck_cntrl/big_led_strip.py', wdir='/home/pi/works/deck_cntrl')

By pressing the Debug button or by introducing the command directly in the console?
I have entered both commands directly in console (!ls and debug).
Hey @piotr-machowski, why did close this one? Did you find a solution for it?
It was not my intention to close it. I did refresh the page with the
report, but not closed it. No, I don't have solution to the problem of
remote kernel.

--Piotr

On Thu, Feb 10, 2022 at 5:44 PM Carlos Cordoba ***@***.***>
wrote:

> Hey @piotr-machowski <https://github.com/piotr-machowski>, why did close
> this one? Did you find a solution for it?
>
> —
> Reply to this email directly, view it on GitHub
> <https://github.com/spyder-ide/spyder/issues/17289#issuecomment-1035147365>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AHY7VQGU6F52WRLOLFDDZYTU2PTQHANCNFSM5NNFHOPA>
> .
> Triage notifications on the go with GitHub Mobile for iOS
> <https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
> or Android
> <https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
>
> You are receiving this because you were mentioned.Message ID:
> ***@***.***>
>

Ok, no worries. I think we can solve this problem but I'm still not sure where.
Hey @piotr-machowski, could you run the `%tb` magic in the console after the error you're having and post the result here?

I think I know how to solve this problem now, but I'd like to be sure.
Sorry for delay, I somewhat missed the notification. Will answer in few hours.
Great! Thanks for your help @piotr-machowski!
Update. Unfortunately I have lost the OS in which the problem has been initially identified (SD card in Raspberry died and I had to reinstall Raspbian; I use several Raspberrys for many years now and it happened for the first time...). So I have new OS installed but ... the symptoms are the same:
- started kernel on remote machine (Raspberry)
- in Spyder on Windows started console with external kernel
- in Spyder loaded Python script *from local folder on Windows* (a copy from Raspberry)
- in Spyder console verified, that we are connected to remote kernel:
```
In []: !uname -a
Linux zero-2 5.10.92-v7+ #1514 SMP Mon Jan 17 17:36:39 GMT 2022 armv7l GNU/Linux
```
- in Spyder console entered runfile command and got error:
```
In []: runfile('/home/pi/works/deck_cntrl/big_led_strip.py', args='--help', wdir='/home/pi/works/deck_cntrl')
This command failed to be executed because an error occurred while trying to get the file code from Spyder's editor. The error was:

An exception has occurred, use %tb to see the full traceback.

FileNotFoundError: [Errno 2] No such file or directory: '/home/pi/works/deck_cntrl/big_led_strip.py'
```
Here is %tb output:
```
In []: %tb
Traceback (most recent call last):

  File "/usr/local/lib/python3.9/dist-packages/spyder_kernels/customize/spydercustomize.py", line 488, in get_file_code
    file_code = frontend_request().get_file_code(

  File "/usr/local/lib/python3.9/dist-packages/spyder_kernels/comms/commbase.py", line 557, in __call__
    return self._comms_wrapper._get_call_return_value(

  File "/usr/local/lib/python3.9/dist-packages/spyder_kernels/comms/commbase.py", line 440, in _get_call_return_value
    return self._sync_error(reply['value'])

  File "/usr/local/lib/python3.9/dist-packages/spyder_kernels/comms/commbase.py", line 496, in _sync_error
    error_wrapper.raise_error()

  File "/usr/local/lib/python3.9/dist-packages/spyder_kernels/comms/commbase.py", line 90, in raise_error
    raise self.etype(self)

FileNotFoundError: [Errno 2] No such file or directory: '/home/pi/works/deck_cntrl/big_led_strip.py'
```

But guided by our previous conversation I started the script by pressing *Run* button in Spyder and ... the script was executed on remote kernel! However Spyder still complained about missing script (despite the fact that the script was actually properly executed!):
```
In []: runfile('C:/Users/piotr/Dropbox/8-prv/1-development/python/rpi/deck_cntrl/big_led_strip.py', args='--help', wdir='C:/Users/piotr/Dropbox/8-prv/1-development/python/rpi/deck_cntrl')
Working directory C:/Users/piotr/Dropbox/8-prv/1-development/python/rpi/deck_cntrl doesn't exist.

usage: big_led_strip.py [-h]
```
The "usage" text is the correct output from the script.

Hope that helps.

Update 2: the trick to run the script with the Windows path works also when entered manually into console (same behavior: complains but executes the script). However if I try to debug the script I get a new error:
```
In []: debugfile('C:/Users/piotr/Dropbox/8-prv/1-development/python/rpi/deck_cntrl/big_led_strip.py', args='--swi --deb', wdir='C:/Users/piotr/Dropbox/8-prv/1-development/python/rpi/deck_cntrl')
This command failed to be executed because an error occurred while trying to get the file code from Spyder's editor. The error was:


An exception has occurred, use %tb to see the full traceback.

OSError: [Errno 22] Invalid argument: '/home/pi/works/deck_cntrl/C:/Users/piotr/Dropbox/8-prv/1-development/python/rpi/deck_cntrl/big_led_strip.py'


In []: %tb
Traceback (most recent call last):

  File "/usr/local/lib/python3.9/dist-packages/spyder_kernels/customize/spydercustomize.py", line 488, in get_file_code
    file_code = frontend_request().get_file_code(

  File "/usr/local/lib/python3.9/dist-packages/spyder_kernels/comms/commbase.py", line 557, in __call__
    return self._comms_wrapper._get_call_return_value(

  File "/usr/local/lib/python3.9/dist-packages/spyder_kernels/comms/commbase.py", line 440, in _get_call_return_value
    return self._sync_error(reply['value'])

  File "/usr/local/lib/python3.9/dist-packages/spyder_kernels/comms/commbase.py", line 496, in _sync_error
    error_wrapper.raise_error()

  File "/usr/local/lib/python3.9/dist-packages/spyder_kernels/comms/commbase.py", line 90, in raise_error
    raise self.etype(self)

OSError: [Errno 22] Invalid argument: '/home/pi/works/deck_cntrl/C:/Users/piotr/Dropbox/8-prv/1-development/python/rpi/deck_cntrl/big_led_strip.py'
```

Look at the error message: `Invalid argument: '>>>/home/pi/works/deck_cntrl<<</C:/Users/piotr/Dropbox/8-prv/1-development/python/rpi/deck_cntrl/big_led_strip.py'`. The indicated part was not entered in the debugfile command... BTW: /home/pi/works/deck_cntrl is the working directory of remote kernel (cwd).

Resolving patch:
diff --git a/external-deps/spyder-kernels/spyder_kernels/customize/spydercustomize.py b/external-deps/spyder-kernels/spyder_kernels/customize/spydercustomize.py
--- a/external-deps/spyder-kernels/spyder_kernels/customize/spydercustomize.py
+++ b/external-deps/spyder-kernels/spyder_kernels/customize/spydercustomize.py
@@ -31,7 +31,7 @@
 from spyder_kernels.customize.spyderpdb import SpyderPdb, get_new_debugger
 from spyder_kernels.customize.umr import UserModuleReloader
 from spyder_kernels.py3compat import (
-    TimeoutError, PY2, _print, encode, compat_exec)
+    TimeoutError, PY2, _print, encode, compat_exec, FileNotFoundError)
 from spyder_kernels.customize.utils import (
     capture_last_Expr, normalise_filename)
 
@@ -511,7 +511,7 @@ def get_file_code(filename, save_all=True):
     try:
         file_code = frontend_request(blocking=True).get_file_code(
             filename, save_all=save_all)
-    except (CommError, TimeoutError, RuntimeError):
+    except (CommError, TimeoutError, RuntimeError, FileNotFoundError):
         file_code = None
     if file_code is None:
         with open(filename, 'r') as f:
diff --git a/external-deps/spyder-kernels/spyder_kernels/py3compat.py b/external-deps/spyder-kernels/spyder_kernels/py3compat.py
--- a/external-deps/spyder-kernels/spyder_kernels/py3compat.py
+++ b/external-deps/spyder-kernels/spyder_kernels/py3compat.py
@@ -317,8 +317,10 @@ def iterlists(d, **kw):
 # =============================================================================
 if PY2:
     TimeoutError = RuntimeError
+    FileNotFoundError = IOError
 else:
     TimeoutError = TimeoutError
+    FileNotFoundError = FileNotFoundError
 
 if PY2:
     import re


Test patch: