Skip to content
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

Running Tox inside a pyenv virutalenv #21

Closed
andymccurdy opened this issue May 29, 2014 · 9 comments
Closed

Running Tox inside a pyenv virutalenv #21

andymccurdy opened this issue May 29, 2014 · 9 comments

Comments

@andymccurdy
Copy link

It seems like you can't use Tox to test against multiple Python versions inside of a virtualenv created with pyenv-virtualenv. From what I can tell, this is because activating a pyenv-virtualenv sets the PYENV_VERSION to the named virtualenv, which makes all the other pythonX.Y shims invalid.

A complete example demonstrating this problem:

$> pyenv install 2.7.6
$> pyenv install 3.4.1
$> pyenv global 2.7.6 3.4.1
$> pyenv versions
  system
* 2.7.6 (set by /Users/andy/.pyenv/version)
* 3.4.1 (set by /Users/andy/.pyenv/version)

# NOTE, installing tox "globally" here and running it
# against 2.7.6 and 3.4.1 works fine because both
#2.7.6 and 3.4.1 are "activated" in the non-virtualenv
# environment

$> pyenv virtualenv 2.7.6 redis-py
$> pyenv activate redis-py
$> pyenv versions
  system
  2.7.6
  3.4.1
* redis-py (set by PYENV_VERSION environment variable)

# Now Tox (or any other program trying to call python3.4) will fail

$> python3.4
pyenv: python3.4: command not found

The `python3.4' command exists in these Python versions:
  3.4.1

I've gotten around this problem by using pyenv-virtualenvwrapper, which doesn't seem to use the pyenv versions system to create the virtualenv and doesn't set the PYENV_VERSION environment variable.

@yyuu
Copy link
Collaborator

yyuu commented May 30, 2014

In this case, you don't have to activate the virtualenv of redis-py.

Following example doesn't help?

## Setup CPython and virtualenv.
$ pyenv install 2.7.6
$ pyenv install 3.4.1
$ pyenv virtualenv 2.7.6 redis-py27
$ pyenv virtualenv 3.4.1 redis-py34
$ pyenv global redis-py27 redis-py34

## Setup tox.
$ pip install tox
$ pyenv rehash
$ cat <<EOF >setup.py
from setuptools import setup
setup(name="x")
EOF
$ cat <<EOF >tox.ini
[tox]
envlist = py27, py34
[testenv:py27]
basepython = python2.7
[testenv:py34]
basepython = python3.4
[testenv]
commands = python --version
EOF

## Then, run tox.
$ tox
GLOB sdist-make: /home/yamashita/x/setup.py
py27 inst-nodeps: /home/yamashita/x/.tox/dist/x-0.0.0.zip
py27 runtests: PYTHONHASHSEED='2368391035'
py27 runtests: commands[0] | python --version
Python 2.7.6
py34 inst-nodeps: /home/yamashita/x/.tox/dist/x-0.0.0.zip
py34 runtests: PYTHONHASHSEED='2368391035'
py34 runtests: commands[0] | python --version
Python 3.4.1
__________________________________________________________________________________ summary ___________________________________________________________________________________
  py27: commands succeeded
  py34: commands succeeded
  congratulations :)

@andymccurdy
Copy link
Author

Perhaps I'm not understanding the "pyenv way". Your example seems to break whenever there's other dependencies. I did what you suggest above and changed a few things:

# AFTER pyenv global redis-py27 redis-py34
pip install hiredis    # a dependency used by my project


# tox.ini:
[tox]
envlist = py27, py34

[testenv:py27]
basepython = python2.7

[testenv:py34]
basepython = python3.4

[testenv]
commands = python foo.py 

# foo.py
from __future__ import print_function

try:
    import hiredis
except ImportError:
    print("import error")


# RUNNING TOX (notice the import errors being printed out)

$> tox
GLOB sdist-make: /Users/andy/tmp/setup.py
py27 inst-nodeps: /Users/andy/tmp/.tox/dist/z-0.0.0.zip
py27 runtests: PYTHONHASHSEED='1564301523'
py27 runtests: commands[0] | python foo.py
import error
py34 inst-nodeps: /Users/andy/tmp/.tox/dist/z-0.0.0.zip
py34 runtests: PYTHONHASHSEED='1564301523'
py34 runtests: commands[0] | python foo.py
import error
___________________________________ summary ____________________________________
  py27: commands succeeded
  py34: commands succeeded
  congratulations :)

Even weirder, I can successfully import hiredis in the REPL from python and python2.7, but not python3.4. Which makes me wonder why the tox py27 environment test failed.

@andymccurdy
Copy link
Author

Sorry, I guess I should have included hiredis as one of the deps in tox.ini. That would fix this issue as tox maintains it's own idea of virtualenvs.

@andymccurdy
Copy link
Author

Even so, it seems pretty painful to me to have to switch the pyenv global when I want to work on a different project.

e.g.,

# work on redis-py...
pyenv global redis-py27 redis-py34
# work on foobar...
pyenv global foobar27 foobar34

I'd rather just activate a single redis-py or foobar virtualenv. That worked with non-pyenv virtualenv and it works with pyenv-virtualenvwrapper.

@yyuu
Copy link
Collaborator

yyuu commented May 30, 2014

There is pyenv local it allows you to set project Python version per directory basis. See also /~https://github.com/yyuu/pyenv/blob/master/COMMANDS.md#pyenv-local

@andymccurdy
Copy link
Author

This works. The biggest disconnect for me was I was thinking that pyenv virtualenv worked just like the Python virtualenv module. I made this assumption because they share the same name.

More documentation around this might be a good idea in the future. Specifically, something that says that when you activate a pyenv virtualenv that all the shims for other Python versions aren't available.

@yyuu
Copy link
Collaborator

yyuu commented Jul 19, 2015

Closing stale issue. Please reopen this if you still have a problem.

@marcgibbons
Copy link

@andymccurdy You can set up multiple envs as "local" which tox will then pickup

e.g.
pyenv local redis-py 2.7.6 3.4.1 ...

@alexjomin
Copy link

@andymccurdy You made my days !

should definitely be in the doc IMHO ! I will do a PR if's ok for you @yyuu

You can set up multiple envs as "local" which tox will then pickup
e.g.
pyenv local redis-py 2.7.6 3.4.1 ...

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

No branches or pull requests

4 participants