8000 Error when installing third-party library - mu 1.1.0 alpha - commit f67852f · Issue #822 · mu-editor/mu · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Error when installing third-party library - mu 1.1.0 alpha - commit f67852f #822

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

Closed
abixadamj opened this issue Apr 30, 2019 · 31 comments
Closed
8000

Comments

@abixadamj
Copy link

When I want to install my own library: https://pypi.org/project/PyTechBrain/
I got an error:

Collecting pytechbrain
Downloading https://files.pythonhosted.org/packages/97/a1/4fb5521501dd2d02f5c06f9c0d40e81d53d49a1f8480dad7c7beabbf1bcd/PyTechBrain-0.7.0-py3-none-any.whl
Collecting pymata-aio (from pytechbrain)
Downloading https://files.pythonhosted.org/packages/c2/38/34346ae97407612ca49091cda062f9fa271c60e80f2cf601c37ed925330d/pymata_aio-2.28-py2.py3-none-any.whl (56kB)
Collecting pyserial (from pymata-aio->pytechbrain)
Downloading https://files.pythonhosted.org/packages/0d/e4/2a744dd9e3be04a0c0907414e2a01a7c88bb3915cbe3c8cc06e209f59c30/pyserial-3.4-py2.py3-none-any.whl (193kB)
Collecting websockets (from pymata-aio->pytechbrain)
Downloading https://files.pythonhosted.org/packages/43/71/8bfa882b9c502c36e5c9ef6732969533670d2b039cbf95a82ced8f762b80/websockets-7.0-cp36-cp36m-manylinux1_x86_64.whl (63kB)
Installing collected packages: pyserial, websockets, pymata-aio, pytechbrain
Exception:
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/pip/basecommand.py", line 215, in main
status = self.run(options, args)
File "/usr/lib/python3/dist-packages/pip/commands/install.py", line 360, in run
prefix=options.prefix_path,
File "/usr/lib/python3/dist-packages/pip/req/req_set.py", line 784, in install
**kwargs
File "/usr/lib/python3/dist-packages/pip/req/req_install.py", line 851, in install
self.move_wheel_files(self.source_dir, root=root, prefix=prefix)
File "/usr/lib/python3/dist-packages/pip/req/req_install.py", line 1064, in move_wheel_files
isolated=self.isolated,
File "/usr/lib/python3/dist-packages/pip/wheel.py", line 247, in move_wheel_files
prefix=prefix,
File "/usr/lib/python3/dist-packages/pip/locations.py", line 153, in distutils_scheme
i.finalize_options()
File "/usr/lib/python3.6/distutils/command/install.py", line 274, in finalize_options
raise DistutilsOptionError("can't combine user with prefix, "
distutils.errors.DistutilsOptionError: can't combine user with prefix, exec_prefix/home, or install_(plat)base

FINISHED

image

@abixadamj
Copy link
Author

2019-04-30 20:02:25,310 - mu.logic:1162(sync_package_state) INFO: Synchronize package states...
2019-04-30 20:02:25,310 - mu.logic:1163(sync_package_state) INFO: Old: set()
2019-04-30 20:02:25,310 - mu.logic:1164(sync_package_state) INFO: New: {'pytechbrain'}
2019-04-30 20:02:25,310 - mu.logic:1168(sync_package_state) INFO: To add: {'pytechbrain'}
2019-04-30 20:02:25,310 - mu.logic:1169(sync_package_state) INFO: To remove: set()
2019-04-30 20:02:25,310 - mu.logic:1170(sync_package_state) INFO: Site packages: /home/adasiek/.local/share/mu/site-packages
2019-04-30 20:02:25,312 - mu.interface.dialogs:456(run_pip) INFO: /usr/bin/python3 -m pip install pytechbrain --target /home/adasiek/.local/share/mu/site-packages
2019-04-30 20:02:30,099 - mu.logic:1120(show_admin) INFO: Showing admin with logs from /home/adasiek/.cache/mu/log/mu.log
2019-04-30 20:02:30,100 - mu.logic:157(installed_packages) INFO: Packages found: []

@abixadamj
Copy link
Author

The solution is:

/usr/bin/python3 -m pip install pytechbrain --system --target /home/adasiek/.local/share/mu/site-packages

I found pypa/pip#3826 when searching and it is working.

image

@carlosperate
Copy link
Member

Reopening as this could still be an issue for users in a debian based platform.

@carlosperate carlosperate reopened this May 12, 2019
@carlosperate
Copy link
Member

@abixadamj if you just run /usr/bin/python3 -m pip install pytechbrain --target /home/adasiek/.local/share/mu/site-packages what is the output?

@abixadamj
Copy link
Author
abixadamj commented May 21, 2019

@carlosperate

adasiek@abix-edukacja:$ /usr/bin/python3 -m pip install pytechbrain --target /home/adasiek/.local/share/mu/site-packages
Collecting pytechbrain
Downloading https://files.pythonhosted.org/packages/97/a1/4fb5521501dd2d02f5c06f9c0d40e81d53d49a1f8480dad7c7beabbf1bcd/PyTechBrain-0.7.0-py3-none-any.whl
Collecting pymata-aio (from pytechbrain)
Downloading https://files.pythonhosted.org/packages/72/ad/3490fe48b137e8caab41faa5368ce9d143a781faafa2eaebbf8ea3583989/pymata_aio-2.30-py2.py3-none-any.whl (57kB)
100% |████████████████████████████████| 61kB 50kB/s
Collecting pyserial (from pymata-aio->pytechbrain)
Downloading https://files.pythonhosted.org/packages/0d/e4/2a744dd9e3be04a0c0907414e2a01a7c88bb3915cbe3c8cc06e209f59c30/pyserial-3.4-py2.py3-none-any.whl (193kB)
100% |████████████████████████████████| 194kB 532kB/s
Collecting websockets (from pymata-aio->pytechbrain)
Downloading https://files.pythonhosted.org/packages/43/71/8bfa882b9c502c36e5c9ef6732969533670d2b039cbf95a82ced8f762b80/websockets-7.0-cp36-cp36m-manylinux1_x86_64.whl (63kB)
100% |████████████████████████████████| 71kB 404kB/s
Installing collected packages: pyserial, websockets, pymata-aio, pytechbrain
Exception:
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/pip/basecommand.py", line 215, in main
status = self.run(options, args)
File "/usr/lib/python3/dist-packages/pip/commands/install.py", line 360, in run
prefix=options.prefix_path,
File "/usr/lib/python3/dist-packages/pip/req/req_set.py", line 784, in install
**kwargs
File "/usr/lib/python3/dist-packages/pip/req/req_install.py", line 851, in install
self.move_wheel_files(self.source_dir, root=root, prefix=prefix)
File "/usr/lib/python3/dist-packages/pip/req/req_install.py", line 1064, in move_wheel_files
isolated=self.isolated,
File "/usr/lib/python3/dist-packages/pip/wheel.py", line 247, in move_wheel_files
prefix=prefix,
File "/usr/lib/python3/dist-packages/pip/locations.py", line 153, in distutils_scheme
i.finalize_options()
File "/usr/lib/python3.6/distutils/command/install.py", line 274, in finalize_options
raise DistutilsOptionError("can't combine user with prefix, "
distutils.errors.DistutilsOptionError: can't combine user with prefix, exec_prefix/home, or install_(plat)base
adasiek@abix-edukacja:~$

@carlosperate
Copy link
Member

Can you try installing each of pyserial, websockets, pymata-aio one by one first to see if one of them is causing the problem? And let us know which ones end up with the same output?

/usr/bin/python3 -m pip install pyserial --target /home/adasiek/.local/share/mu/site-packages
/usr/bin/python3 -m pip install websockets --target /home/adasiek/.local/share/mu/site-packages
/usr/bin/python3 -m pip install pymata-aio --target /home/adasiek/.local/share/mu/site-packages

@abixadamj
Copy link
Author
/usr/bin/python3 -m pip install pyserial --target /home/adasiek/.local/share/mu/site-packages
Collecting pyserial
  Using cached https://files.pythonhosted.org/packages/0d/e4/2a744dd9e3be04a0c0907414e2a01a7c88bb3915cbe3c8cc06e209f59c30/pyserial-3.4-py2.py3-none-any.whl
Installing collected packages: pyserial
Exception:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/pip/basecommand.py", line 215, in main
    status = self.run(options, args)
  File "/usr/lib/python3/dist-packages/pip/commands/install.py", line 360, in run
    prefix=options.prefix_path,
  File "/usr/lib/python3/dist-packages/pip/req/req_set.py", line 784, in install
    **kwargs
  File "/usr/lib/python3/dist-packages/pip/req/req_install.py", line 851, in install
    self.move_wheel_files(self.source_dir, root=root, prefix=prefix)
  File "/usr/lib/python3/dist-packages/pip/req/req_install.py", line 1064, in move_wheel_files
    isolated=self.isolated,
  File "/usr/lib/python3/dist-packages/pip/wheel.py", line 247, in move_wheel_files
    prefix=prefix,
  File "/usr/lib/python3/dist-packages/pip/locations.py", line 153, in distutils_scheme
    i.finalize_options()
  File "/usr/lib/python3.6/distutils/command/install.py", line 274, in finalize_options
    raise DistutilsOptionError("can't combine user with prefix, "
distutils.errors.DistutilsOptionError: can't combine user with prefix, exec_prefix/home, or install_(plat)base


@abixadamj
Copy link
Author

adasiek@abix-edukacja:~$ /usr/bin/python3 -m pip install websockets --target /home/adasiek/.local/share/mu/site-packages
Collecting websockets
  Using cached https://files.pythonhosted.org/packages/43/71/8bfa882b9c502c36e5c9ef6732969533670d2b039cbf95a82ced8f762b80/websockets-7.0-cp36-cp36m-manylinux1_x86_64.whl
Installing collected packages: websockets
Exception:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/pip/basecommand.py", line 215, in main
    status = self.run(options, args)
  File "/usr/lib/python3/dist-packages/pip/commands/install.py", line 360, in run
    prefix=options.prefix_path,
  File "/usr/lib/python3/dist-packages/pip/req/req_set.py", line 784, in install
    **kwargs
  File "/usr/lib/python3/dist-packages/pip/req/req_install.py", line 851, in install
    self.move_wheel_files(self.source_dir, root=root, prefix=prefix)
  File "/usr/lib/python3/dist-packages/pip/req/req_install.py", line 1064, in move_wheel_files
    isolated=self.isolated,
  File "/usr/lib/python3/dist-packages/pip/wheel.py", line 247, in move_wheel_files
    prefix=prefix,
  File "/usr/lib/python3/dist-packages/pip/locations.py", line 153, in distutils_scheme
    i.finalize_options()
  File "/usr/lib/python3.6/distutils/command/install.py", line 274, in finalize_options
    raise DistutilsOptionError("can't combine user with prefix, "
distutils.errors.DistutilsOptionError: can't combine user with prefix, exec_prefix/home, or install_(plat)base

@abixadamj
Copy link
Author

adasiek@abix-edukacja:~$ /usr/bin/python3 -m pip install pymata-aio --target /home/adasiek/.local/share/mu/site-packages
Collecting pymata-aio
  Using cached https://files.pythonhosted.org/packages/72/ad/3490fe48b137e8caab41faa5368ce9d143a781faafa2eaebbf8ea3583989/pymata_aio-2.30-py2.py3-none-any.whl
Collecting websockets (from pymata-aio)
  Using cached https://files.pythonhosted.org/packages/43/71/8bfa882b9c502c36e5c9ef6732969533670d2b039cbf95a82ced8f762b80/websockets-7.0-cp36-cp36m-manylinux1_x86_64.whl
Collecting pyserial (from pymata-aio)
  Using cached https://files.pythonhosted.org/packages/0d/e4/2a744dd9e3be04a0c0907414e2a01a7c88bb3915cbe3c8cc06e209f59c30/pyserial-3.4-py2.py3-none-any.whl
Installing collected packages: websockets, pyserial, pymata-aio
Exception:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/pip/basecommand.py", line 215, in main
    status = self.run(options, args)
  File "/usr/lib/python3/dist-packages/pip/commands/install.py", line 360, in run
    prefix=options.prefix_path,
  File "/usr/lib/python3/dist-packages/pip/req/req_set.py", line 784, in install
    **kwargs
  File "/usr/lib/python3/dist-packages/pip/req/req_install.py", line 851, in install
    self.move_wheel_files(self.source_dir, root=root, prefix=prefix)
  File "/usr/lib/python3/dist-packages/pip/req/req_install.py", line 1064, in move_wheel_files
    isolated=self.isolated,
  File "/usr/lib/python3/dist-packages/pip/wheel.py", line 247, in move_wheel_files
    prefix=prefix,
  File "/usr/lib/python3/dist-packages/pip/locations.py", line 153, in distutils_scheme
    i.finalize_options()
  File "/usr/lib/python3.6/distutils/command/install.py", line 274, in finalize_options
    raise DistutilsOptionError("can't combine user with prefix, "
distutils.errors.DistutilsOptionError: can't combine user with prefix, exec_prefix/home, or install_(plat)base

@abixadamj
Copy link
Author

Whatever else...


adasiek@abix-edukacja:~$ /usr/bin/python3 -m pip install ar --target /home/adasiek/.local/share/mu/site-packages
Collecting ar
  Downloading https://files.pythonhosted.org/packages/b2/a2/4d792d4436ccab471f1add041e8add8ed1872f33405b72615cb3b29e781b/ar-1.5.0.zip
Building wheels for collected packages: ar
  Running setup.py bdist_wheel for ar ... done
  Stored in directory: /home/adasiek/.cache/pip/wheels/c2/8c/78/3e5782c6e297139dd8acc059d121163156fe78b8a0c95ffcc5
Successfully built ar
Installing collected packages: ar
Exception:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/pip/basecommand.py", line 215, in main
    status = self.run(options, args)
  File "/usr/lib/python3/dist-packages/pip/commands/install.py", line 360, in run
    prefix=options.prefix_path,
  File "/usr/lib/python3/dist-packages/pip/req/req_set.py", line 784, in install
    **kwargs
  File "/usr/lib/python3/dist-packages/pip/req/req_install.py", line 851, in install
    self.move_wheel_files(self.source_dir, root=root, prefix=prefix)
  File "/usr/lib/python3/dist-packages/pip/req/req_install.py", line 1064, in move_wheel_files
    isolated=self.isolated,
  File "/usr/lib/python3/dist-packages/pip/wheel.py", line 247, in move_wheel_files
    prefix=prefix,
  File "/usr/lib/python3/dist-packages/pip/locations.py", line 153, in distutils_scheme
    i.finalize_options()
  File "/usr/share/python-wheels/setuptools-39.0.1-py2.py3-none-any.whl/setuptools/command/install.py", line 38, in finalize_options
    orig.install.finalize_options(self)
  File "/usr/lib/python3.6/distutils/command/install.py", line 274, in finalize_options
    raise DistutilsOptionError("can't combine user with prefix, "
distutils.errors.DistutilsOptionError: can't combine user with prefix, exec_prefix/home, or install_(plat)base

@carlosperate
Copy link
Member

Thank you @abixadamj, I was hoping one of the packages was doing something weird, but it doesn't look that way, problem persist with any pip install with the target flag.

@carlosperate
Copy link
Member

Can you check the environmental variables on your system? Specifically anything that starts with PIP_? Maybe there is something there to force the user option.
https://pip.pypa.io/en/stable/user_guide/#environment-variables

For installing packages Mu will fork the same version of Python that has launched Mu, and if it is using the system Python it will use the system pip as well. If the problem is from the debian patch to pip mentioned in pypa/pip#3826, then perhaps we can try using a different pip version.
Are you running Mu in a virtual environment? If you are, I would also suggest to update pip inside that, I am hoping an updated version of pip inside your virtualenv will not have that "feature" debian injected (unless the change is also applied via environment variable).

@carlosperate
Copy link
Member

Based on this it sounds like this is maybe an issue when running Mu on the system Python and not in a virtual environment: https://sources.debian.org/patches/python-pip/18.1-5/set_user_default.patch/

@ntoll
Copy link
Member
ntoll commented May 22, 2019

@carlosperate this appears entirely to do with Debian patching Python in a way that makes using pip inconsistent with any other OS or pip's own documentation. This was, I believe, discussed a few weeks ago on another ticket and/or on the chat forum.

My hunch is this is a problem of Debian's making. There is no reliable way to detect if Mu is running on a Debian based distribution, so building in a "special case" for Debian appears to be a can of worms (I'd rather not open).

I'm at a loss about how to fix this -- there's not a lot Mu can do, and upstream Debian don't appear to want to change their patching of pip. The best we can suggest is that the user run Mu in a virtualenv (as I do on Ubuntu).

😢 🐮 💔

@carlosperate
Copy link
Member

Yes, we were also discussing this in #836 (comment), not sure if there was also something in the chat as well, but I moved the conversation here as it makes more sense to have it where people will find it if they search for the error message in the repo.

My hunch is this is a problem of Debian's making.

It looks like it, based on pypa/pip#3826 (comment) and https://sources.debian.org/patches/python-pip/18.1-5/set_user_default.patch/.

There is no reliable way to detect if Mu is running on a Debian based distribution, so building in a "special case" for Debian appears to be a can of worms (I'd rather not open).

Even if there was an easy way to detect if it was debian, it would prefer to find a way around applying platform-specific special cases.

However, if the patch was implemented in a way that we could circumvent, like a PIP_* environment variable forcing the user option, I think it would be okay to "disable it" within Mu, as that is a safe option in all our use cases/platforms, since we are using the target flag. But looking at the patch that is not the case :(

My concern here is that this is a patch to upstream Debian, and probably present in the Raspbian version as well. This means that when the new Mu .deb installers fo Raspbian and Debian Buster are released, they will use the default python3-pip version with the patch and users will encounter the same problem when installing via apt-get install mu-editor.

The best we can suggest is that the user run Mu in a virtualenv (as I do on Ubuntu).

That would have been my recommendation as well if it didn't affect "deb-installed" versions of Mu.

There are other options we could consider, like https://github.com/spotify/dh-virtualenv, or to find a way to package or use a different version of pip. Or maybe there is a better way, which is why I think this is worth exploring.

@ntoll
Copy link
Member
ntoll commented May 22, 2019

@carlosperate I think this photo, taken at the recent PyCon, pretty much sums up Python packaging... ;-)

packaging

@abixadamj
Copy link
Author

OK, today I have 5 minuts free to come back to this issue.

  1. I realy cannot use mu in virtualenv. Why? Because I create https://free-desktop.pl - this is remix of linux Mint . And based on it, i build system for classromms with ltsp-pnp https://pracowniainformatyczna.pl And threfore I need to have mu-editor installed from deb package, not in virtualenv in each user's directiory, because when I have 400 users, 400 virtualenv seems to be waste of disk space, also with ltsp I need to minimize LAN traffic (everything what is in user's dir makes LAN traffic...)
  2. I tried to find out some PIP_ environment, but with no luck. Maybe someone will have solution.
  3. At the end - of course I can make a fork and create my own version of mu (just for me), but I dont want to do it - the last line of defence for me;-)

So, I want to propose solution :

Create environment variable, maybe MU_PIP_DEBIAN, and check in code, if there will be such env (export MU_PIP_DEBIAN=YES), and then (only then) add --system to pip code in MU-editor

This will not breake other systems, and If there will be situation like in me, there will be a way to solve it. What do you think @ntoll ? If you will approve it, I will make PR...

@ntoll
Copy link
Member
ntoll commented Jun 1, 2019

@abixadamj 👍 on finding something that will work. I'd rather things worked the other way around from a logical point of view and were not Debian specific (I'll explain below).

In terms of functionality:

  • The default behaviour remains the same.

  • If there is a MU_PIP_SYSTEM envar that evaluates to True then, and only then, execute pip with the --system command (with the caveat that Mu assumes the user will have the required privileges to do this, as they do on Debian). Perhaps this flag could also be set in the admin dialog?

  • Why make this non-Debian specific? Because I imagine some folks on other OS's may want Mu to be able to interact with their "system" Python (whatever that means).

  • Also, it feels more "generic" and less "Debian is a very special case" to have the flag work in this way.

I'm partially playing devil's advocate here, so it's an opportunity to encourage some discussion before someone (@abixadamj?) creates a PR with the agreed upon solution. So, thoughts on this would be most welcome..! Let's see what sort of consensus we can arrive at so we can both fix @abixadamj's problem and perhaps add a bit of flexibility to Mu (after all, some folk have mentioned they'd like Mu to use system Python's packages / path too).

Thoughts..? :-)

@carlosperate
Copy link
Member

Why make this non-Debian specific? Because I imagine some folks on other OS's may want Mu to be able to interact with their "system" Python (whatever that means).

Unfortunately the --system flag will throw an error in any non-debian operating systems, as pip will print that the flag is not recognised:

$ pip install requests --system
Usage:   
  pip install [options] <requirement specifier> [package-index-options] ...
  pip install [options] -r <requirements file> [package-index-options] ...
  pip install [options] [-e] <vcs project url> ...
  pip install [options] [-e] <local project path> ...
  pip install [options] <archive url/path> ...

no such option: --system

Perhaps there is a way to query pip to see if the flag is available and then added if it is? And we could do that independently of the operating system.
In this case the system flag is added by the Debian patch to be able to counteract the user flag that it embeds in all pip invocations outside venvs and without sudo.

@tmontes
Copy link
Member
tmontes commented Jun 1, 2019

Chiming in with 2c of a thought that keeps coming up on my mind whenever a "can't install 3rd party package with Mu" new issue is raised and solutions are sought (and I believe there have been a few, recently).

Here are a few facts I suppose are correct, concerning Python mode:

  • Mu runs and debugs code under the same python executable and environment as itself.
    Thus, import PyQt5 in the REPL, for example, works (should it? read on...)
  • Mu runs pip in a documented, but seldom used, way to install 3rd party packages in a specific target directory of its own. Specifically, it runs pip with the same python executable as itself with the additional --target <mu's-package-directory> argument.
  • I haven't looked at the code but I suppose that when running/debugging, the above mentioned <mu's-package-directory> is appended/prepended (?) to sys.path.
  • 3rd party package removal is done with shutil.rmtree, however: apparently, the --target option is not available to pip uninstall. This is not only unfortunate, but also leads to brittle and unnecessarily complex code to handle it (see PackageDialog.remove_package in mu/interface/dialogs.py).

Here's a thought / vision I believe leads to a more robust overall solution that, AFAICT, will not need platform specific "thingies", whichever they are:

  • Mu could create a virtual environment to run / debug programs in Python mode, and hold any 3rd party packages.
  • Such venv would be automatically created and 100% transparent to users. They would never know.
  • It could probably be located within the same directory where the above mentioned <mu's-package-directory> is. But it would probably be called venv or some such and hold a fully isolated Python virtual environment.
  • Mu's Python executable would only be used to create such venv.
  • Other operations like run and debug would use that venv's Python executable.
  • Installing / removing packages would be a widely used and tested python -m pip install / uninstall using that venv's Python executable.

Benefits:

  • Installing and removing 3rd party packages should become much more robust. Given that the wide majority of packages (and systems, including Debian) install fine with a "plain" pip install within a virtual environment.
  • No need to play around with sys.path to run/debug. Just use the venv's Python executable ensuring the CWD is ~/mu_code.

Trade-off:

  • A venv must be created taking a little bit more of disk space and a little while to be created.

Challenges:

  • Not sure about the need to "refresh" such venv as in, say, created with Mu 1.1.0 based off Python 3.7. What happens when Mu 1.3.0 comes out, based off Python 3.9? Users will want to benefit from the new 3.9 features unavailable in the "old" venv which was created with 3.7 and, thus, is 3.7. :)
  • Maybe others I'm not seeing yet.

IMPORTANT NOTE: I don't mean to hijack this issue. My intent is the best. But I do believe that once we start going the "if this then do that, else if env var is set but the sun is setting then dance while holding three sharp knives on fire" we'll never see an end to it. I honestly believe that what I propose above is for the better of all users and is the right answer to most (all?) "can't install 3rd party package" issues. I see no technical reason why it shouldn't work, even when Debian hacks pip to behave somehow differently. I very briefly shared these thoughts with @tjguk the other day too, but we did not get to the point of discussing them.

@tmontes
Copy link
Member
tmontes commented Jun 1, 2019

PS: As an extra, after re-reading @ntoll's comment above, if people want to use the system Python's packages, Mu could be told to run / debug using not its venv Python executable, but any Python executable that advanced beginners would set: no other changes would be needed at all. :)

@ntoll
Copy link
Member
ntoll commented Jun 2, 2019

Morning @tmontes. That's a really interesting proposal, which I like a lot. Some thoughts below:

  • I don't think disk space is an issue here.
  • +1 on system Python support.
  • When updating to a new version of Python (in later releases of Mu) perhaps we could do a "once only" pip freeze to gather the installed packages, create a new venv then install the packages before deleting the old venv? (This also makes upgrade a one-way task).
  • Packaging PyGame, PGZero or (with web mode) Flask, could be removed from the installer and done as a "upon start" check to pip install them in the venv instead.

This feels a promising direction to take and I agree that the benefits are strong. I'm trying to remember why we didn't go with the venv route before. Perhaps (most likely) it's because we (I) didn't think of it. ;-)

