Skip to content

fix(packaging): declare Python 3.14 and guard the classifiers in CI - #200

Merged
luk384090-cloud merged 1 commit into
mainfrom
dev/issues-9-1
Sep 17, 2026
Merged

luk384090-cloud merged 1 commit into
mainfrom
dev/issues-9-1

Conversation

@lzsweb

@lzsweb lzsweb commented Sep 17, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Add the missing Programming Language :: Python :: 3.14 classifier and 3.14 to the CI test matrix. 3.14 already carries 3.11% of PyPI downloads (5.7% back in June), so pip install dashscope was reporting no support for an interpreter a material slice of users are actually on.
  • Make the gap unable to reopen at 3.15: tests/unit/test_packaging_metadata.py now fails when a version carrying >=1% of downloads has no classifier, when the declared versions have a hole in them, when the matrix tests something setup.py does not claim, or when the python_requires floor sits above the lowest classifier.
  • Ignore scripts/, which holds local PyPI investigation tooling that is deliberately not shipped.

The guard lives in the existing unit-test job rather than a separate script and CI job, so it runs on every pull request with nothing extra to keep in sync — PyYAML>=6.0 is already in requirements-test.txt. Only one matrix interpreter queries pypistats, because four parallel requests invite a 429 that would skip the very check it is meant to run, and an unreachable pypistats degrades to a skip rather than a failure. A rate limit is not a packaging defect and must not be able to turn CI red.

Why this is a packaging fix and not a performance fix

The originating report was that Python 3.12 install success had been driving download volume since 8/17. Investigated locally, it had not:

  • pypistats counts successful CDN file downloads, so a failure during install never suppresses a count. Only a resolver refusing the requirement outright does — and sweeping the last 8 releases (1.26.6 -> 1.27.5) x Pythons 3.8-3.13 x every published extra against a historically accurate PyPI snapshot resolves 303/303. There was never a 3.12 resolution failure to fix.
  • The 8/17-8/25 movement is a PyPI log-export change, not a release effect. Four independent series step down on 2026-08-25 (dashscope Darwin -46%, Windows -54%; modelscope Darwin -51%, Windows -52%), with no release from either package. Normalizing against the control, dashscope's Linux position actually improved through the break: ds/ms ratio 0.617 (w/o 8/31) -> 0.780 (9/7) -> 1.050 (9/14).
  • The 3.11 surge near 8/17 is a three-day platform-wide batch event (peak 7.4x, excess 293,318, weekend/weekday ratio 0.91) with modelscope spiking 4.72x on the same days. It temporarily knocked 3.12's share of 3.11+3.12 from 84.7% to 48.1%; that share is back to 88.5%.
  • The one genuinely dashscope-specific burst, 6/17-6/26, is an external consumer rather than an SDK change: +1,117,026 excess downloads that are 100.4% Linux and 99.1% Python 3.12, with every other version flat (3.11 1.12x, 3.10 1.01x, 3.13 1.05x), peaking on Sat 6/20 and Sun 6/21 while modelscope fell those days. openai moved 1.08x over the same window, ruling out a base-image refresh. Onset 6/15 precedes 1.25.22 (6/16) and offset 6/27 has no adjacent release.

So the only actionable defect was the undeclared 3.14 support, which is what this PR fixes. The resolution-matrix and download-analysis tooling used to reach that conclusion stays local under the now-ignored scripts/.

Test plan

  • python -m pytest tests/unit -q -> 800 passed, 7 skipped
  • pre-commit run --files on all 4 changed files -> all hooks pass
  • Live pypistats path exercised directly: shares resolve (3.12 61.82%, 3.11 24.27%, 3.13 5.90%, 3.10 3.77%, 3.14 3.11%, 3.9 0.49%) and the audit returns no violations
  • ci_versions() reads the matrix as ['3.9', '3.12', '3.13', '3.14']
  • Confirm the test (ubuntu-latest, 3.14) job goes green on this PR's own CI run

3.14 already carries 3.11% of PyPI downloads -- 5.7% back in June -- but had
no classifier, so `pip install dashscope` reported no support for an
interpreter a material slice of users are actually on. Adding the classifier
alone would let the same gap reopen at 3.15, so the unit-test job now also
fails when a version carrying >=1% of downloads is undeclared, when the
declared versions have a hole in them, when the matrix tests something
setup.py does not claim, or when the python_requires floor sits above the
lowest classifier.

The guard lives in tests/unit/test_packaging_metadata.py rather than a
separate script and CI job, so it runs on every pull request with nothing
extra to keep in sync; PyYAML is already in requirements-test.txt. Only one
matrix interpreter queries pypistats, because four parallel requests invite a
429 that would skip the very check it is meant to run, and an unreachable
pypistats degrades to a skip rather than a failure -- a rate limit is not a
packaging defect.

scripts/ holds local PyPI investigation tooling that is deliberately not
shipped, so it is ignored.
@lzsweb lzsweb changed the title fix(packaging): declare Python 3.14 and add PyPI analysis tooling fix(packaging): declare Python 3.14 and guard the classifiers in CI Sep 17, 2026
@luk384090-cloud
luk384090-cloud merged commit fde7be5 into main Sep 17, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants