Skip to content

Add option to use pyenv instead of virtualenv? #4

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
lanshark opened this issue Mar 3, 2016 · 11 comments
Closed

Add option to use pyenv instead of virtualenv? #4

lanshark opened this issue Mar 3, 2016 · 11 comments

Comments

@lanshark
Copy link

lanshark commented Mar 3, 2016

pyenv is an alternative way to create virtualenvs, by installing multiple copies of python (different versions). It uses the pyenv virtualenv syntax instead of virtualenv , and activates with pyenv activate . Should be possible as a config option.

@theacodes
Copy link
Collaborator

Hmm. Can you illustrate a use case? From what I understand pyenv can help provide interpreters for virtualenv, but it does not itself handle management of virtualenvs.

@lanshark
Copy link
Author

lanshark commented Mar 3, 2016

While pyenv does provide interpreters, it also has a plugin for creating/managing virtualenvs built from those interpreters.

https://github.com/yyuu/pyenv-virtualenv

I use that to create the virtualenvs. Internally, pyenv uses either the venv command (if python 3) or the virtualenv command (if not).

I have forked the project, and will try to work up a PR for you.

@theacodes
Copy link
Collaborator

Cool, PRs are welcome. 👍

@stsewd
Copy link
Collaborator

stsewd commented Aug 24, 2018

Why doesn't the normal workflow works for you? I'm using nox with pyenv like thispyenv virtualenv 3.6 nox and pyenv activate nox, actually I use a .python-version file to avoid having to activate pyenv manually.

@tswast
Copy link
Contributor

tswast commented Aug 27, 2018

If you are having trouble getting nox to pick the right Python when using pyenv, this guide may help: https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/MAC_SETUP.md

@theacodes
Copy link
Collaborator

I'm thinking of closing this, unless there's something we can actually do here.

Somethings that come to mind:

  1. Add explicit documentation on using pyenv to provide interpreters
  2. Figure out what deeper integration we can do with pyenv.

@moshez
Copy link
Contributor

moshez commented Sep 15, 2018

I would definitely appreciate [1]. I've been fighting with getting nox to see my pyenv-ish 3.7.0 for a couple of hours.

@FollowTheProcess
Copy link
Collaborator

Going through some of the older issues to see if we can close any off. cc @cjolowicz

I'm not sure this one is still relevant? Perhaps we've changed stuff in the time since this was raised but I was able to install python 3.8.12 using pyenv and run a nox session utilising this python:

(I have python 3.10.1 (pyenv), python 3.9.9 (homebrew) and this python 3.8.12 (pyenv) on my machine)

# noxfile.py

import nox


@nox.session(python="3.10")
def py310(session: nox.Session) -> None:
    """
    Do stuff with 3.10
    """
    session.install("pytest")
    session.log(f"My python is {session.python}")


@nox.session(python="3.9")
def py39(session: nox.Session) -> None:
    """
    Do stuff with 3.9
    """
    session.install("pytest")
    session.log(f"My python is {session.python}")


@nox.session(python="3.8")
def py38(session: nox.Session) -> None:
    """
    Do stuff with 3.8
    """
    session.install("pytest")
    session.log(f"My python is {session.python}")

Which results in:

image

And catting the .pyvenv.cfg for .nox/py38 reveals that the correct environment was used:

image

The trick with pyenv is that in order for Nox to have access, you must declare the python version to be the "global" one pyenv global 3.8.12 for example.

Or you can include a .python-version in the project to use it for this project only.

I tested this approach too:

# .python-version
3.8.12

image

image

In between each of these runs I rm -rf'd the whole .nox directory so it was the same condition each time (fresh nox run)

@cjolowicz
Copy link
Collaborator

Closing this as suggested by @FollowTheProcess . Happy to reopen if people want to pursue this further.

As far as I understand, there were two separate points raised in this issue:

  1. Supporting pyenv-virtualenv as an additional venv backend.
  2. Users experiencing problems where Nox does not use an interpreter installed with pyenv.

I'm not sure about the value of 1, given that pyenv-virtualenv is a frontend to venv and virtualenv which we already support?

For users affected by 2 with a recent pyenv and virtualenv, I'd suggest to:

  1. Double-check that pyenv is configured correctly and the interpreters are indeed activated (see the resource linked above)
  2. Try removing virtualenv's cache directory if the issue persists (see Cache invalidation broken with pyenv? pypa/virtualenv#2130)

@neozenith
Copy link

neozenith commented Mar 27, 2022

For anyone coming to this issue later (likely me), I am totally fine with nox using virtualenv to manage the virtual environments and to discover what versions of python are on my system. The virtualenv <-> pyenv ecosystem is lacking.

However,

  • The pyenv globals ... trick above wasn't working.
  • Neither was the pyenv-virtualenv (because this is not what it is for)
  • and the virtualenv-pyenv plugin wasn't working either, which is supposed to enhance virtualenv to discover pyenv installed versions.

Turns out ~/.pyenv/shims/ isn't enough to have on your PATH. Despite it showing results when I run which -a python3.7 etc for each target version.

It seems virtualenv wants the ~/.pyenv/versions/X.Y.Z/bin path on your PATH.

So I created the below basic script to discover what versions are available, check if that path is not already on PATH and generate a shell command you can run yourself to update your PATH for the sake of that shell session by appending them to the end of your PATH.

import os
from os import listdir
from os.path import isfile, join
from pathlib import Path

PATH = os.environ["PATH"]
# Maybe change this to get the result from subprocess.run(["pyenv", "root"])
target = Path(Path.home() / ".pyenv/versions/")

dirs = [
    d
    for d in [
        str(target / e / "bin")
        for e in os.listdir(target)
        if not isfile(join(target, e))
    ]
    if d not in PATH
]

if dirs:
    print(f"PATH=$PATH:{':'.join(dirs)}")

So for me it is these extra steps to get a nox testing session working with my installed pyenv versions:

eval $(python3 pyenv_discover_paths.py) 
nox

No need to reopen this ticket, just wanted to add this here since this is where google took me and I wanted to leave my solution on the bread crumb trail for the next person (most likely me again).

@everdark
Copy link

everdark commented Nov 28, 2022

Just run into this issue today and I found that pyenv global works for me.
In my case, I have a system python 3.9.6 (system python) on my macOS, together with 3.9.15, 3.10.8, 3.8.15, all 3 installed by pyenv. nox can only pickup my system python. For nox (installed in my system python) to find my other python versions, I simply do:

pyenv global system 3.9.15 3.10.8 3.8.15

and it now works as expected.
for py39 nox will use my system, but if I change the order of the pyenv global it will also use the one from pyenv.

Hope this helps for whoever run into this in the future. :)

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

No branches or pull requests

9 participants