@tmontes
Copy link
Member
tmontes commented Jun 2, 2019

Glad that you feel the approach is promising. There is one thing that I suppose will be more complex but, from skimming the docs/code, seems doable: the Jupyter REPL.

We should not require Jupyter and friends to be installed on the venv: thus, Juptyer/QtConsole will need to run from within Mu's own Python environment, connected to a Kernel running the venv's Python... This should be fun and good learning opportunity. :)

@abixadamj
Copy link
Author
abixadamj commented Jun 2, 2019

My friends,
let me explain deeply my problem. I do classroms based on Linux Mint server and diskless workstations, startnig the system from server over PXE and NBD. It is LTSP-PNP Fat Client architecture. The whole operating system and applications are sent to station over the PXE protocol, then switching to NBD. And ALL user's directory is mapped via SSHFS over the net to workstation. All users files are located on HDD on server. So for average school in Poland (8 years x 5 class per year x 25 students per class) it is about 1 000 users accounts on server. So, if for every one user I need to create 0,5 GB venv it tooks about 500 GB of disk space. I know, it is still not big number (standard disk for users is 2 TB).
But - and here is my real problem): Now mu is read one time from NBD device over the net and unpacked into RAM memory of diskless workstation. No more traffic over the net. And with venv there will be (i think, of course I always can be wrong) more traffic over the net and more i/o operations on hdd on server. And I have bad experience in such situations, for example Scratch 2.0 offline, which read a lot of data from user directory. Starting such application consumes about 3 minutes (180 seconds with watch on hand)... And this is why I am against venv.

