pytest running with another version of python
Asked Answered
M

4

46

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?

Molly answered 21/11, 2016 at 11:13 Comment(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.Lamont
@Lamont which python => /home/meysam/.pyenv/shims/python - which pytest => /usr/local/bin/pytestMolly
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.Gwenette
L
43

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.
Lamont answered 21/11, 2016 at 12:34 Comment(3)
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 pytestMolly
@Meysam that means you didn't install pytest for both versions of python (you need to do it separately, you know).Lamont
Thanks. I installed it separately and now it works :)Molly
S
12

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

python -m pytest tests/my_test.py

I hope it works

Starkey answered 21/11, 2016 at 11:50 Comment(4)
I get this error by running the above command: /home/meysam/.pyenv/versions/3.5.2/bin/python: No module named pytestMolly
Have you installed pytest successfully?Starkey
Yes, and all of my tests are passed when I run it. But it only runs under python 2.7.6.Molly
Use python -m pip install pytest to install pytest in the environment and then try running python -m pytestGwenette
R
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 "$@"
Rna answered 7/11, 2020 at 13:23 Comment(0)
L
1

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).

Laniferous answered 6/11, 2023 at 21:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.