Skip to content

Commit 657cd44

Browse files
committed
Use natsort to sort trove_classifiers.
1 parent a76b899 commit 657cd44

15 files changed

+118
-44
lines changed

repo_helper/cli/commands/suggest.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
# 3rd party
3232
import click
3333
from consolekit import CONTEXT_SETTINGS
34+
from natsort import natsorted
3435

3536
# this package
3637
from repo_helper.cli import cli_group
@@ -147,7 +148,7 @@ def classifiers(add: bool, status: Optional[int], library: Optional[bool]):
147148
# # Lines starting with a # will be discarded.
148149
# """
149150
# )
150-
# file_content += "\n".join(sorted(suggested_classifiers))
151+
# file_content += "\n".join(natsorted(suggested_classifiers))
151152
#
152153
# def remove_invalid_entries(line):
153154
# line = line.strip()
@@ -170,10 +171,10 @@ def classifiers(add: bool, status: Optional[int], library: Optional[bool]):
170171

171172
if sys.stdout.isatty():
172173
click.echo("Based on what you've told me I think the following classifiers are appropriate:")
173-
for classifier in sorted(suggested_classifiers):
174+
for classifier in natsorted(suggested_classifiers):
174175
click.echo(f" - {classifier}")
175176
else:
176-
for classifier in sorted(suggested_classifiers):
177+
for classifier in natsorted(suggested_classifiers):
177178
click.echo(classifier)
178179

179180
if add is None:
@@ -192,7 +193,7 @@ def classifiers(add: bool, status: Optional[int], library: Optional[bool]):
192193
data = yaml.load((rh.target_repo / "repo_helper.yml").read_text())
193194

194195
if "classifiers" in data:
195-
data["classifiers"] = sorted({*data["classifiers"], *suggested_classifiers})
196+
data["classifiers"] = natsorted({*data["classifiers"], *suggested_classifiers})
196197

197198
yaml.explicit_start = True # type: ignore
198199

@@ -204,7 +205,7 @@ def classifiers(add: bool, status: Optional[int], library: Optional[bool]):
204205

205206
with (rh.target_repo / "repo_helper.yml").open('a') as fp:
206207
fp.write('\n')
207-
yaml.dump({"classifiers": sorted(suggested_classifiers)}, fp)
208+
yaml.dump({"classifiers": natsorted(suggested_classifiers)}, fp)
208209

209210

210211
# TODO: flags for interactive options, and clean output when piped

repo_helper/configuration/__init__.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
from domdf_python_tools.paths import PathPlus
3737
from domdf_python_tools.typing import PathLike
3838
from domdf_python_tools.versions import Version
39+
from natsort import natsorted
3940

