Skip to content

Commit 689708c

Browse files
feat: sort classifier-derived Python versions (#1100)
1 parent c6e1008 commit 689708c

2 files changed

Lines changed: 35 additions & 1 deletion

File tree

nox/project.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import packaging.requirements
1818
import packaging.specifiers
19+
import packaging.version
1920
from dependency_groups import resolve
2021

2122
if TYPE_CHECKING:
@@ -108,7 +109,7 @@ def _load_script_block(filepath: Path, *, missing_ok: bool) -> dict[str, Any]:
108109

109110

110111
def python_versions(
111-
pyproject: dict[str, Any], *, max_version: str | None = None
112+
pyproject: dict[str, Any], *, max_version: str | None = None, sort: bool = True
112113
) -> list[str]:
113114
"""
114115
Read a list of supported Python versions. Without ``max_version``, this
@@ -117,6 +118,9 @@ def python_versions(
117118
value of ``max_version`` as the upper bound. (Reminder: you should never
118119
set an upper bound in ``requires-python``).
119120
121+
Classifier-derived versions are sorted by default. Set ``sort=False`` to
122+
preserve classifier order.
123+
120124
Example:
121125
122126
.. code-block:: python
@@ -137,6 +141,8 @@ def python_versions(
137141
if c.startswith("Programming Language :: Python :: 3.")
138142
]
139143
if from_classifiers:
144+
if sort:
145+
return sorted(from_classifiers, key=packaging.version.Version)
140146
return from_classifiers
141147
msg = 'No Python version classifiers found in "project.classifiers"'
142148
raise ValueError(msg)

tests/test_project.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,34 @@ def test_classifiers() -> None:
2323
assert python_versions(pyproject) == ["3.10", "3.11", "3.12"]
2424

2525

26+
def test_classifiers_are_sorted_by_default() -> None:
27+
pyproject = {
28+
"project": {
29+
"classifiers": [
30+
"Programming Language :: Python :: 3.12",
31+
"Programming Language :: Python :: 3.10",
32+
"Programming Language :: Python :: 3.11",
33+
],
34+
}
35+
}
36+
37+
assert python_versions(pyproject) == ["3.10", "3.11", "3.12"]
38+
39+
40+
def test_classifiers_can_preserve_order() -> None:
41+
pyproject = {
42+
"project": {
43+
"classifiers": [
44+
"Programming Language :: Python :: 3.12",
45+
"Programming Language :: Python :: 3.10",
46+
"Programming Language :: Python :: 3.11",
47+
],
48+
}
49+
}
50+
51+
assert python_versions(pyproject, sort=False) == ["3.12", "3.10", "3.11"]
52+
53+
2654
def test_no_classifiers() -> None:
2755
pyproject = {"project": {"requires-python": ">=3.10"}}
2856
with pytest.raises(ValueError, match="No Python version classifiers"):

0 commit comments

Comments
 (0)