wntrblm / nox

Flexible test automation for Python
https://nox.thea.codes
Apache License 2.0
1.3k stars 148 forks source link

Support version specifiers in `nox`'s Python definition #814

Open chrysle opened 5 months ago

chrysle commented 5 months ago

How would this feature be useful?

I think it would really spare some work to not have to hard-code the Python versions to use in nox's session decorator or elsewhere. Version specifiers are a clean and efficient way to specify version ranges and exclude versions. packaging could handle the parsing of the specifier set, as it's also already a dependency of nox. This might also be useful regarding what #811 proposes.

Describe the solution you'd like

Being able to specify something like the following in the end:

@nox.session(python=">=3.8,<=3.12,!=3.9")
def tests(session):
    pass

Describe alternatives you've considered

Working with the Python specification syntax that exists currently, which isn't too tedious.

Anything else?

No response

henryiii commented 5 months ago

Yes, it would. The biggest issue would be parametrization; how would you parametrize over Pythons using this? I don't like Python parametrization most of the time (the new force-python support for unparameterized session is fantastic!), but some people do. A followup might be to add some sort of generator function that would turn >=3.10 into 3.10, 3.11, and 3.12.

I'm not sure how this would interact with PyPy.

Also, great care should be taken not to promote upper caps. These are not supported properly in the Python ecosystem and packages that add them (numba, numpy, etc) quickly have had to remove them due to breakage and them not behaving as you might expect - they are used to back solve, and back solving is never correct for an upper cap, you are not more likely to support a newer Python version in the past. See https://iscinumpy.dev/post/bound-version-constraints/ for example. I think this would only be tempting for parametrization, so maybe we could ignore upper caps and require a user to specify an upper cap in the helper function, something like nox.project.supported_pythons(">=3.10", max="3.12").

I've been eyeing https://pypi.org/project/findpython and wondering if we could use that to find Python's. I'm not sure if it supports Specifiers, it calls it a version_spec, but there are no examples with one, and pipx run findpython ">=3.10" doesn't work.

chrysle commented 4 months ago

(the new force-python support for unparameterized session is fantastic!)

Thank you!

A followup might be to add some sort of generator function that would turn >=3.10 into 3.10, 3.11, and 3.12.

I'm in favour.

I'm not sure how this would interact with PyPy.

Could you elaborate on your concerns?

I think this would only be tempting for parametrization, so maybe we could ignore upper caps and require a user to specify an upper cap in the helper function, something like nox.project.supported_pythons(">=3.10", max="3.12").

Ah, I didn't know about that problem. Thanks for pointing me towards it.

I've been eyeing https://pypi.org/project/findpython and wondering if we could use that to find Python's. I'm not sure if it supports Specifiers, it calls it a version_spec, but there are no examples with one, and pipx run findpython ">=3.10" doesn't work.

As the author has shown his support for the request, I'll see whether I can implement something in the near future.

chrysle commented 4 months ago

By the way, by introducing this, we'll also be able to address #384.