51

I've installed pyenv and have different versions of python installed with it:

$ pyenv versions
  system
  2.7.1
  3.2.5
  3.5.0
  3.5.1
* 3.5.2

I use the following command to switch to python 3.5.2:

pyenv shell 3.5.2

And when I check the python version this is what I get:

$ python --version
Python 3.5.2

But when I run pytest, it still runs under python 2.7.6:

pytest -v
==================================================================== test session starts ====================================================================
platform linux2 -- Python 2.7.6, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- /usr/bin/python

Why is pytest running under the older version?

3
  • What do which python and which pytest show? Are the pointed-to files links or some launcher scripts? You may also try hash -r to eliminate the case of stale bash path cache. Commented Nov 21, 2016 at 11:38
  • @ivan_pozdeev which python => /home/meysam/.pyenv/shims/python - which pytest => /usr/local/bin/pytest Commented Nov 21, 2016 at 12:20
  • 3
    From the which out you learn that python uses the python version in your environment, however pytest uses the globally available one, that is located under /usr/local/.... To run Pytest inside your virtual environment, first install it using python -m pip install pytest and then run python -m pytest. Commented Sep 15, 2021 at 16:46

4 Answers 4

47

Bottom line: run

  • python -m pytest, or
  • py.test-<version> if your alternative Python and pytest are installed with system package manager, or
  • if your alternative Python has been installed with pyenv, switch with pyenv to that version and make sure you have pytest installed for it. Then you can just run pytest.
    • since the pip executable is also among the ones being switched, you need to switch to the alternative Python before installing pytest for it, too.

As I can see, /usr/bin/pytest (that belongs to the system package manager's python-pytest package) has a shebang !#/usr/bin/python since it corresponds to the system python's installation.

pyenv, as its README.md says, does not replace /usr/bin/python - because it indeed should not be replaced to avoid breaking system packages.

Instead, it adds its directory to PATH and inserts a launcher there (called "shim") which is what gets invoked when you type "python". As you probably guessed, this hack is ignored by a shebang like the above - as it should.

  • Running python -m pytest will make whichever python that launches itself use the package from its installation.
  • Alternatively, pytest for your other Python version may include versioned executables on the PATH named py.test-<version> (e.g. py.test-3 or py.test-3.6) depending on the way you installed it.
    • If it's from a system package manager's package for nonstandard python - like python36-pytest - this is virtually guaranteed.
    • I checked that if you install a version with pip, it only creates an unversioned executable (though you can create a versioned one yourself). Moreover, if you install the same package for a different Python version but with the same --prefix, it will overwrite the existing one's executable!
  • pyenv's suggested way seems to be to install all python versions of interest and packages for them under ~/.pyenv/versions.
    • This is not applicable for the system's Python but the default /usr/local can be used for it.
    • Once you switch to an alternative Python version, it claims to create shims for all scripts (including pip!) that are currently installed for that version, so invoking those scripts without a path would run those shims.
      • So, if a package (and thus its script) is not installed for the alternative version but installed for system version, trying to run its executable would "fall through" to /usr/local with just the result you're seeing now.
Sign up to request clarification or add additional context in comments.

3 Comments

I don't know why but when I run python -m pytest I get this error: /home/meysam/.pyenv/versions/3.5.2/bin/python: No module named pytest
@Meysam that means you didn't install pytest for both versions of python (you need to do it separately, you know).
Thanks. I installed it separately and now it works :)
14

I found this related question. For them it worked with this:

python -m pytest tests/my_test.py

I hope it works

4 Comments

I get this error by running the above command: /home/meysam/.pyenv/versions/3.5.2/bin/python: No module named pytest
Have you installed pytest successfully?
Yes, and all of my tests are passed when I run it. But it only runs under python 2.7.6.
Use python -m pip install pytest to install pytest in the environment and then try running python -m pytest
2

I just wanted to run "black" for Python 2.7, but I have installed it in pyenv's Python 3.7.9. It worked correctly with the script /usr/local/bin/black27:

PYENV_VERSION=3.7.9 black -t py27 "$@"

It didn't work with:

pyenv shell 3.7.9
black -t py27 "$@"

nor

pyenv shell 3.7.9
pyenv exec black -t py27 "$@"

Comments

2

I have encountered this issue during my recent runs of pytest, and the reason was that I had pytest installed globally too.

The scenario is running pytest during your virtual environment is active, and you get errors, the reason is that the shell looks for pytest in your $PATH environment variable and it finds a pytest executable before it finds the one in your virtual environment which is associated with your system-wide Python installation.

In summary to solve this, by running,

python -m pytest

you tell Python to use pytest that is installed in the current Python environment.

By the way, -m flag is used to run a library module as a script (Execute module's __main__.py file).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.