But - if there will be no different way, I will must live with it. That is all.

@tmontes
Copy link
Member
tmontes commented Jun 2, 2019

@abixadamj, thanks for sharing your concerns regarding possible constraints deriving from the infrastructure you work with: that's helpful.

Importantly, your experience of 3 minutes (!!!) to launch Scratch feels like a very negative factor in a classroom environment. For clarification sake, how long does a Mu launch currently take after a clean boot? What about after being cached (launch/quit/launch)? And how long does it take to start running a program? Have you tried importing large packages like numpy, or is that completely out of scope?

Regarding virtual environments:

  • Freshly created Python 3.6 virtual environments take ~6 MB on Ubuntu 18.04, ~12 MB on macOS 10.12, ~24 MB on Windows 10.
  • Adding PyTechBrain, which triggered this issue, makes them grow by ~2 MB.
  • Adding ipykernel, for example, which may be needed for a nicer REPL, adds ~30 MB.
  • They will get bigger as more packages are installed, obviously.

Of course each person's use case is potentially very different, but I wonder if you are being over-conservative due to a bad experience you might have had before. Even though 0.5 GB of venv is not unheard of -- in particular when data analysis tools are brought in -- I'd say that such size is probably an over estimation of what the real size on disk will probably be (you will know better, of course!) :)

