pyjamas
pyjamas

Reputation: 5408

How to manage multiple Python versions in Windows 10 to use with Python tox?

I'm trying to use tox to automate pytest testing of my project on Python 3.7 and 3.8 but am struggling with how to best set this up. What's the easiest way to get multiple Python versions installed on my Windows 10 machine in order to use them with tox?

If I just manually install them using the official installers how do I set up my environment variables? Because each installation contains python.exe, so if I install two versions and add both their paths C:\Program Files\Python37\ and C:\Program Files\Python38\ to my Path environment variable this won't differentiate them... python will just refer to the first one listed. So do I need to go and manually rename the python.exe files to names like python37.exe and python38.exe? This all seems very manual and clunky but I can't find any easier way or tutorial about this step.

The tox documentation just gives a solution using conda, but I'm not using conda and don't want to switch to it just to use tox.

If Python version paths and aliases are set up manually, then if someone clones my project to work on a PR and wants to run tests locally, tox would not work correctly if their Python install locations are different or they're on a different OS. Is there some standard way to define and set this all up so things are easy and consistent across machines?

If all this is unavoidable, what is an alternative to tox for consistently testing projects across multiple Python versions that can work on any machine or CI/CD pipeline?

Upvotes: 0

Views: 1334

Answers (1)

Jürgen Gmach
Jürgen Gmach

Reputation: 6121

tox has quite some logic implemented to find installed Python interpreters.

While the documentation lacks some details (maybe you want to create an issue?), we can still have a look a the source code:

@tox.hookimpl
def tox_get_python_executable(envconfig):
    spec, path = base_discover(envconfig)
    if path is not None:
        return path
    # second check if the py.exe has it (only for non path specs)
    if spec.path is None:
        py_exe = locate_via_pep514(spec)
        if py_exe is not None:
            return py_exe

    # third check if the literal base python is on PATH
    candidates = [envconfig.basepython]
    # fourth check if the name is on PATH
    if spec.name is not None and spec.name != envconfig.basepython:
        candidates.append(spec.name)
    # or check known locations
    if spec.major is not None and spec.minor is not None:
        if spec.name == "python":
            # The standard names are in predictable places.
            candidates.append(r"c:\python{}{}\python.exe".format(spec.major, spec.minor))
    return check_with_path(candidates, spec)

As you can see, there are five ways to determine the available Python interpreters on a Windows system.

Especially the second one looks promising -it is using the already mentioned Python launcher for Windows, also see https://www.python.org/dev/peps/pep-0514/

As far as I understand it, you just need to install your Python interpreters, and they will be automatically discoverable.

tox is definitely a very good way to test Python applications against multiple interpreters, both locally and in CI.

P.S.: Yes, it works!!

I just rdp'ed into a Windows box, installed Python 3.8 and Python 3.9 - just clicked through the default installer, and created the following tox.ini

[tox]
envlist = py38, py39

[testenv]
commands = python -c "print('hello')"
skip_install = true

Both interpreters were detected and both environments got executed.

(venv) C:\Users\jugmac00\Projects\stackoverflow>tox
py38 create: C:\Users\jugmac00\Projects\stackoverflow\.tox\py38
py38 run-test-pre: PYTHONHASHSEED='296'
py38 run-test: commands[0] | python -c 'print('"'"'hello'"'"')'
hello
py39 create: C:\Users\jugmac00\Projects\stackoverflow\.tox\py39
py39 run-test-pre: PYTHONHASHSEED='296'
py39 run-test: commands[0] | python -c 'print('"'"'hello'"'"')'
hello
_______________________________________________________ summary _______________________________________________________
  py38: commands succeeded
  py39: commands succeeded
  congratulations :)

(venv) C:\Users\jugmac00\Projects\stackoverflow>

Upvotes: 2

Related Questions