Pyenv: pyvenv: command not found


#1

It seems that some changes in the ubuntu image have caused pyenv not to be available anymore.

I was able to reproduce it just with this config and using Ubuntu 14.04:

machine:
    python:
        version: 3.4.3

And this is the error I get:

pyenv: pyvenv: command not found

The `pyvenv' command exists in these Python versions:
  3.3.5
  3.3.6
  3.4.3
  3.4.4
  3.5.0
  3.5.1


((if (directory? "/home/ubuntu/virtualenvs/venv-3.4.3") (echo "Using cached venv") (do ("pyvenv" "/home/ubuntu/virtualenvs/venv-3.4.3" || exit 1) (source "/home/ubuntu/virtualenvs/venv-3.4.3/bin/activate" || exit 2) (pip install nose || exit 3))) "rm -rf venv; ln -s /home/ubuntu/virtualenvs/venv-3.4.3 venv" (echo "source /home/ubuntu/virtualenvs/venv-3.4.3/bin/activate" >> "~/.circlerc")) returned exit code 1

Action failed: pyvenv

#2

Thanks for reporting this. We just rolled out a new version of the 14.04 image which fixes this (and several other issues).


#3

I’m still getting the pyenv error with CIRCLE_BUILD_IMAGE=ubuntu-14.04. It only happens when rebuilding w/o cache, but that’s exactly what I need to do for my build at the moment due to a separate issue.


#4

Apologies that it still didn’t work when rebuilding without cache.

To elaborate, I tested by SSHing into a 14.04 container running the image and pyenv ran successfully. So for new builds things should run correctly.

For anyone else running into issues, a workaround being used by Ian is to add something like the following to circle.yml:

machine:
  pre:
    - pyenv local 3.5.1
    - virtualenv venv

#5

This appears to have regressed in 2.0 using the circleci/python:3.6.1 docker image. Is there another that includes pyenv, tox, etc, or is this no longer supported?


#6

On CircleCI 2.0 we recommend using different container images for different language versions.

Or you could find or create a Docker image that has pyenv and the other requirements preinstalled.

Another alternative is to install them during the job as dependencies (e.g. pip instaling tox will be fast and can be done on each build if you wish)

Here’s an example of using multiple containers to do a matrix style build:

version: 2.0

shared: &shared
    working_directory: ~/circleci-demo-workflows
    steps:
      - checkout
      - run: bundle install --path vendor/bundle
      - run: bundle exec rake db:create db:schema:load
      - run:
          name: Run tests
          command: rake

jobs:
  "ruby-2.2":  
    <<: *shared
    docker:
      - image: circleci/ruby:2.2-node
      - image: circleci/postgres:9.4.12-alpine

  "ruby-2.3":
    <<: *shared
    docker:
      - image: circleci/ruby:2.3-node
      - image: circleci/postgres:9.4.12-alpine


  "ruby-2.4":
    <<: *shared
    docker:
      - image: circleci/ruby:2.4-node
      - image: circleci/postgres:9.4.12-alpine

workflows:
  version: 2
  build:
    jobs:
      - "ruby-2.2"
      - "ruby-2.3"
      - "ruby-2.4"

This is using a feature of YAML called ‘anchors’ to reduce repetition.


#7

Thanks, @tom. I ended up spending the day implementing the first two options, and will stick with workflows for now, so I don’t also have to maintain the additional Docker image as well.

However, the result is quite bulky and unsatisfying, especially for a small project. It would be nicer to have something cleaner, especially given that so many Python projects these days have to deal with Py2/3 compatibility.


#8

Thanks for the feedback @carldunham, much appreciated. I agree with the sentiment that the current way of doing this could be simpler and more elegant.

We’re having discussions internally on ways to make things easier in the future for this kind of use case so your feedback is very helpful to make sure we implement something that is of value.


#9

Thank you, @tom .

Just one other piece of input: using just plain tox will be helpful for people who just want generic 2/3 compatibility, given that Ubuntu allows both versions to be installed. However, even for that, it means adding an apt-get call for the “other” version. Going past just the two, for example to deal with the various Python3 versions (3.4.0 for Trusty, 3.5.1 for Xenial, and 3.6.1 as “current”, for example), would require either multiple containers, a custom Docker image that installs pyenv and does pyenv install for each version, or a config.yml that does essentially the same thing (and takes a long time to run).

I’m sure you are aware of this all, just wanted to leave it here as an observation.

Thanks again for listening!


#10