4041
# this package
4142
import repo_helper
@@ -330,16 +331,14 @@ def custom_parsing(
330331
parsed_config_vars["tox_travis_versions"] = tox_travis_versions
331332
parsed_config_vars["gh_actions_versions"] = tox_travis_versions
332333

333-
def add_classifier(classifier):
334-
if classifier not in parsed_config_vars["classifiers"]:
335-
parsed_config_vars["classifiers"].append(classifier)
336-
337334
if (repo_path / parsed_config_vars["import_name"].replace('.', '/') / "py.typed").is_file():
338-
add_classifier("Typing :: Typed")
335+
parsed_config_vars["classifiers"].append("Typing :: Typed")
339336

340337
if parsed_config_vars["use_experimental_backend"]:
341338
parsed_config_vars["tox_build_requirements"].append("repo_helper")
342339

340+
parsed_config_vars["classifiers"] = natsorted(set(parsed_config_vars["classifiers"]))
341+
343342
return parsed_config_vars
344343

345344

repo_helper/configuration/metadata.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
# 3rd party
3131
from configconfig.configvar import ConfigVar
3232
from configconfig.utils import optional_getter
33+
from natsort import natsorted
3334
from packaging.version import Version
3435
from shippinglabel.classifiers import validate_classifiers
3536

@@ -376,7 +377,7 @@ def add_classifier(c):
376377

377378
validate_classifiers(classifier_list)
378379

379-
return sorted(classifier_list)
380+
return natsorted(classifier_list)
380381

381382

382383
class keywords(ConfigVar): # noqa

repo_helper/configuration/utils.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
import pathlib
2828
from typing import Any, Dict, Iterable, List, Mapping, Tuple
2929

30+
# 3rd party
31+
from natsort import natsorted
32+
3033
__all__ = [
3134
"get_tox_python_versions",
3235
"get_tox_travis_python_versions",
@@ -105,7 +108,7 @@ def get_version_classifiers(python_versions: Iterable[str]) -> List[str]:
105108
version_classifiers.append("Programming Language :: Python")
106109
version_classifiers.append("Programming Language :: Python :: 3 :: Only")
107110

108-
return sorted(set(version_classifiers))
111+
return natsorted(set(version_classifiers))
109112

110113

111114
def parse_extras(raw_config_vars: Mapping[str, Any], repo_path: pathlib.Path) -> Tuple[Dict, List[str]]:

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ dulwich>=0.19.16
1010
email-validator==1.1.2
1111
isort>=5.0.0
1212
jinja2>=2.11.2
13+
natsort>=7.1.0
1314
packaging>=20.4
1415
pre-commit>=2.7.1
1516
requests>=2.25.0

tests/test_config_vars.py

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
test_list_int,
4141
test_list_str
4242
)
43+
from pytest_regressions.data_regression import DataRegressionFixture
4344

4445
# this package
4546
from repo_helper.configuration import * # pylint: disable=wildcard-import
@@ -309,46 +310,51 @@ def test_import_name_errors(wrong_value, match):
309310
import_name.get(wrong_value)
310311

311312

312-
def test_classifiers():
313+
@pytest.mark.parametrize(
314+
"config_dict",
315+
[
316+
pytest.param({"classifiers": ["Environment :: Console"]}, id="environment_console"),
317+
pytest.param({"classifiers": []}, id="empty"),
318+
pytest.param({"username": "domdfcoding"}, id="not_given_1"),
319+
pytest.param({}, id="not_given_2"),
320+
pytest.param({
321+
"classifiers": ["Environment :: Console"],
322+
"python_versions": [3.6, 3.7, 3.8],
323+
},
324+
id="environment_console_simple_versions"),
325+
pytest.param({
326+
"classifiers": ["Environment :: Console"],
327+
"python_versions": [3.6, 3.7, 3.8, "3.10"],
328+
},
329+
id="environment_console_complex_versions"),
330+
pytest.param({
331+
"classifiers": ["Environment :: Console"],
332+
"python_versions": [3.7, "3.10", 3.8, 3.6],
333+
},
334+
id="environment_console_unordered_versions"),
335+
pytest.param({
336+
"classifiers": ["Environment :: Console"],
337+
"python_versions": [3.6, 3.7, 3.8, "pypy3"],
338+
},
339+
id="environment_console_pypy_versions"),
340+
pytest.param({
341+
"classifiers": ["Environment :: Console"],
342+
"license": "MIT",
343+
},
344+
id="environment_console_license_mit"),
345+
]
346+
)
347+
def test_classifiers(config_dict: Dict[str, Any], data_regression: DataRegressionFixture):
348+
data_regression.check(classifiers.get(config_dict))
313349

314-
default_classifiers = [
350+
assert classifiers.get() == [
315351
"Operating System :: OS Independent",
316352
"Programming Language :: Python",
317353
"Programming Language :: Python :: 3 :: Only",
318354
"Programming Language :: Python :: 3.6",
319355
"Programming Language :: Python :: Implementation :: CPython",
320356
]
321357

322-
assert classifiers.get({"classifiers": ["Environment :: Console"]}) == [
323-
"Environment :: Console",
324-
*default_classifiers,
325-
]
326-
assert classifiers.get({
327-
"classifiers": ["Environment :: Console"],
328-
"python_versions": [3.6, 3.7, 3.8],
329-
}) == [
330-
"Environment :: Console",
331-
"Operating System :: OS Independent",
332-
"Programming Language :: Python",
333-
"Programming Language :: Python :: 3 :: Only",
334-
"Programming Language :: Python :: 3.6",
335-
"Programming Language :: Python :: 3.7",
336-
"Programming Language :: Python :: 3.8",
337-
"Programming Language :: Python :: Implementation :: CPython",
338-
]
339-
assert classifiers.get({
340-
"classifiers": ["Environment :: Console"],
341-
"license": "MIT",
342-
}) == [
343-
"Environment :: Console",
344-
"License :: OSI Approved :: MIT License",
345-
*default_classifiers,
346-
]
347-
assert classifiers.get({"classifiers": []}) == default_classifiers
348-
assert classifiers.get({"username": "domdfcoding"}) == default_classifiers
349-
assert classifiers.get() == default_classifiers
350-
assert classifiers.get({}) == default_classifiers
351-
352358

353359
@pytest.mark.parametrize(
354360
"wrong_value",
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
- 'Operating System :: OS Independent'
2+
- 'Programming Language :: Python'
3+
- 'Programming Language :: Python :: 3 :: Only'
4+
- 'Programming Language :: Python :: 3.6'
5+
- 'Programming Language :: Python :: Implementation :: CPython'
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
- 'Environment :: Console'
2+
- 'Operating System :: OS Independent'
3+
- 'Programming Language :: Python'
4+
- 'Programming Language :: Python :: 3 :: Only'
5+
- 'Programming Language :: Python :: 3.6'
6+
- 'Programming Language :: Python :: Implementation :: CPython'
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
- 'Environment :: Console'
2+
- 'Operating System :: OS Independent'
3+
- 'Programming Language :: Python'
4+
- 'Programming Language :: Python :: 3 :: Only'
5+
- 'Programming Language :: Python :: 3.6'
6+
- 'Programming Language :: Python :: 3.7'
7+
- 'Programming Language :: Python :: 3.8'
8+
- 'Programming Language :: Python :: 3.10'
9+
- 'Programming Language :: Python :: Implementation :: CPython'
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
- 'Environment :: Console'
2+
- 'License :: OSI Approved :: MIT License'
3+
- 'Operating System :: OS Independent'
4+
- 'Programming Language :: Python'
5+
- 'Programming Language :: Python :: 3 :: Only'
6+
- 'Programming Language :: Python :: 3.6'
7+
- 'Programming Language :: Python :: Implementation :: CPython'

0 commit comments

Comments
 (0)