trove-classifiers
The canonical, versioned list of PyPI trove classifiers for validating Python package metadata.
Repository Health
Technical Analysis
trove-classifiers is the PyPA-maintained, canonical source of the classifier strings PyPI accepts on package uploads — the Development Status ::, License ::, Programming Language :: style tags that appear on every project’s PyPI page. It ships the full list as two importable Python objects, a classifiers set and a deprecated_classifiers mapping from retired tags to their replacements, plus a small CLI that prints the current list.
Packaging tools such as twine, setuptools, and PyPI’s own upload validation depend on this package to check that a project’s declared classifiers are real and current before publishing, rather than hardcoding a copy of the list that drifts out of date.
What You Get
- A
classifiersset of every currently valid PyPI classifier string, importable directly into Python code - A
deprecated_classifiersdict mapping retired classifier strings to the classifiers that replace them - An
all_classifierslist combining current and deprecated entries for lookups that need to recognize both - A
trove-classifiersconsole script (andpython -m trove_classifiers) that prints the full sorted list to stdout - Full type annotations with a shipped
py.typedmarker for strict downstream type-checking
Common Use Cases
- Validating that a project’s
setup.py/pyproject.tomlclassifiers are real before uploading to PyPI - Building packaging tooling (linters,
setup.pygenerators, upload clients) that needs an authoritative, up-to-date classifier list - Looking up whether a classifier a project is using has been deprecated, and what to replace it with
- Populating a dropdown or autocomplete UI for classifier selection in a packaging tool or web form
Under The Hood
Architecture
The package is a single-module data library: src/trove_classifiers/__init__.py defines a flat sorted_classifiers list literal, derives a classifiers set from it, hand-maintains a deprecated_classifiers dict mapping retired tags to their replacements, and computes a merged all_classifiers list by sorting the two together. __main__.py is a two-line CLI that iterates sorted_classifiers and prints each entry, wired to a trove-classifiers console-script entry point. There’s no class hierarchy, no I/O, and no dependency injection — the entire public surface is four module-level constants declared in __all__, making the one canonical list the single source of truth and everything else a pure derivation of it.
Tech Stack
Plain Python 3 with zero runtime dependencies. It’s packaged with setuptools and versioned via CalVer (use_calver in setup.py) rather than semver, so each release’s version number encodes its publish timestamp. Dev tooling covers black for formatting, mypy in strict mode for type-checking (backed by the shipped py.typed marker), pytest for tests, and natsort to power a custom sort-order checker. CI is a single GitHub Actions workflow running make lint and make test on every push and pull request, with a separate workflow handling releases.
Code Quality
Tests are parametrized pytest cases exercising a purpose-built validator against both the shipped data and hand-crafted fixtures covering invalid top-level classifiers, dangling deprecated-classifier replacements, whitespace and colon violations, and Private :: prefix rules. A second test file diffs the output of the module invocation against the installed console script to guarantee they stay identical. Typing is enforced with mypy --strict in CI, formatting with black --check, and an unusual AST-based script fails the build if any of the three literal collections drift out of natural sort order — a lightweight but effective way to keep a large, frequently-edited list reviewable in diffs.
What Makes It Unique
There’s no clever algorithm here — the real value is institutional rather than technical: this is the single package PyPI itself, and most packaging tools, now depend on for classifier validation, replacing the old pattern of every tool bundling its own copy of the list that quietly went stale. The deprecated_classifiers mapping with forward-pointing replacements, and the sort-order enforcement for a 900+ entry list, are small but genuinely useful curation choices for what is otherwise static string data.