bulletmark/mpr

Is recursive put broken?

Closed this issue · 19 comments

I was trying out mpr as a better mpremote and was wanting to copy a directory from local to remote recursively.

I am running in a windows command prompt and have a virtual env with mpr installed:

(raspberry-pi-pico) C:\Users\<snip>\gui\demo>pip list
Package            Version
------------------ -------
mpr                1.19
mpremote           1.20.0
pip                22.3.1

and help for command says put can do recursive

(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr put -h
usage: mpr put [-h] [-f] [-r] src [src ...] dst

Copy one or more local files to directory on device.

positional arguments:
  src              name of local source file[s] on PC
  dst              name of destination dir on device

options:
  -h, --help       show this help message and exit
  -f, --file       destination is file, not directory
  -r, --recursive  copy local directory recursively to / on device

on my local I have

(raspberry-pi-pico) C:\Users\<snip>\gui\demo>tree
C:.
├───driver
│   └───generic
└───lib

and to "copy local directory recursively":

(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr put -r driver /
mpremote requires source must be directory and target must be "/"

what I see is driver is a directory
and target I have put as /

I have also tried the destination as:

  • driver
  • /driver
  • /driver/
  • driver/
    and none of those worked.

also tried next most logical thing for me - write it out longhand

mpr -v p driver\generic\axp192.py driver/generic/axp192.py
(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr -v p driver\generic\axp192.py driver/generic/axp192.py
mpremote cp driver\generic\axp192.py :driver\generic\axp192.py\axp192.py
cp driver\generic\axp192.py :driver\generic\axp192.py\axp192.py
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: 20

and variant

(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr -v p driver\generic\axp192.py /driver/generic/axp192.py
mpremote cp driver\generic\axp192.py :\driver\generic\axp192.py\axp192.py
cp driver\generic\axp192.py :\driver\generic\axp192.py\axp192.py
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: 20

in the end as a workaround, I just used a text editor script to paste in a set of commands like

mpr -v p driver\generic\axp192.py /driver/generic
(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr -v p driver\generic\axp192.py /driver/generic
mpremote cp driver\generic\axp192.py :\driver\generic\axp192.py
cp driver\generic\axp192.py :\driver\generic\axp192.py

Must be a windows issue because I just created driver/generic/axp192.py and did mpr put -r driver / just fine.

I just improved that error message. Can you please install the latest master, eg ./venv/bin/pip install "git+https://github.com/bulletmark/mpr", and run it again.

Can you also please paste the output of:

$ mpr -V
$ mpr -v version

Actually, thinking about how this probably works on windows, I have committed a likely fix so please try it. It would be good if you could also try a few other commands to confirm there are no other windows issues.

Did the pip install

pip install "git+https://github.com/bulletmark/mpr"
(raspberry-pi-pico) C:\Users\<snip>>pip install "git+https://github.com/bulletmark/mpr"
Collecting git+https://github.com/bulletmark/mpr
  Cloning https://github.com/bulletmark/mpr to c:\users\<snip>\appdata\local\temp\pip-req-build-6kcl4fln
  Running command git clone --filter=blob:none --quiet https://github.com/bulletmark/mpr 'C:\Users\<snip>\AppData\Local\Temp\pip-req-build-6kcl4fln'
  Resolved https://github.com/bulletmark/mpr to commit 96bfec073fa08e4f1c02779c99ead632e852df0f
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Installing backend dependencies ... done
  Preparing metadata (pyproject.toml) ... done
Building wheels for collected packages: mpr
  Building wheel for mpr (pyproject.toml) ... done
  Created wheel for mpr: filename=mpr-1.19.post4+g96bfec0-py3-none-any.whl size=14762 sha256=7406507771ef01eb1d49d30dbf368e9ca1836bbd2afcd172a8e1724bb21ba628
  Stored in directory: C:\Users\<snip>\AppData\Local\Temp\pip-ephem-wheel-cache-011spsd1\wheels\d0\be\b9\3c43da895bcced95e4ede8baff14fb7374fc0d8a2943c49106
Successfully built mpr
Installing collected packages: mpr
  Attempting uninstall: mpr
    Found existing installation: mpr 1.19
    Uninstalling mpr-1.19:
      Successfully uninstalled mpr-1.19
Successfully installed mpr-1.19.post4+g96bfec0

Version info:

mpr -V
(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr -V
1.19.post4+g96bfec0
mpr -v version
(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr -v version
mpremote version
mpremote 1.20.0

and the recursive put worked nicely

mpr put -r driver /
(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr put -r driver /
cp driver/generic/axp192.py :driver/generic/
cp driver/generic/ft6x36.py :driver/generic/
cp driver/generic/ili9xxx-test.py :driver/generic/
cp driver/generic/ili9xxx.py :driver/generic/
cp driver/generic/st77xx-test.py :driver/generic/
cp driver/generic/st77xx.py :driver/generic/
cp driver/generic/xpt2046-test.py :driver/generic/
cp driver/generic/xpt2046.py :driver/generic/

mpr put -r lib /
(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr put -r lib /
cp lib/display_driver.py :lib/
cp lib/display_driver_utils.py :lib/
cp lib/fs_driver.py :lib/
cp lib/lv_colors.py :lib/
cp lib/lv_utils.py :lib/
cp lib/tpcal.py :lib/
cp lib/utils.py :lib/

Can you please experiment with various commands to let me know if they all work on windows.

mpr -h
(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr -h
usage: mpr [-h] [-d DEVICE] [-m MOUNT] [-M MOUNT_UNSAFE_LINKS] [-x] [-b] [-p PATH_TO_MPREMOTE] [--mip-list-url MIP_LIST_URL] [-c]
           [-v] [-V]
           {get,g,put,p,copy,c,ls,mkdir,mkd,rmdir,rmd,rm,touch,edit,e,reset,x,reboot,b,repl,r,list,l,devs,run,eval,exec,mip,m,bootloader,df,rtc,version,config,cf}
           ...

This is a command line tool to wrap the MicroPython mpremote tool and provide a more conventional command line interface. Multiple
arguments can be specified for commands and inbuilt usage help is provided for all commands.

options:
  -h, --help            show this help message and exit
  -d DEVICE, --device DEVICE
                        serial port/device to connect to, default is "auto". Specify "-d list" to print out device mnemonics that
                        can be used.
  -m MOUNT, --mount MOUNT
                        mount local directory on device before command
  -M MOUNT_UNSAFE_LINKS, --mount-unsafe-links MOUNT_UNSAFE_LINKS
                        mount local directory and allow external links
  -x, --reset           do soft reset after command
  -b, --reboot          do hard reboot after command
  -p PATH_TO_MPREMOTE, --path-to-mpremote PATH_TO_MPREMOTE
                        path to mpremote program. Assumes same directory as this program, or then just "mpremote"
  --mip-list-url MIP_LIST_URL
                        mip list url for packages, default="https://micropython.org/pi/v2/index.json"
  -c, --completion      output shell TAB completion code
  -v, --verbose         print executed commands (for debug)
  -V, --version         show mpr version

Commands:
  {get,g,put,p,copy,c,ls,mkdir,mkd,rmdir,rmd,rm,touch,edit,e,reset,x,reboot,b,repl,r,list,l,devs,run,eval,exec,mip,m,bootloader,df,rtc,version,config,cf}
    get (g)             Copy one or more files from device to local directory.
    put (p)             Copy one or more local files to directory on device.
    copy (c)            Copy one of more remote files to a directory on device.
    ls                  List directory on device.
    mkdir (mkd)         Create the given directory[s] on device.
    rmdir (rmd)         Remove the given directory[s] on device.
    rm                  Remove the given file[s] on device.
    touch               Touch the given file[s] on device.
    edit (e)            Edit the given file[s] on device.
    reset (x)           Soft reset the device.
    reboot (b)          Hard reboot the device.
    repl (r)            Enter REPL on device.
    list (l, devs)      List currently connected devices.
    run                 Run the given local scripts on device.
    eval                Evaluate and print the given strings on device.
    exec                Execute the given strings on device.
    mip (m)             Run mip to install packages on device.
    bootloader          Enter bootloader on device.
    df                  Show flash usage on device.
    rtc                 Get/set the Real Time Clock (RTC) time from/to device.
    version             Show mpremote version.
    config (cf)         Open the mpr configuration file with your editor.

Type "mpr <command> -h" to see specific help/usage for any of the above commands. Note you can set default options in
~\.config\mpr.conf (e.g. for --path-to-mpremote or --mip-list-url). Use "mpr config" to conveniently change the file.
mpr list
(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr list
COM3 E66044304323442B 2e8a:0005 Microsoft None
mpr ls
(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr ls
ls :/
           0 driver/
           0 lib/
         645 main.py

Pico was connected in VS Code:

mpr get main.py -
(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr get main.py -
no device found  

Pico was disconnected in VS Code:

mpr get main.py -
(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr get main.py -
from machine import Pin
from utime import sleep
import lvgl as lv
<snip>
mpr -v mkdir bob
(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr -v mkdir bob
mpremote mkdir bob
mkdir :bob
mpr -v rmdir bob
(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr -v rmdir bob
mpremote rmdir bob
rmdir :bob
mpr -v list
(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr -v list
mpremote devs
COM3 E66044304323442B 2e8a:0005 Microsoft None
mpr -v df
(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr -v df
mpremote df
mount   size    used    avail   use%
        1048576 159744  888832  15
driver  1048576 159744  888832  15
lib     1048576 159744  888832  15

play with rtc

(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr -v rtc
mpremote rtc
mpremote: 'rtc' is not a command

(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr rtc
mpremote: 'rtc' is not a command

(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr rtc -h
usage: mpr rtc [-h] [-s]

Get/set the Real Time Clock (RTC) time from/to device.

options:
  -h, --help  show this help message and exit
  -s, --set   set the RTC to the current PC time, default is to get the time

(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr rtc -s
mpremote: 'rtc' is not a command

launched bootloader:

(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr -v bootloader
mpremote bootloader

some commands after entering bootloader:

(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr reboot
no device found

(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr reset
no device found

(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr -v bootloader
mpremote bootloader
no device found

plug device back in again and do a reset

mpr reset
(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr reset
Connected to MicroPython at COM3
Use Ctrl-] or Ctrl-x to exit this shell
>
MicroPython v1.20.0-700-g841ece132 on 2023-08-17; Raspberry Pi Pico with RP2040
Type "help()" for more information.
>>> print("hello")
hello
>>>

try edit file

(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr edit main.py
Traceback (most recent call last):
  File "C:\Users\<snip>\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Users\<snip>\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "C:\Users\<snip>\python\venvs\raspberry-pi-pico\Scripts\mpremote.exe\__main__.py", line 7, in <module>
  File "C:\Users\<snip>\python\venvs\raspberry-pi-pico\lib\site-packages\mpremote\main.py", line 502, in main
    handler_func(state, args)
  File "C:\Users\<snip>\python\venvs\raspberry-pi-pico\lib\site-packages\mpremote\commands.py", line 169, in do_edit
    raise pyboard.PyboardError("edit: $EDITOR not set")
mpremote.pyboard.PyboardError: edit: $EDITOR not set

try to see if windows variables works

(raspberry-pi-pico) C:\Users\<snip>\gui\demo>set EDITOR="C:\Progra~1\Notepad++\notepad++.exe"

(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr edit main.py
edit :main.py
The filename, directory name, or volume label syntax is incorrect.

try edit config

(raspberry-pi-pico) C:\Users\<snip>\gui\demo>mpr -v config
Traceback (most recent call last):
  File "C:\Users\<snip>\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Users\<snip>\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "C:\Users\<snip>\python\venvs\raspberry-pi-pico\Scripts\mpr.exe\__main__.py", line 7, in <module>
  File "C:\Users\<snip>\python\venvs\raspberry-pi-pico\lib\site-packages\mpr.py", line 342, in main
    args.func(args)
  File "C:\Users\<snip>\python\venvs\raspberry-pi-pico\lib\site-packages\mpr.py", line 700, in run
    subprocess.run(f'{editor} {cnffile}'.split())
  File "C:\Users\<snip>\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 501, in run
    with Popen(*popenargs, **kwargs) as process:
  File "C:\Users\<snip>\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 969, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "C:\Users\<snip>\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 1438, in _execute_child
    hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
FileNotFoundError: [WinError 2] The system cannot find the file specified

So in summary you found the following further issues:

  1. The rtc command does not work. That is because you are running an old version of mpremote. The rtc command was added to mpremote by this commit in May 2023.
  2. The reset command hangs. Again due to an old version of mpremote. That is due to a bug I reported in mpremote in Feb 2023 which was fixed by this commit in Aug 2023.
  3. The edit command fails because $EDITOR (which is universal on Linux) is not respected on Windows. I will have to add windows special code for this.
  4. The config command fails because I assume Linux paths/files etc. I will have to add windows special code for this.

Actually #3 above is not a bug in mpr, it is a bug in mpremote. mpr merely invokes the mpremote edit command and that $EDITOR not set etc error messages are coming out of mpremote. One of us should probably raise a bug on mpremote about that.

I think if you set EDITOR=notepad on windows it will work but I just pushed a commit which chooses notepad as the default on Windows so can you please try the latest master for the mpr cf command?

retried the edit and that worked nicely (not the latest master default...just read that comment when posting this

(raspberry-pi-pico) C:\Users\<snip>\lvgl\helloworld\libs>set EDITOR=notepad

(raspberry-pi-pico) C:\Users\<snip>\lvgl\helloworld\libs>mpr -v edit st77xx.py
mpremote edit st77xx.py
edit :st77xx.py

tried to copy a single file but that failed. I know that some of the below formats might not be technically correct giving the limitations of mpremote, but they would be idiomatic to me, its a shame that mpremote was not coded to be more like linux cp or windows copy

There was two things I was trying to achieve

  1. Copy a libs folder to remote - which works fine if I want a libs folder also on remote
  2. Because one of the files I was copying had a python import from the same directory, I ended up wanting all my remote files to be flat and in a single folder, but still wanted my lib python files locally in a lib folder
    so wanted to do things like copy lib/*.py /
    but could simple work around that by cd to lib then copy *.py to /
    but that didn't work so ended up copying them one by one
mpr -v c lv_utils.py /
(raspberry-pi-pico) C:\Users\<snip>\lvgl\helloworld\libs>mpr -v c lv_utils.py /
mpremote cp :lv_utils.py :lv_utils.py
cp :lv_utils.py :lv_utils.py
Traceback (most recent call last):
  File "C:\Users\<snip>\site-packages\mpremote\pyboard.py", line 547, in fs_stat
    return os.stat_result(self.eval("uos.stat(%s)" % (("'%s'" % src)), parse=True))
  File "C:\Users\<snip>\site-packages\mpremote\pyboard.py", line 484, in eval
    ret = self.exec_("print(repr({}))".format(expression))
  File "C:\Users\<snip>\site-packages\mpremote\pyboard.py", line 496, in exec_
    raise PyboardError("exception", ret, ret_err)
mpremote.pyboard.PyboardError: ('exception', b'', b'Traceback (most recent call last):\r\n  File "<stdin>", line 1, in <module>\r\nOSError: [Errno 2] ENOENT\r\n')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\<snip>Python310\lib\runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Users\<snip>Python310\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "C:\Users\<snip>\mpremote.exe\__main__.py", line 7, in <module>
  File "C:\Users\<snip>\site-packages\mpremote\main.py", line 502, in main
    handler_func(state, args)
  File "C:\Users\<snip>\site-packages\mpremote\commands.py", line 157, in do_filesystem
    pyboard.filesystem_command(
  File "C:\Users\<snip>\site-packages\mpremote\pyboard.py", line 704, in filesystem_command
    op(src2, dest2, progress_callback=progress_callback)
  File "C:\Users\<snip>\site-packages\mpremote\pyboard.py", line 584, in fs_cp
    src_size = self.fs_stat(src).st_size
  File "C:\Users\<snip>\site-packages\mpremote\pyboard.py", line 549, in fs_stat
    raise e.convert(src)
  File "C:\Users\<snip>\site-packages\mpremote\pyboard.py", line 95, in convert
    return OSError(errno.ENOENT, info)
NameError: name 'errno' is not defined

Alternate format also failed

mpr -v copy lv_utils.py lv_utils.py
(raspberry-pi-pico) C:\Users\<snip>\lvgl\helloworld\libs>mpr -v copy lv_utils.py lv_utils.py
mpremote cp :lv_utils.py :lv_utils.py\lv_utils.py
cp :lv_utils.py :lv_utils.py\lv_utils.py
Traceback (most recent call last):
  File "C:\Users\<snip>\site-packages\mpremote\pyboard.py", line 547, in fs_stat
    return os.stat_result(self.eval("uos.stat(%s)" % (("'%s'" % src)), parse=True))
  File "C:\Users\<snip>\site-packages\mpremote\pyboard.py", line 484, in eval
    ret = self.exec_("print(repr({}))".format(expression))
  File "C:\Users\<snip>\site-packages\mpremote\pyboard.py", line 496, in exec_
    raise PyboardError("exception", ret, ret_err)
mpremote.pyboard.PyboardError: ('exception', b'', b'Traceback (most recent call last):\r\n  File "<stdin>", line 1, in <module>\r\nOSError: [Errno 2] ENOENT\r\n')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\<snip>Python310\lib\runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Users\<snip>Python310\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "C:\Users\<snip>\mpremote.exe\__main__.py", line 7, in <module>
  File "C:\Users\<snip>\site-packages\mpremote\main.py", line 502, in main
    handler_func(state, args)
  File "C:\Users\<snip>\site-packages\mpremote\commands.py", line 157, in do_filesystem
    pyboard.filesystem_command(
  File "C:\Users\<snip>\site-packages\mpremote\pyboard.py", line 704, in filesystem_command
    op(src2, dest2, progress_callback=progress_callback)
  File "C:\Users\<snip>\site-packages\mpremote\pyboard.py", line 584, in fs_cp
    src_size = self.fs_stat(src).st_size
  File "C:\Users\<snip>\site-packages\mpremote\pyboard.py", line 549, in fs_stat
    raise e.convert(src)
  File "C:\Users\<snip>\site-packages\mpremote\pyboard.py", line 95, in convert
    return OSError(errno.ENOENT, info)
NameError: name 'errno' is not defined

This variant also failed

mpr -v put lv_utils.py lv_utils.py
(raspberry-pi-pico) C:\Users\<snip>\lvgl\helloworld\libs>mpr -v put lv_utils.py lv_utils.py
mpremote cp lv_utils.py :lv_utils.py\lv_utils.py
cp lv_utils.py :lv_utils.py\lv_utils.py
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 2] ENOENT

this variant worked

mpr -v put lv_utils.py /
(raspberry-pi-pico) C:\Users\<snip>\lvgl\helloworld\libs>mpr -v put lv_utils.py /
mpremote cp lv_utils.py :\lv_utils.py
cp lv_utils.py :\lv_utils.py

Interestingly one of the above commands that failed worked after an initial copy using put

mpr -v copy lv_utils.py /
(raspberry-pi-pico) C:\Users\<snip>\lvgl\helloworld\libs>mpr -v copy lv_utils.py /
mpremote cp :lv_utils.py :lv_utils.py
cp :lv_utils.py :lv_utils.py

This variant of put did not work

mpr -v put *.py /
(raspberry-pi-pico) C:\Users\<snip>\lvgl\helloworld\libs>mpr -v put *.py /
"*.py" does not exist.

This variant of copy did not work

mpr -v copy *.py /
(raspberry-pi-pico) C:\Users\<snip>\lvgl\helloworld\libs>mpr -v copy *.py /
mpremote cp :*.py :*.py
cp :*.py :*.py
Traceback (most recent call last):
  File "C:\Users\<snip>\site-packages\mpremote\pyboard.py", line 547, in fs_stat
    return os.stat_result(self.eval("uos.stat(%s)" % (("'%s'" % src)), parse=True))
  File "C:\Users\<snip>\site-packages\mpremote\pyboard.py", line 484, in eval
    ret = self.exec_("print(repr({}))".format(expression))
  File "C:\Users\<snip>\site-packages\mpremote\pyboard.py", line 496, in exec_
    raise PyboardError("exception", ret, ret_err)
mpremote.pyboard.PyboardError: ('exception', b'', b'Traceback (most recent call last):\r\n  File "<stdin>", line 1, in <module>\r\nOSError: [Errno 2] ENOENT\r\n')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\<snip>Python310\lib\runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Users\<snip>Python310\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "C:\Users\<snip>\mpremote.exe\__main__.py", line 7, in <module>
  File "C:\Users\<snip>\site-packages\mpremote\main.py", line 502, in main
    handler_func(state, args)
  File "C:\Users\<snip>\site-packages\mpremote\commands.py", line 157, in do_filesystem
    pyboard.filesystem_command(
  File "C:\Users\<snip>\site-packages\mpremote\pyboard.py", line 704, in filesystem_command
    op(src2, dest2, progress_callback=progress_callback)
  File "C:\Users\<snip>\site-packages\mpremote\pyboard.py", line 584, in fs_cp
    src_size = self.fs_stat(src).st_size
  File "C:\Users\<snip>\site-packages\mpremote\pyboard.py", line 549, in fs_stat
    raise e.convert(src)
  File "C:\Users\<snip>\site-packages\mpremote\pyboard.py", line 95, in convert
    return OSError(errno.ENOENT, info)
NameError: name 'errno' is not defined

cleared out the EDITOR setting
checked:

mpr -v edit st77xx.py
(raspberry-pi-pico) C:\Users\<snip>\lvgl\helloworld\libs>mpr -v edit st77xx.py
mpremote edit st77xx.py
Traceback (most recent call last):
  File "C:\Users\<snip>Local\Programs\Python\Python310\lib\runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Users\<snip>Local\Programs\Python\Python310\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "C:\Users\<snip>\raspberry-pi-pico\Scripts\mpremote.exe\__main__.py", line 7, in <module>
  File "C:\Users\<snip>\raspberry-pi-pico\lib\site-packages\mpremote\main.py", line 502, in main
    handler_func(state, args)
  File "C:\Users\<snip>\raspberry-pi-pico\lib\site-packages\mpremote\commands.py", line 169, in do_edit
    raise pyboard.PyboardError("edit: $EDITOR not set")
mpremote.pyboard.PyboardError: edit: $EDITOR not set

installed latest

pip install "git+https://github.com/bulletmark/mpr"
(raspberry-pi-pico) C:\Users\<snip>\lvgl\helloworld\libs>pip install "git+https://github.com/bulletmark/mpr"
Collecting git+https://github.com/bulletmark/mpr
  Cloning https://github.com/bulletmark/mpr to c:\users\<snip>local\temp\pip-req-build-s3a0wonq
  Running command git clone --filter=blob:none --quiet https://github.com/bulletmark/mpr 'C:\Users\<snip>Local\Temp\pip-req-build-s3a0wonq'
  Resolved https://github.com/bulletmark/mpr to commit eeff0bac9248b1261fa2d41ea922dd9a8fe48f09
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Installing backend dependencies ... done
  Preparing metadata (pyproject.toml) ... done
Collecting platformdirs (from mpr==1.19.post5+geeff0ba)
  Obtaining dependency information for platformdirs from https://files.pythonhosted.org/packages/14/51/fe5a0d6ea589f0d4a1b97824fb518962ad48b27cd346dcdfa2405187997a/platformdirs-3.10.0-py3-none-any.whl.metadata
  Downloading platformdirs-3.10.0-py3-none-any.whl.metadata (11 kB)
Downloading platformdirs-3.10.0-py3-none-any.whl (17 kB)
Building wheels for collected packages: mpr
  Building wheel for mpr (pyproject.toml) ... done
  Created wheel for mpr: filename=mpr-1.19.post5+geeff0ba-py3-none-any.whl size=14935 sha256=5dd6a16227082bfb8749806d951d4a6b7095008223f6f44bac0bbb6f519514be
  Stored in directory: C:\Users\<snip>Local\Temp\pip-ephem-wheel-cache-3f88g4on\wheels\d0\be\b9\3c43da895bcced95e4ede8baff14fb7374fc0d8a2943c49106
Successfully built mpr
Installing collected packages: platformdirs, mpr
  Attempting uninstall: mpr
    Found existing installation: mpr 1.19.post4+g96bfec0
    Uninstalling mpr-1.19.post4+g96bfec0:
      Successfully uninstalled mpr-1.19.post4+g96bfec0
Successfully installed mpr-1.19.post5+geeff0ba platformdirs-3.10.0

tried the edit again to see if notepad was default with no variable set, that failed

mpr -v edit st77xx.py
(raspberry-pi-pico) C:\Users\<snip>\lvgl\helloworld\libs>mpr -v edit st77xx.py
mpremote edit st77xx.py
Traceback (most recent call last):
  File "C:\Users\<snip>Local\Programs\Python\Python310\lib\runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Users\<snip>Local\Programs\Python\Python310\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "C:\Users\<snip>\raspberry-pi-pico\Scripts\mpremote.exe\__main__.py", line 7, in <module>
  File "C:\Users\<snip>\raspberry-pi-pico\lib\site-packages\mpremote\main.py", line 502, in main
    handler_func(state, args)
  File "C:\Users\<snip>\raspberry-pi-pico\lib\site-packages\mpremote\commands.py", line 169, in do_edit
    raise pyboard.PyboardError("edit: $EDITOR not set")
mpremote.pyboard.PyboardError: edit: $EDITOR not set

Firstly, I will reply to your immediate last comment above. Perhaps you misunderstood my last 2 comments. The mpr edit simply invokes mpremote edit and the editor is then run by mpremote itself, including looking for ~$EDITOR. So nothing I can change in mpr can affect that. You have shown from your tests above that mpremote requires $EDITOR to be set. If it is not set then you get an exception from mpremote about it not being set.

However the mpr config (or mpr cf for short) is to allow editing the mpr config file and it that case mpr does run your editor to edit that file. I have changed the most recent master to look for a different default editor on windows if $EDITOR is not set so I was asking you to please 1) set $EDITOR=notepad++ and run mpr cf to confirm that works, and then 2) unset $EDITOR and confirm that mpr at least runs notepad as a default.

Now regarding your second previous post. Please read the usage of mpr get -h, mpr put -h and mpr copy -h. As the usage says (and there is a description about this in the README) the target argument is always assumed to be a directory. If you want to copy to a file, then you must add the -f/--file option.

If you have a heap of *.py files in a local lib dir but want to copy those files to the / of the remote device then just type mpr p lib/*.py / but from your examples above it seems you have not running this from a Linux like shell (or WSL etc) which allows wildcards? Please note the expanding of *.py is not done by mpr (nor by any Linux command), it is done by the shell.

I added a Troubleshooting section to the README that you should read.

I tried out

1) set $EDITOR=notepad++ and run mpr cf to confirm that works, and then 
2) unset $EDITOR and confirm that mpr at least runs notepad as a default.

I couldn't get notepad++ set and working in windows so in both cases above notepad opened, so at least a good default behaviour.

My current wsl doesn't have python/pip/venv etc setup so will need to try that another time to try out the "mpr p lib/*.py /"

When you did your commands above specifying *.py then why did that not get expanded by your shell? The only way that could happen on Linux is if there are no *.py files.

So in summary here, the only thing I changed in mpr to improve things was the change the default editor, i.e. used when you don't have $EDITOR set, from vi to the following:

OS Tool
Windows notepad
Mac open -e
default vim

Everything else discussed here is due to the OP's environment or a limitation of mpremote.