With this in mind, my note in this issue is the culmination of observing many people, like you, having issues installing 3rd party packages -- a hugely wanted capability by many -- and things not working seamlessly. Using a venv will address most, if not all, of the issues that have been recently reported, while at the same time having the potential to simplify Mu's code by itself -- on the contrary, the more ifs we put into the code, the more difficult will it be to sustainably manage it, going forward.

Please do not take this as personal confrontation: it is not. :-) It's more about an idea which I believe to be sounder, simpler, and that has the potential to address many user's issues, including yours. With such a solution, the potential for performance impact in your infrastructure could come out as something like:

  • Launching Mu: equal or faster.
  • Creating the venv: slower, but happens only once (could be done in advance?...)
  • Running programs: initial delay on the 1st run, while, say, ~10 MB are loaded across the network (depends on which 3rd party packages are installed and imported).

Benefits:

  • Install PyTechBrain and it works!
  • Mu will be less complex and has the potential to live longer.

:-)

@tjguk
Copy link
Collaborator
tjguk commented Jun 3, 2019

Just to chime in: I had the same sort of idea when we were brainstorming previously for the 3rd-party packages solution. I don't remember whether I voiced it publicly, but I think @ntoll came to his --user/--target solution before I developed the notion of a private venv further. When @tmontes raised it the other in passing I was glad to hear an independent version of the same notion and broadly support it.

