nox icon indicating copy to clipboard operation
nox copied to clipboard

Allow running a session with a different Python interpreter

Open pfmoore opened this issue 2 years ago • 8 comments

How would this feature be useful?

I normally run nox -s test to run my tests using the default Python version (the one nox is installed under, I guess?) This is my most common activity, and I'd like it to be straightforward. However, I sometimes want to run the tests for a specific Python version. I can do this by parametrising the Python version for the test session, but if I do that, nox -s test now means "run the test session for all Python versions.

Furthermore, I don't want to have to hard-code the list of Python versions. Doing that means I need to update the noxfile every time a new Python version comes out.

Describe the solution you'd like

If a session does not have the Python version parametrised, nox -s session --use-python 3.9 would run the given session with Python 3.9. Having -P as a short form for --use-python would be useful.

Describe alternatives you've considered

  • Using @session(python=None, "3.8", "3.9", "3.10") looks like it might work, as it creates a session with no suffix. But that still runs all of the suffixed sessions, rather than just running the one session.
  • --force-pythons sounds like it would work, but it doesn't, it just says "Python version selection caused no sessions to be selected".

Anything else?

No response

pfmoore avatar May 25 '22 16:05 pfmoore

I'm personally open to this idea, but I would also like to hear the opinion from other maintainers. If we decide to apply this, I'm a strong +1 to add --use-python / -P.

DiddiLeija avatar May 25 '22 16:05 DiddiLeija

Hi @pfmoore!

I normally run nox -s test to run my tests using the default Python version (the one nox is installed under, I guess?)

If you use nox.session with no python specified, Nox will indeed use the version it is installed under.

but if I do that, nox -s test now means "run the test session for all Python versions.

You should be able to do e.g nox -s test-3.10 and select only the 3.10 version in a parametrised test, I don't know if this is any help to you?

Furthermore, I don't want to have to hard-code the list of Python versions. Doing that means I need to update the noxfile every time a new Python version comes out

I'm with you on this one, there is a proposal in #384 to read requires_python from a PEP 621 pyproject.toml. This could be used to test all current versions above this minimum removing the need to specify it twice (once in metadata, again in the noxfile), however this hasn't been started on yet (although I'm always after another project so might have a go at some point).

Overall I like this idea, my only cause for concern is the presence of both a --force-python and a --use-python. To me they are too similar and are a hint that the same functionality is being repeated. I do vaguely remember a bug being raised against --force-python that led to the error message you ran into being implemented but I can't recall the details.

I would like it if we could combine the functionality into 1 flag but if that's not feasible or leads to too much mess I'm happy with the --use-python or -P flag you suggest.

Perhaps the --force-python flag should truly be a "force" operation, disregard all other version checks and make a best effort to run the given session with the matching interpreter (if it exists)

FollowTheProcess avatar May 25 '22 17:05 FollowTheProcess

You should be able to do e.g nox -s test-3.10 and select only the 3.10 version in a parametrised test, I don't know if this is any help to you?

I'm aware of that but (a) it's more verbose, and (b) it requires me to parametrise the session, which as I say is a maintenance overhead.

there is a proposal in https://github.com/wntrblm/nox/issues/384 to read requires_python from a PEP 621 pyproject.toml

That would still result in the session being parametrised, which means that nox -s test will run multiple sessions, which is exactly what I want to avoid (having to remember that nox -s build needs no Python version, but nox -s test-3.10 does is a big part of the issue for me here).

Just a thought, though - as far as reading requires_python is concerned, presumably the list in @session(python=[...]) could be generated dynamically, so you could do this without needing explicit support for it in nox?

Overall I like this idea, my only cause for concern is the presence of both a --force-python and a --use-python

Fair point. I couldn't see the point of --force-python, but on checking again, it seems that --force-python does what I want, but only for sessions that have the Python interpreter parametrised. Maybe allowing --force-python to work on "normal" sessions (without the Python version parametrised) would be a more consistent approach? (But if we go that way, can we make -P be a short form of --force-python?)

Actually, I just did some further testing. If I put the following in my noxfile.py:

import nox

@nox.session(python=[None])
def test(session):
    session.run("python", "-V")

it appears to work just as I want: nox -s test --force-python 3.9 runs the session under 3.9, and nox -s test runs it under the default Python.

I don't understand the difference between @session and @session(python=[None]). Is there a reason why they can't both behave in the same way? That would be much more reasonable to me.

In the meantime I have a workaround. It's ugly, but it appears to give me the behaviour I want.

pfmoore avatar May 25 '22 18:05 pfmoore

Maybe allowing --force-python to work on "normal" sessions (without the Python version parametrised) would be a more consistent approach?

This looks like a good approach to me :)

I don't understand the difference between @session and @session(python=[None]).

According to https://nox.thea.codes/en/stable/config.html#defining-sessions, python is None by default, not [None]. I suppose that's the reason.

DiddiLeija avatar May 25 '22 18:05 DiddiLeija

According to https://nox.thea.codes/en/stable/config.html#defining-sessions, python is None by default, not [None]. I suppose that's the reason.

Sorry, I should have been clearer, I knew that (that's actually what prompted me to try [None]) but I'm not sure what the intended difference is. Or more fundamentally, what the actual difference is between a parametrised session and a non-parametrised session (beyond the obvious, that a parametrised test might have more than one Python version specified).

pfmoore avatar May 25 '22 18:05 pfmoore

Oh, got it. I'm also not sure of that :man_shrugging:

DiddiLeija avatar May 25 '22 18:05 DiddiLeija

I'm aware of that but (a) it's more verbose, and (b) it requires me to parametrise the session, which as I say is a maintenance overhead.

Oh I see now sorry! You want to have a session e.g.:

@nox.session
def test(session):
    session.install("pytest")
    session.run("pytest")

That will by default run on the python that Nox is installed into, and then you want to instruct it to use another one i.e.:

nox -s test -P 3.9

The session will now run on 3.9 (if available)?

In this case I think your suggestion is the cleanest way to implement this:

Maybe allowing --force-python to work on "normal" sessions (without the Python version parametrised) would be a more consistent approach? (But if we go that way, can we make -P be a short form of --force-python?)

FollowTheProcess avatar May 25 '22 19:05 FollowTheProcess

@FollowTheProcess Exactly that, yes.

pfmoore avatar May 25 '22 20:05 pfmoore