Audits that rename or dissolve a category never added a redirect, which is how the 404s appearing in Search Console traced back to renamed category pages.
Co-Authored-By: Claude <noreply@anthropic.com>
Category pages carried no text of their own beyond the README one-line description, and most meta descriptions fell back to a generic "Explore N curated Python projects" line, which correlated with weak search rankings for category queries. This adds optional per-category intro markdown files rendered under the H1, with the first paragraph used as the meta description and links opening in a new tab, starting with the ORM category.
Co-Authored-By: Claude <noreply@anthropic.com>
Renamed or dissolved category slugs (e.g. /categories/web-servers/rpc/, /categories/code-analysis/code-linters/) returned 404, Search Console lists 7 of them, and each audit re-home was dropping the old URL's ranking.
Co-Authored-By: Claude <noreply@anthropic.com>
PR numbers named in chat during a review-prs run should be clickable so the maintainer can open each PR in the browser while deciding on it. Defines the PR link convention once in the intro and uses it at both chat sites: the closing-comment draft label and the final summary table.
Co-Authored-By: Claude <noreply@anthropic.com>
In the last review-prs run, closing comments were posted to GitHub without the maintainer ever seeing their full text - the AskUserQuestion options carried one-line paraphrases and the actual comment bytes first appeared inside the gh pr close --comment command. The old wording ("AskUserQuestion presenting the draft closing comment") was satisfiable by a summary. The Close arm now prints each draft verbatim in chat (fenced block, PR number as label) before the AskUserQuestion, and the step's completion criterion binds every posted comment to be byte-identical to a printed draft or to the maintainer's custom text.
Co-Authored-By: Claude <noreply@anthropic.com>
The uv-audit bug has no automatic guard outside the bundled-entry
case, so the hazard has to live in the audit process instead. The
sweep only queries names matching PYPI_NAME_RE, so a display name
with a space is skipped outright; renaming it into a PyPI-shaped name
starts it being queried, which is how 'uv audit' became 'uv-audit'
and picked up an unrelated third-party package by rocshers.
The gotcha tells the auditor to fetch PyPI metadata for any renamed
entry and add a null override when the package isn't the linked
project. It also records two broader checks that were measured
against the full list and rejected, so a future audit doesn't spend
time re-proposing them: the repo-backlink check misses this case
entirely since uv-audit declares no repo URL, as do 26 legitimate
entries, and it flags 10 benign org moves; the name-versus-repo-name
check returns 46 hits that are all legitimate, including uv-build
with the shape identical to uv-audit.
Co-Authored-By: Claude <noreply@anthropic.com>
The uv-audit bug had no automated guard: pypi_name_overrides.json is
a manual registry, so a wrong-package mapping is only caught if
someone already suspects it.
Two broader checks were measured against the real list and rejected.
Checking that PyPI metadata links back to the entry's GitHub repo
would not have caught uv-audit, since that package declares no
home_page or project_urls, landing it in a 26-entry bucket of
packages that simply don't declare a repo (numba, selenium, pyglet,
etc.), plus 10 benign cases of orgs moving or splitting bindings.
Flagging display-name/repo-name mismatches yields 46 hits, all
legitimate python-X-repo-to-X-package pairs, with uv-build sitting
among them despite being a real Astral package with the identical
shape to uv-audit.
What discriminates is the bundled marker itself: a "(part of X)"
entry ships inside something else and has no package of its own, so
the sweep must never query it. This test walks the real README and
requires a null override for every bundled entry whose normalized
name is PyPI-shaped. Verified it fails with exactly the uv-audit
message when that override is removed, and passes with it restored,
across the three current bundled entries with no false positives. It
runs offline, fitting the existing network-less CI.
Co-Authored-By: Claude <noreply@anthropic.com>
Renaming the entry from "uv audit" to "uv-audit" made the name PyPI-shaped: normalize() leaves spaces alone, so "uv audit" failed PYPI_NAME_RE and collect_names skipped it, but "uv-audit" passes, so the next sweep would have queried PyPI for it.
A uv-audit package does exist on PyPI, but it is version 0.1.9 by Alekse Marusich of rocshers, an unrelated third-party tool whose summary ("uv Tool for checking dependencies for vulnerabilities") is close enough to be mistaken for Astral's built-in uv audit subcommand. Without the override the entry would have shown that stranger's download count and lost its Bundled badge.
The sweep now writes uv-audit as NOT_FOUND, which load_downloads skips, so the badge is unaffected.
Co-Authored-By: Claude <noreply@anthropic.com>
Keep the docs link inline in the description instead of as the primary entry link, matching the format used by other entries.
Co-Authored-By: Claude <noreply@anthropic.com>
azure-sdk-for-python and google-cloud-python were rendering "Not on
PyPI", which is misleading. Both do ship on PyPI, just as many
per-service packages (azure-identity, azure-storage-blob,
google-cloud-storage, etc.) rather than under the repo name.
pypi_name_overrides.json already recorded that distinction in its
reason field; those two entries now carry an optional "badge" value
that build.py reads into the PyPI Downloads column. The other sixteen
no-count entries (cpython, renpy, agent skill repos, etc.) keep
"Not on PyPI" since that remains accurate for them.
Co-Authored-By: Claude <noreply@anthropic.com>
django.db.models, geodjango, httpx.URL and uv audit were rendering
"Not on PyPI" alongside eighteen genuinely standalone projects that
simply are not packaged on PyPI, conflating two different reasons for
a missing download count.
These four entries now carry a "(part of X)" description prefix in
README.md, mirroring the existing "(Python standard library)"
convention. build.py reads that prefix into a bundled flag that both
templates render as a "Bundled" badge.
The prefix approach was chosen over a separate data file so README.md
stays the single source of content truth, and over inferring from the
entry name because geodjango is neither dotted nor spaced and would
have been missed. Redundant tail wording was trimmed from the
httpx.URL, geodjango and uv audit descriptions now that the prefix
names the parent.
The new entry format is documented in CONTRIBUTING.md and the
vocabulary in CONTEXT.md.
Co-Authored-By: Claude <noreply@anthropic.com>
Standard-library entries rendered "Not on PyPI" in the PyPI Downloads
column, which read like missing data rather than a deliberate category
— the build already forces downloads to None for them so they never
pick up a same-named PyPI backport. They now render a "Stdlib" badge
instead, while genuine non-PyPI entries keep "Not on PyPI".
The filter tag is renamed to match, so the source-type value, the row
filter tag, and the synthetic category heading all read Stdlib now.
The literal "Built-in" strings scattered through build.py are routed
through the existing BUILTIN_FILTER constant so the label lives in one
place. The category page slug stays "built-in" so the public URL
/categories/built-in/ does not break.
Co-Authored-By: Claude <noreply@anthropic.com>
Add a Stability Exceptions section to docs/audit-logs.md documenting
the zensical override (admitted pre-1.0 to displace a dying mkdocs
upstream). Add a matching evidence bullet to CLAUDE.md and AGENTS.md
warning that a download count is not automatically independent demand
when one listed entry depends on another, using mkdocs / mkdocs-material
as the worked example. Both facts were discovered during this sitting
and need to persist so the next audit doesn't rediscover them.
Co-Authored-By: Claude <noreply@anthropic.com>
Material for MkDocs went into maintenance mode on 2025-11-05 and its
own team called upstream mkdocs unmaintained since 2024-08 and a
supply chain risk; the mkdocs repo was last pushed 2025-10-20. Since
mkdocs-material hard-depends on mkdocs, mkdocs' download count is
almost entirely mkdocs-material pulling it in (18,360,677/month vs
mkdocs-material's 18,167,775/month, ~1% delta), so dropping the
redundant direct entry costs little. zensical is a clean replacement
with no mkdocs dependency, built by the same Material for MkDocs
team, at 1,585,786 downloads/month and 5,540 stars, pushed
2026-08-21. Added as a challenger, placed last below pdoc, keeping
the section at 5 of 5. Approved via verdict preview.
Co-Authored-By: Claude <noreply@anthropic.com>
Obvious choice for physical units and dimensional analysis in Python: 8,647,557 downloads/month (pepy.tech, 2026-08-23), more than twice astropy (3,713,879) and thirty-six times obspy (237,352), 2,781 stars, created 2012, pushed 2026-08-05. PyPI classifier still reads Beta at v0.25.3, treated as stale given fourteen years of history and download scale (judgment call). Listed under Physics and Engineering per maintainer choice over minting a Units and Quantities subcategory.
Co-Authored-By: Claude <noreply@anthropic.com>
Audit of proposed additions from a YouTube video roundup. Admitted as
a challenger: 761,507 downloads/month (pepy.tech, 2026-08-23) already
outranks the incumbent prospector (497,880), the repo is active
(pushed 2026-08-21, version 7.0.1, Production/Stable) and it has
reached 794 stars since being created in January 2024. It fills a
real gap: ruff's PLR0912 measures cyclomatic complexity while
complexipy measures cognitive complexity, and the two are
complementary. Adoption-trajectory evidence is thin, so the
challenger tier is a judgment call. Placed last in the subcategory
since position marks tier and challengers follow obvious choices.
Co-Authored-By: Claude <noreply@anthropic.com>
Audit of proposed additions from a YouTube video roundup. transitions
has not been pushed since 2025-09-11 and crosses the 12-month activity
line on 2026-09-11, while python-statemachine is actively developed
(pushed 2026-08-17, version 3.2.1 released 2026-08-01) and covers
strictly more (SCXML-compliant statecharts, compound and parallel
states, history, sync and async). Downloads 1,422,332/month vs
transitions 3,137,416/month (pepy.tech, 2026-08-23).
Co-Authored-By: Claude <noreply@anthropic.com>
v7 blocks checking out fork PR heads under pull_request_target and
workflow_run. Neither workflow here uses those triggers, so the only
effect is staying current with the other repos.
Pydantic Services took over stewardship of the stalling httpx under the httpx2 name, Starlette already switched its TestClient, and it hit 144M downloads/month (pepy) within 3 months of first release at Production/Stable v2.12.0. Placed last in the challenger tier behind urllib3 per the downloads-descending ordering rule. Fork format and a rewritten description distinguish it from httpx, whose PyPI summary is identical.
Co-Authored-By: Claude <noreply@anthropic.com>
Project now requires Python >=3.14; the pin fails live (verified during
PR review), and plain uv run / make resolves correctly without it.
Co-Authored-By: Claude <noreply@anthropic.com>
The "most diffs sit on stale bases" claim was a one-time artifact of
the shortlist reform, not a durable fact about future PRs. Reworded to
state that diff context lines show the base the PR was written on,
which may have changed since, while keeping conflict-to-Merge-arm
routing.
Co-Authored-By: Claude <noreply@anthropic.com>
Two live review-prs runs surfaced fixes:
- Merge conflicts move from the screen-out rules to a local-merge path
in the Merge arm; 7/10 PRs conflicted only from the reform's stale
bases, and one such PR had already been merged this way.
- Target use case is now resolved from the current README instead of
stale diff context, since most PR bases no longer match live
sections.
- Judge gets a third verdict: no fitting use case is a structure
question, carried to Act for the maintainer to decide.
- Act's Close step gets a batching and checklist note, and the whole
step gets an explicit completion criterion after a verdict nearly
fell out of the question batches.
- Drop the "claude reviewed" label mechanism entirely: the fetch
filter, the Park arm, and the labeled-open terminal state.
Co-Authored-By: Claude <noreply@anthropic.com>
Add seleniumbase to Testing — Browser Automation as a challenger (2.86M downloads/month via pepy vs selenium 56.9M; admitted by maintainer decision). Entry placed per Entry Ordering, display name set to the canonical PyPI package name.
Superseded by the rewritten .claude/skills/review-prs/SKILL.md
committed just before (9ce2a21); leaving it in place would keep a
stale second copy of the PR-review instructions.
Co-Authored-By: Claude <noreply@anthropic.com>
The old review-pending-prs command carried a stale copy of CONTRIBUTING.md's rejection rules (100-star bar, "too niche") that contradicted the current shortlist model. This skill screens from the diff only, delegates admission judgment to the audit-the-list skill, then acts on GitHub: merge with section reconcile, AskUserQuestion-gated closes.
Co-Authored-By: Claude <noreply@anthropic.com>
Kicker now mirrors the hero kicker ("The definitive list that
answers..."), replacing the old "field guide" line changed in
8b14b4f. Subtitle now matches the current tagline ("An opinionated
guide to the best Python frameworks, libraries, and tools.") on one
line. PNG regenerated from the SVG.
Co-Authored-By: Claude <noreply@anthropic.com>
Entries now end with "(PyPI downloads/month: N, GitHub stars: M)" where
known, replacing the stars-only note, since download counts are the
list's stated primary evidence signal. annotate_entries_with_stars is
renamed to annotate_entries_with_stats and looks downloads up by the
first link's display name, skipping category-index bullets (which link
into the site itself) and Built-in entries (which would otherwise hit
same-named PyPI backports like logging or asyncio).
The intro now mirrors the README subtitle verbatim with the
project/category totals on their own line below, and the "opinionated
catalog" wording is gone since the shortlist ADR is literally titled
"shortlist, not a catalog".
Co-Authored-By: Claude <noreply@anthropic.com>
Replaces the em dash in the PyPI Downloads column with a source-badge
pill labeled "Not on PyPI", reusing the existing badge style used by
the stars column for visual consistency. Sorting is unaffected since
non-numeric cells already parse as missing.
Co-Authored-By: Claude <noreply@anthropic.com>
Downloads is now the default sort, so it sits directly after the
project name in both the index and category table templates. The
source-type badge stays in the stars cell.
Co-Authored-By: Claude <noreply@anthropic.com>
Entries with a download count now sort first (descending), with
stars, then Built-in, then name as fallback tiers for entries that
lack a count. main.js mirrors this in its default activeSort, clean
URL check, and third-click reset target. Sorting by stars remains one
header click away.
Co-Authored-By: Claude <noreply@anthropic.com>
Every entry is now {"package": str|null, "reason": str|null} instead of
a bare string/null. Reasons are required for null packages, explaining
why the name must never be queried (squatted name, stdlib module,
monorepo umbrella, GitHub-only project, and so on). Reasons are
optional for remaps and kept only on the six non-obvious ones: pytorch
(squatter), jinja (jinja is Jinja1), strawberry (unrelated bookmarking
service), django-rules (abandoned fork), django-rest-framework (dead
alias), and devpi (deprecated metapackage); plain publishes-as-X
remaps get a null reason.
load_overrides() in the clickpy fetcher now extracts the package field
from each entry; resolve() and the pepy/bigquery cross-check scripts
are unchanged since they consume load_overrides()'s output.
Co-Authored-By: Claude <noreply@anthropic.com>
Every queried name now resolves 447/447. Adds 23 explicit null
overrides so squatters can never silently attach a PyPI number to
these names later: stdlib-named entries (concurrent-futures, difflib,
mimetypes, sqlite3, tkinter, tomllib, zoneinfo), interpreters
(micropython, pypy), monorepo umbrellas (azure-sdk-for-python,
google-cloud-python), self-hosted or distro-installed projects (odoo,
cloud-init, warehouse), GitHub-only projects (thealgorithms,
geodjango, django-db-models, django-ai-plugins, graphify,
sentry-skills, social-engineer-toolkit, trailofbits-skills), and
httpx-url (a class within httpx, not a package).
Caveat: graphify and django-ai-plugins are young projects that may
legitimately publish to PyPI later — flip their null to a remap
during a future audit if they do.
Co-Authored-By: Claude <noreply@anthropic.com>
autobahn-python publishes as autobahn (7.1M/mo), pangu-py as pangu, and
strawberry-django as strawberry-graphql-django (1.5M/mo). httpx.URL is
left unmapped deliberately since it's a class within the httpx package,
not a package of its own.
Co-Authored-By: Claude <noreply@anthropic.com>
Sourced from website/data/pypi_downloads.tsv the same way
github_stars.json feeds the stars column. The new sortable column
sits between GitHub Stars and Last Commit on the homepage and
category pages, formatted with thousands separators like stars, with
an em dash when no PyPI data exists. Rows are matched by normalized
README display name; Built-in entries never show counts since
same-named PyPI packages are stdlib backports (e.g. the asyncio
package).
Below 960px the column hides and the count moves into the expand
row, mirroring the existing Last Commit treatment. main.js gains the
downloads sort branch and URL param.
The deploy workflow fetches the TSV via the new
make fetch_pypi_downloads target with a daily actions/cache
fallback, mirroring the stars fetch, but non-fatal: the column
degrades to dashes when the fetch fails, unlike stars which the
build requires.
Co-Authored-By: Claude <noreply@anthropic.com>
A pypi.org identity sweep of all 438 cached rows (project_urls/home_page
vs entry GitHub URL) found download counts were looked up by README
display name, so entries whose name differs from the canonical package
silently measured squatters or dead predecessors: pytorch measured a
squatter (169,737/mo vs torch's 94M), jinja measured Jinja1 (3,168 vs
jinja2's 736M), django-rest-framework a dead alias package (real:
djangorestframework), django-rules an abandoned fork (real: rules),
strawberry an unrelated bookmarking service (real: strawberry-graphql),
devpi a deprecated metapackage (mapped to devpi-server).
New curated website/data/pypi_name_overrides.json maps normalized
README name to the real package, or null for projects not
pip-installable whose name is squatted or a relic (cpython, pyenv,
renpy, python-patterns, winpython); also maps mem0 to mem0ai, fasthtml
to python-fasthtml, and playwright-python to playwright.
All three fetch scripts resolve names through it; the clickpy TSV
cache gains a package column recording what each row actually
measured. .gitignore switches website/data/ to website/data/* with a
negation so the curated overrides file is tracked while caches stay
ignored.
Co-Authored-By: Claude <noreply@anthropic.com>
The entry linked hydra-ecosystem/hydra, an unrelated W3C Hydra API
toolkit, while the entry name and description describe
facebookresearch's Hydra configuration framework, mixing the wrong
repo's stars with the right package's identity. Found during the
downloads-column identity sweep.
Co-Authored-By: Claude <noreply@anthropic.com>
Exact reproducibility already lives in uv.lock via 'uv sync --locked',
so == in pyproject.toml only duplicates the lockfile and blocks
'uv lock --upgrade'. Locked versions are unchanged.
Co-Authored-By: Claude <noreply@anthropic.com>
watchdog 6.0.0 (last release 2024-11-01) ships no cp314 macOS wheel,
and uv has no per-package build allowlist under no-build = true, so
the preview file watcher moves to watchfiles, which ships cp314
wheels. watchfiles now lives in its own preview dependency group.
UV_PYTHON=3.13 is no longer needed on machines that only have 3.14.
Co-Authored-By: Claude <noreply@anthropic.com>
Removed the companion-project clause from the Sub-item definition in
CONTEXT.md's vocabulary. Its examples (aws-sdk-pandas under pandas,
flower under celery) went stale this sitting: those companions were
promoted, re-homed, or deleted. Per the maintainer's 2026-08-16 policy
decision, sub-items are now reserved for awesome-* also-see links only
- a companion project must earn a full Entry in its proper Use Case or
not be listed.
Co-Authored-By: Claude <noreply@anthropic.com>
Re-homed pyenv-win from a pyenv sub-item (Environment Management) to a full entry in Microsoft Windows, placed before winpython by downloads (25.8k/mo vs 172). Actively maintained, pushed 2026-08-14, 7,360 stars. Maintainer preference is to move sub-items to a fitting category rather than delete.
Co-Authored-By: Claude <noreply@anthropic.com>
Flower isn't a task queue, so nesting it under celery misclassified it; Task Queues is also at its entry cap. Monitoring and Processes is its honest home, ranking fourth by downloads (12.35M/mo ClickPy, between supervisor 17.0M and sh 11.8M), and Celery's own docs name it the recommended monitor. Repo pushed 2026-08-16 with 7,232 stars. This fills Monitoring and Processes to its 5-entry cap.
Co-Authored-By: Claude <noreply@anthropic.com>
Was a sub-item under mkdocs. By downloads it ranks second in the
section at 17.6M/mo (ClickPy), above mkdocs' 17.4M, and it powers
FastAPI, Pydantic, and Ruff/Polars docs (27,269 stars, pushed
2026-08-09). Documentation now sits at its 5-entry cap.
Co-Authored-By: Claude <noreply@anthropic.com>
Not a tool readers install: type checkers bundle it automatically as a
stub collection, it has no PyPI package, and no standalone use case.
The Type Checkers subcategory label already links to
awesome-python-typing for ecosystem depth.
Co-Authored-By: Claude <noreply@anthropic.com>
Sub-item policy reserves sub-items for awesome-* links. aws-sdk-pandas
promoted out as awswrangler in Data Ingestion / ETL > General
(85.3M downloads/mo, 10x dlt, active).
Co-Authored-By: Claude <noreply@anthropic.com>
Reuses CONTRIBUTING.md's plainer 'would name when asked' phrasing instead of 'unprompted', per maintainer feedback that 'unprompted' didn't sound right.
Co-Authored-By: Claude <noreply@anthropic.com>
The old template used a stars-based tier system (Industry Standard /
Rising Star / Hidden Gem) that contradicted the current CONTRIBUTING.md,
which judges entries by obvious-choice/challenger tiers, favors PyPI
downloads over stars, and requires Displacement when a use case is at
its cap. The new template reflects those rules and adds a checklist
item pointing contributors to CONTRIBUTING.md.
Co-Authored-By: Claude <noreply@anthropic.com>
The maintainer decided how duplicate entries across categories should
be handled (e.g. uv listed in both Environment Management and Package
Management): each slot must earn its place independently, entries are
listed in full with identical lines rather than a cross-reference,
description edits update every copy in the same commit, and each slot
is audited on its own.
Co-Authored-By: Claude <noreply@anthropic.com>
Capture parser quirks worth knowing before editing README.md:
everything above is ignored, new subcategories need no
parser change, a standalone all-bold paragraph becomes a Thematic
Group marker, prose after leaks into llms.txt, and the
build's "Total entries" figure counts sub-items rather than just
entries.
Co-Authored-By: Claude <noreply@anthropic.com>
Note that data/github_stars.json is gitignored and fetched by CI at
deploy time, so local runs are preview-only and should never be
committed; entries removed from README.md just leave harmless orphan
keys behind.
Co-Authored-By: Claude <noreply@anthropic.com>
Extend the known failure-mode list for PyPI download counts beyond
model weights to any project consumed outside pip (SDK downloads like
renpy, deployed services like thumbor). Also clarify that the per-Use-
Case Cap is a ceiling, not a floor: a freshly minted Use Case may hold
a single entry.
Co-Authored-By: Claude <noreply@anthropic.com>
Cross-section re-homes now ride the originating audit's commit instead
of needing a separate one, since both sides of the move land in one
diff. Also note that Resources sections are out of audit scope and
never parsed by the website, so they're not project entries subject
to the one-entry-per-commit rule.
Co-Authored-By: Claude <noreply@anthropic.com>
Git history already archives every removal's reason via commit body,
but it can't be scanned at a glance. docs/audit-logs.md is the
at-a-glance register of overrides (naming exceptions, mature-stable
keeps) allowed by CONTRIBUTING.md. Drop the docs/* gitignore exclusion
(and stale .superpowers/ and skills-lock.json entries) so the file and
future doc additions outside docs/adr/ can be tracked.
Co-Authored-By: Claude <noreply@anthropic.com>
The pypi downloads sweep looks up counts by README display name; when
the display name differs from the canonical package, the row silently
measures an unrelated squatter or a dead predecessor. Document the
failure mode in both the fetcher's docstring and the audit skill so
famous entries with off-looking counts get identity-verified before
being cited.
Co-Authored-By: Claude <noreply@anthropic.com>
Resolves decision 10's reservation on maintainer word: the 3+2/5 cap
numbers stay as written — across the full prune they held everywhere
except a handful of explicit overrides — and the override practice
itself becomes a written rule: the maintainer may exceed any limit
for a specific entry or use case by explicit decision, case-by-case,
carrying no weight for submissions. CONTEXT.md gains the matching
Override vocabulary entry.
Co-Authored-By: Claude <noreply@anthropic.com>
Maintainer reversal of c0a31ce, restoring the entry and its
awesome-fasthtml sub-item to their prior position. The
challenger-limit override that rode the move is withdrawn with it —
Asynchronous returns to 4 entries within the standard cap shape.
Co-Authored-By: Claude <noreply@anthropic.com>
Re-admission on maintainer word, reversing the Data Analysis sweep's
drop (f3c920d — the xlsxwriter reversal precedent): the drop was
partly a mis-homing casualty, since its honest home, an ETL use case,
did not exist then. The repo self-describes as a Python ETL framework
for stream processing and LLM/RAG pipelines: 62.5K stars, pushed
daily; 16.5K downloads/month is weak for the star count and noted.
Enters as challenger behind dlt (7.8M/mo).
Co-Authored-By: Claude <noreply@anthropic.com>
The safishamsi/graphify URL is a stale redirect — the repo moved to
Graphify-Labs/graphify (verified via the GitHub API). Maintainer
declined the Agent Skills re-home; the entry stays in Data
Visualization > Specialized with its link fixed.
Co-Authored-By: Claude <noreply@anthropic.com>
Maintainer-adjudicated close of the standing flag: fasthtml runs on
Starlette and Uvicorn (ASGI), so Synchronous was the wrong shelf. It
lands as a third challenger behind starlette and tornado's obvious
choices — the use case holds 5 with 3 challengers by explicit
maintainer override (Async I/O precedent; the awesome-fasthtml
sub-item rides along). 1.19M downloads/month as python-fasthtml.
Co-Authored-By: Claude <noreply@anthropic.com>
No removals. mimetypes and pathlib (standard library) lead
alphabetically under the stdlib-first rule; watchfiles (389.3M/mo,
partly uvicorn-transitive — the riser) completes the obvious choices;
watchdog (113.3M/mo, the demoted incumbent, Second Tier) and
python-magic (32.3M/mo) challengers.
Co-Authored-By: Claude <noreply@anthropic.com>
Tiers: beautifulsoup4 (renamed from beautifulsoup — the bare PyPI
name is the abandoned bs3 shim; 451.4M/mo, docs link per the PyQt
precedent), lxml (401.3M/mo), xmltodict (124.5M/mo) obvious choices;
markupsafe (820.5M/mo — the section's biggest raw count, but
jinja-transitive infrastructure, so challenger on judgment; watch:
quiet since 2025-09) and justhtml (67.8K/mo, 1.1K stars in two
years — trajectory judgment on a young pure-Python HTML5 parser)
challengers.
Removed:
- html-to-markdown — coordinated multi-entry self-promotion
(automatic-rejection rule): PyPI provenance verified to xberg-io,
the org's fourth planted entry overall. 1.5M downloads/month is
real but the rule stands.
- pyquery — 2.2M downloads/month and an active repo (pushed
2026-07); editorial drop at cap: the jQuery-style API is the
least-reached-for of the keeps. Judgment call.
- tinycss2 — 110.5M downloads/month is transitive (weasyprint
declares it a hard dependency, verified in PyPI metadata) against
190 stars; a CSS parser mis-homed in an HTML/XML section with no
better home. Judgment call.
Co-Authored-By: Claude <noreply@anthropic.com>
The industry's fuzzy string matching answer (web-verified: the
production recommendation over thefuzz — same API, MIT license, C++
speed — and preferred over textdistance for string metrics). 181.7M
downloads/month (pepy), 4.1K stars, pushed 2026-08. Sole obvious
choice; the subcategory label rides this commit so it is never empty,
completing the displacement of textdistance.
Co-Authored-By: Claude <noreply@anthropic.com>
The ecosystem's default encoding detector — requests switched to it
in 2021 and 2026 guidance names it the choice for new projects
(web-verified). 1.73B downloads/month (pepy; heavily
requests-transitive, but default-status is the point), pushed
2026-08. Co-obvious with chardet, which retains a verified accuracy
claim — the PyQt/PySide pair shape.
Co-Authored-By: Claude <noreply@anthropic.com>
Restructure: the 10-entry General grab-bag dissolves — Encoding and
Unicode (chardet 224.1M/mo obvious choice, joined by
charset-normalizer next commit; ftfy 14.4M/mo kept as the fifth
mature-stable past-line keep, repo and release both 2024-10),
Internationalization (babel 135.2M/mo sole), Transliteration and
Slugs (python-slugify 87.7M/mo, unidecode 31.8M/mo), and a residual
General (difflib stdlib-first, pyfiglet 6.2M/mo judgment keep).
pypinyin (1.9M/mo) and pangu.py (14.9K/mo as PyPI pangu — display
name kept by explicit maintainer word, the second deliberate naming
exception after pytorch; kept on sole-tool judgment for CJK spacing)
re-home to Natural Language Processing > Chinese as challengers
beside jieba. Parser re-tiers: pygments (1.25B/mo), pyparsing
(422.3M/mo), sqlparse (146.8M/mo) obvious choices; phonenumbers
(renamed from python-phonenumbers, 39.4M/mo) and parsy (4M/mo)
challengers. Unique identifiers reorders to shortuuid then sqids.
Removed:
- textdistance — last release 2024-07 (25 months) and repo quiet
since 2025-04, past the 12-month line; displaced by rapidfuzz
(181.7M/mo vs 2.5M), entering in its own commit.
- python-nameparser — 3.3M downloads/month (as nameparser) and an
active repo; editorial drop at cap: the domain-parser class is
trimmed to the giant, phonenumbers. Judgment call.
- python-user-agents — repo quiet since 2023-02, three and a half
years past the 12-month line.
- tree-sitter-language-pack — coordinated multi-entry self-promotion
(automatic-rejection rule): PyPI provenance verified to xberg-io,
the org that previously planted xberg and liter-llm. 6.6M/mo is
real but the rule stands; its sibling drops from HTML Manipulation.
Co-Authored-By: Claude <noreply@anthropic.com>
No removals. General tiers: opencv-python (renamed from opencv to the
canonical pip package this entry already linked; 55.9M/mo) and
ultralytics (8.4M/mo, 60.7K stars) obvious choices; kornia (3.1M/mo)
and fiftyone (253.7K/mo — dataset tooling rather than a vision
algorithm library, kept as the unprompted answer for that adjacent
job) challengers. OCR minted as a distinct job: pytesseract (24M/mo)
and easyocr (3.6M/mo, quiet since 2025-12 — watch) obvious choices.
Co-Authored-By: Claude <noreply@anthropic.com>
General tiers: nltk (71.4M/mo), spacy (25.4M/mo) obvious choices;
gensim (6M/mo, quiet since 2025-11 — watch) and stanza (1.1M/mo)
challengers. Chinese: jieba kept as mature-stable past the 12-month
activity line (repo quiet since 2024-08, last release 0.42.1 in
2020-01) on the sortedcontainers precedent — the fourth such keep:
3.3M downloads/month, 35.1K stars, still the Chinese segmentation
answer with no successor.
Removed:
- funnlp — three independent grounds: a link-collection rather than a
library; repo quiet since 2024-05, past the 12-month line; 55
downloads/month. Its 82.5K stars measure the bookmark, not a tool.
Co-Authored-By: Claude <noreply@anthropic.com>
Restructure: the 12-entry flat section splits into General
(scikit-learn 234.7M/mo obvious choice; pgmpy 843.7K/mo and
feature-engine — renamed from feature_engine to its canonical PyPI
name, 297.1K/mo — challengers), Gradient Boosting (xgboost 52M/mo,
lightgbm 26.5M/mo, catboost 6.3M/mo, all obvious choices; lightgbm's
lightgbm-org link verified current — microsoft/LightGBM redirects
there), and Time Series Forecasting (timesfm sole — a foundation
model judged by ecosystem adoption, 285K/mo and 27.6K stars; prophet
and darts are named absences, deliberately not added this sitting).
Removed:
- h2o — 215.1K downloads/month, 7.5K stars, and the repo is active;
the drop is purely editorial: no longer anyone's unprompted answer
against scikit-learn and the boosting trio. Judgment call.
- mindsdb — the linked repo redirects to mindsdb/mindshub, a "models
workspace"; the AI-layer-for-databases product this entry described
no longer exists (verified). 23.9K downloads/month.
- scikit-lego — 72.5K downloads/month, 1.4K stars; a grab-bag of
sklearn extras that never became an unprompted answer. Judgment.
- TabGAN — 574 stars, 2.3K downloads/month. Nowhere near the bar.
- spark.ml — duplicate in all but name: pyspark is already listed in
the audited DevOps group, same repo, same pip install. Structural.
Co-Authored-By: Claude <noreply@anthropic.com>
The RL environments standard: community successor to OpenAI Gym
(unmaintained since 2022; few maintained RL libraries still support
old Gym — web-verified). 6.5M downloads/month (pepy), 12.3K stars,
pushed 2026-08. Obvious choice beside stable-baselines3, ordering
first by downloads.
Co-Authored-By: Claude <noreply@anthropic.com>
No removals. Frameworks tiers: pytorch (96.6M/mo as PyPI torch — the
display name stays pytorch by explicit maintainer word, a deliberate
exception to the naming convention; the bare pytorch PyPI package is
a squatting placeholder), tensorflow (19.2M/mo — production incumbent,
flagged as a Second Tier demotion candidate for the next audit), keras
(18.6M/mo, backend-agnostic since Keras 3) obvious choices; jax
(21.8M/mo, TPU/performance trajectory) and pytorch-lightning
(11M/mo) challengers. Landscape verified: PyTorch is the 2026 default
with 85% research share.
stable-baselines3 moves into the minted Reinforcement Learning
subcategory — RL is a distinct job; gymnasium joins it next commit.
Co-Authored-By: Claude <noreply@anthropic.com>
Maintainer challenge upheld: Odoo is a ready-made web application
platform you extend, the sibling concept of CMS and Admin Panels —
so the section belongs beside them, not in the Other grab-bag (its
first placement was inertia from tryton's Miscellaneous home). TOC
and body both move; the group's section tail stays alphabetical
(Admin Panels, CMS, ERP, Static Site Generators).
Co-Authored-By: Claude <noreply@anthropic.com>
The Python ERP by adoption: about 7M users across editions, 50+ app
modules, 53.7K stars, pushed daily (web-verified). Not pip-distributed
— the PyPI odoo package is a dateless placeholder — so no download
signal; judged by ecosystem and displayed by repository name (renpy
precedent). Sole obvious choice.
Second structure override of decision 18 by maintainer word (Supply
Chain Security precedent): ERP lands as a new section in the Other
group rather than a slot in the Miscellaneous grab-bag, replacing the
dropped tryton. TOC line, heading, and description ride this commit.
Co-Authored-By: Claude <noreply@anthropic.com>
Restructure: itsdangerous moves to Security > Cryptography as a
challenger — HMAC-based data signing fits "cryptographic primitives
and secure protocols" better than the grab-bag. Kept past the
12-month activity line (repo quiet since 2025-06, last release
2024-04) as mature-stable on the sortedcontainers precedent: 222.8M
downloads/month, the signing answer, no successor. Miscellaneous
keeps blinker (192.2M/mo) and boltons (26.5M/mo) as obvious choices.
Removed:
- tryton — 10.9K downloads/month, and that PyPI package is the
desktop client (the framework server is trytond); the linked GitHub
repo is a self-described 216-star mirror; and the ERP obvious
choice by adoption is Odoo (~7M users vs hundreds-to-thousands of
Tryton deployments, web-verified), which enters in the next commit.
Co-Authored-By: Claude <noreply@anthropic.com>
Tiers: bleak (2.5M/mo) and pynput (2.2M/mo) obvious choices;
jumpstarter (1.5K/mo, 211 stars, created 2026-01) kept as a
challenger by explicit maintainer flip against the seeded drop.
Removed:
- synology-api — 579 stars, 14.5K downloads/month; a single-vendor
NAS API wrapper, not an obvious choice for any hardware job a
general reader has. Judgment call.
Co-Authored-By: Claude <noreply@anthropic.com>
Maintainer-proposed during the Security sitting: uv's built-in
vulnerability and malware scanning (announced 2026-06, OSV-backed,
4-10x faster than pip-audit on typical projects). Enters as a
no-signal challenger behind pip-audit — not a package, so this is a
subcommand pointer entry linking the CLI docs (httpx.URL precedent).
Astral marks the feature preview/unstable; kept by explicit maintainer
override of the production-ready quality bar — the first stability
override. The description carries the preview label.
Co-Authored-By: Claude <noreply@anthropic.com>
The PyPA-official dependency vulnerability scanner: 30.9M
downloads/month (pepy; largely CI traffic, which is the use case),
1.3K stars, pushed 2026-08. Verified 2026 guidance names it the free
baseline over the older commercial safety. Sole obvious choice.
This mints the reform's first new section — an explicit maintainer
override of decision 18 (all minted use cases are subcategories),
accepted in the audit preview. TOC line, heading, and description
ride this commit per the Build Backends pattern; placed alphabetically
in the Security group.
Co-Authored-By: Claude <noreply@anthropic.com>
No removals in either section.
Cryptography: adds the missing italic section description; reorders to
downloads — cryptography (1.48B/mo), pynacl (241.7M/mo), paramiko
(155.4M/mo; SSH kept here as secure-protocols-adjacent rather than
minting a sole-entry use case) — all obvious choices.
Penetration Testing: tiers mitmproxy (10.8M/mo) and sqlmap (official
PyPI package verified, 65.3K/mo under-measures git-based usage; 38.2K
stars) obvious choices; sherlock-project (renamed from sherlock — the
bare PyPI name is an unrelated distributed-lock library; 115.9K/mo,
89.6K stars) and social-engineer-toolkit (renamed from setoolkit —
no PyPI package, so the naming convention falls back to the repository
name; no download signal, judged by ecosystem standing) challengers.
Co-Authored-By: Claude <noreply@anthropic.com>
Maintainer-approved batch: gtts → gTTS, twisted → Twisted, cython →
Cython, per the naming convention (display name = canonical PyPI
package name, verified via the PyPI JSON API). All three were caught
post-commit in earlier sittings and parked awaiting explicit word.
Co-Authored-By: Claude <noreply@anthropic.com>
Maintainer-adjudicated close of the standing flag from the Developer
Tools sitting: pre-commit is developer-workflow tooling (a git-hook
framework orchestrating linters), not ops — it leaves the DevOps
Tools > Other grab-bag for a minted sole-entry Git Hooks subcategory
in Code Analysis. Placement avoids stretching the Linters and
Formatters cap override (already 6 by maintainer word). No additions
or removals — a pure re-home.
Co-Authored-By: Claude <noreply@anthropic.com>
Displacement of the dropped python-decouple: same job — settings from
environment variables and files — done with validation and types on
the pydantic ecosystem's momentum. 495M downloads/month (pepy), pushed
2026-08. Obvious choice, ordering after python-dotenv.
Co-Authored-By: Claude <noreply@anthropic.com>
Tiers: configparser (stdlib, leads the use case under the stdlib-first
ordering rule), python-dotenv (782.2M/mo) obvious choices —
pydantic-settings joins them in its own addition commit; hydra-core
(23.8M/mo — renamed from hydra to its canonical PyPI name; the cache's
bare hydra row is an ancient unrelated package; link updated to
hydra-ecosystem/hydra, where the facebookresearch repo now redirects,
target verified by description) and dynaconf (6.8M/mo) challengers.
Removed:
- python-decouple — repo dormant since 2024-11, last release 3.8 in
2023-03, three and a half years past any release and past the
12-month activity line. 8.4M downloads/month, 3.0K stars.
Displaced by pydantic-settings (495M/mo) entering next.
Co-Authored-By: Claude <noreply@anthropic.com>
Maintainer-directed restructure: instead of dropping pyarmor as
mis-homed, an Obfuscation subcategory is minted for it (sole obvious
choice — 501.5K/mo, 5.2K stars, pushed 2026-08); code obfuscation is a
distinct job from building executables. Executables tiers: pyinstaller
(13.1M/mo), Nuitka (512K/mo) obvious choices; shiv (487.3K/mo),
cx-Freeze (221K/mo) challengers. No removals.
Co-Authored-By: Claude <noreply@anthropic.com>
Challenger: uv's own backend at 26.5M downloads/month (pepy) within a
year of release, riding uv's adoption trajectory. Deferred by the
maintainer from the Developer Tools sitting; this closes that agenda
item.
Co-Authored-By: Claude <noreply@anthropic.com>
The modern default backend — PyPA docs and project templates reach for
it: 507M downloads/month (pepy), pushed 2026-08. Obvious choice
alongside setuptools; ordering after it by downloads.
Co-Authored-By: Claude <noreply@anthropic.com>
Mints the Build Backends subcategory — the deferred agenda item from
the Developer Tools sitting (2026-08-16), landing in its designated
Python Toolchain slot. setuptools is the incumbent obvious choice:
1.51B downloads/month (pepy), half the ecosystem still builds with it,
pushed 2026-08.
Co-Authored-By: Claude <noreply@anthropic.com>
Restructure: the flat section becomes two subcategories — Package
Managers (this commit) and Build Backends (entering next as three
addition commits; the pyproject build-backend choice is a distinct job
from installing packages).
Package Managers tiers: pip (689.4M/mo), uv (194.1M/mo, the 2026
default recommendation for new projects), poetry (79M/mo) obvious
choices; hatch (22.2M/mo — kept by explicit maintainer flip against
the seeded drop), pipx (7.1M/mo, Second Tier — uv tool covers the job
for uv users), conda (no pip signal, the data-science distribution
standard; sorts last) challengers. The use case holds 6 entries by
explicit maintainer cap override — the list's third, same 3 obvious
choices + 3 challengers shape as Linters and Async I/O.
No removals.
Co-Authored-By: Claude <noreply@anthropic.com>
Tiers: virtualenv (545.7M/mo, much of it transitive via pip and tox),
uv (194.1M/mo, dual-listed here and in Package Managers by maintainer
acceptance), pyenv (no pip signal — distributed via git and brew;
45.0K stars) all obvious choices. pyenv-win converts to an indented
sub-item under pyenv (the flower/celery companion pattern — its job is
inseparable from its parent's), freeing a slot without losing the
pointer.
Removed:
- KillPy — 124 stars, created 2025, 3.7K downloads/month; nowhere
near obvious-choice or challenger territory.
Co-Authored-By: Claude <noreply@anthropic.com>
Maintainer correction to the previous amendment: stdlib sorts at the
top of the whole use case, not merely first within its tier. No README
movement results — the stdlib admission rule (a standard-library
module is listed only where it is itself the obvious choice) means
every stdlib entry already sits in the first tier, so tier-top and
use-case-top coincide; the rule text now states the intent directly.
Co-Authored-By: Claude <noreply@anthropic.com>