While the devil is obviously in the details. I think that the private venv does provide the neatest solution to the issue of safely and consistently pip-installing/uninstalling 3rd-party packages because it basically does the most tested thing in this sphere: combining pip & a venv. In addition, the notion of a pip-freeze to essentially copy the venv when upgrading obviously buys into the same idea: using the most commonly-invoked mechanism for generating one venv as a copy of another.

Nor do I think the use of a venv, once it's established, should cause too much code churn elsewhere. eg the core process runner is at mu\mu\interface\panes.py:start_process and, potentially, maybe, just needs to switch from sys.executable to path-to-venv-executable.

I acknowledge the problems which @abixadamj and others might face who are using any kind of unusual storage regime. Assuming that the cost of implementing a PoC isn't too high, we could try to put something in place and ask @abixadamj to try it out to see what the effect is on the runtime etc.

In short: I'm in favour, altho 6D40 ugh I'm not proposing to offer a PR right here right now, but I'd be happy to assist in review or implementation in good time.

@abixadamj
Copy link
Author

My friends,
I know everything and understand your position - I will test it deeply next week. @ntoll - how much time do I have for it? Other words - when do you plan to freeze current release?

@carlosperate
Copy link
Member

@abixadamj now that everything is installed inside a new venv created with the virtualenv package, and that updates pip to the latest compatible version from PyPI, then it's likely this issue is now resolved since it doesn't use the system pip anymore.

Would you be able to test again with the latest release? https://github.com/mu-editor/mu/releases/

@abixadamj
Copy link
Author

@carlosperate of course, after easter...

@abixadamj
Copy link
Author

@carlosperate
It looks works like a charm ;-)

Collecting pytechbrain
Downloading PyTechBrain-0.7.2-py3-none-any.whl (6.7 kB)
Collecting pymata-aio==2.33
Downloading pymata_aio-2.33-py2.py3-none-any.whl (57 kB)
Requirement already satisfied: pyserial in /home/adasiek/.local/share/mu/mu_venv-38-20210325-220026/lib/python3.8/site-packages (from pymata-aio==2.33->pytechbrain) (3.5)
Collecting websockets
Downloading websockets-8.1-cp38-cp38-manylinux2010_x86_64.whl (78 kB)
Installing collected packages: websockets, pymata-aio, pytechbrain
Successfully installed pymata-aio-2.33 pytechbrain-0.7.2 websockets-8.1

FINISHED

Zrzut ekranu z 2021-04-07 15-58-40

@carlosperate
Copy link
Member

Awesome, thanks for all the testing @abixadamj!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants
0