python-poetry / poetry

Python packaging and dependency management made easy
https://python-poetry.org
MIT License
31k stars 2.25k forks source link

`poetry use pypy3` switches to a Python 3.6 venv if it already exists #2089

Open thedrow opened 4 years ago

thedrow commented 4 years ago

Issue

When I try to switch my environment to PyPy3 using poetry use pypy3 but have previously typed poetry use 3.6 poetry switches to the CPython 3.6 virtualenv instead of creating a new virtualenv for pypy3. You can reproduce this by doing the following:

$ poetry env use 3.6
Using virtualenv: /home/thedrow/.cache/pypoetry/virtualenvs/jumpstarter-H8PwDp0q-py3.6
$ poetry env use pypy3
Using virtualenv: /home/thedrow/.cache/pypoetry/virtualenvs/jumpstarter-H8PwDp0q-py3.6
$ poetry run which pypy3
/home/thedrow/.pyenv/shims/pypy3 # should be the virtualenv's pypy
finswimmer commented 4 years ago

Hello @thedrow,

poetry creates the venv folders based on the project's name, its path and the python version. pypy3 and 3.6 will return both a 3.6 version number. With the current implementation poetry is unable to differ them.

Maybe we should take the name (or the path) of the executable into account when creating the venv?

fin swimmer

thedrow commented 4 years ago

Just include the platform if it's not CPython in the virtualenv's name.

finswimmer commented 4 years ago

Good idea :+1:

But I guess this won't be fixed soon, as this would be a breaking change.

thedrow commented 4 years ago

I'd rather you'd make it a higher priority since it interferes with my workflow when using nox. Currently poetry can't really switch to an existing virtualenv (#1579) so I can't use the virtualenv nox creates for me. Instead I issue a poetry env use command at the beginning of the session. I guess that on the CI environment everything will be fine but I do want developers to be able to run the entire test suite on all supported Python versions in a seamless way.

So you can either make #1579 a higher priority or this issue.

I'd argue it's not much of a breaking change anyway. At most, a new virtualenv will be created for the user which isn't that bad.

thedrow commented 4 years ago

I gave it a quick shot with

diff --git a/poetry/utils/env.py b/poetry/utils/env.py
index dcdec03..f0aa631 100644
--- a/poetry/utils/env.py
+++ b/poetry/utils/env.py
@@ -589,7 +589,13 @@ class EnvManager(object):
             venv = venv_path
         else:
             name = self.generate_env_name(name, str(cwd))
-            name = "{}-py{}".format(name, python_minor.strip())
+            if platform.python_implementation() != "CPytohn":
+                implementation = platform.python_implementation().lower()
+                if implementation == 'pypy':
+                    implementation = '{}{}'.format(implementation, sys.pypy_version_info)
+                name = "{}-py{}-{}".format(name, python_minor.strip(), implementation)
+            else:
+                name = "{}-py{}".format(name, python_minor.strip())
             venv = venv_path / name

         if not venv.exists():

And unfortunately I get an unrelated error:

home/thedrow/.cache/pypoetry/virtualenvs/poetry-ccu6VUlg-py3.7/bin/poetry env use pypy3
Creating virtualenv poetry-ccu6VUlg-py3.6-cpython in /home/thedrow/.cache/pypoetry/virtualenvs
Traceback (most recent call last):
  File "<stdin>", line 14, in <module>
  File "/home/thedrow/.pyenv/versions/pypy3.6-7.3.0/lib-python/3/venv/__init__.py", line 65, in create
    self.setup_python(context)
  File "/home/thedrow/.pyenv/versions/pypy3.6-7.3.0/lib-python/3/venv/__init__.py", line 245, in setup_python
    copier(src, dst)
  File "/home/thedrow/.pyenv/versions/pypy3.6-7.3.0/lib-python/3/venv/__init__.py", line 199, in symlink_or_copy
    shutil.copyfile(src, dst)
  File "/home/thedrow/.pyenv/versions/pypy3.6-7.3.0/lib-python/3/shutil.py", line 120, in copyfile
    with open(src, 'rb') as fsrc:
IsADirectoryError: [Errno 21] Is a directory: '/home/thedrow/.pyenv/versions/pypy3.6-7.3.0/bin/../lib/tcl'

[EnvCommandError]
Command ['/home/thedrow/.cache/pypoetry/virtualenvs/poetry-ccu6VUlg-py3.6-cpython/bin/python', '-'] errored with the following return code 127, and output:
/home/thedrow/.cache/pypoetry/virtualenvs/poetry-ccu6VUlg-py3.6-cpython/bin/python: error while loading shared libraries: libncursesw.so.6: cannot open shared object file: No such file or directory
input was : import sys

if hasattr(sys, "real_prefix"):
    print(sys.real_prefix)
elif hasattr(sys, "base_prefix"):
    print(sys.base_prefix)
else:
    print(sys.prefix)

Maybe I don't know how to correctly setup the dev env for poetry. In addition, it doesn't really pick up the platform.

PetterS commented 4 years ago

Would be nice to have a fix for this issue in 1.1.

PetterS commented 4 years ago

I gave it ≈30 mins in the above PR but was not able to get all the way.

Too bad, since I'd like having pypy support available for experimentation.

PetterS commented 4 years ago

With some more time that PR now seems to work, at least with my installation of pypy.