Skip to content

fix(pypa-index): escape for href tag requires-python - #153

Merged
definfo merged 1 commit into
masterfrom
fix/pypa-index-spec
Sep 1, 2026
Merged

definfo merged 1 commit into
masterfrom
fix/pypa-index-spec

Conversation

@definfo

@definfo definfo commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Summary

The generated pytorch-wheels PyPA Simple indexes corrupt HTML-encoded requires-python values while parsing and re-rendering upstream PyTorch index pages.

Upstream PyTorch HTML:

data-requires-python=">=3.10"

Our generated HTML:

data-requires-python=">=3.10"

Our generated JSON:

"requires-python": ">=3.10"

After one HTML decoding pass, clients receive the literal string >=3.10 rather than >=3.10. This is not a valid Python version specifier.

For the live filelock index, all 170 entries carrying requires-python were affected.

Reproduction

Create a temporary project:

[project]
name = "pytorch-rewrite-check"
version = "0.0.0"
requires-python = ">=3.11"
dependencies = ["filelock==3.29.7"]

Run:

RUST_LOG=uv=debug uv lock -vv \
  --dry-run \
  --no-cache \
  --no-config \
  --default-index https://mirror.sjtu.edu.cn/pytorch-wheels/cpu/

Observed output:

Skipping file for filelock: Failed to parse `requires-python`: `>=3.10`
...
Because there is no version of filelock==3.29.7 ...

The version exists in the generated index, but uv discards it because its requires-python value is malformed.

Root cause

crates/pypa-simple/src/lib.rs::parse_anchors reads HTML attribute values from tl without decoding character references. render_project then HTML-escapes those already encoded strings again.

This affects data-requires-python, data-yanked reasons and query strings in href HTML tag.

The correct behavior is to decode HTML entities once when importing attributes into the internal model, then escape them once when serializing HTML.

Other routes

  • astral-wheels currently receives JSON-origin metadata and is unaffected in tested indexes: 8/8 requires-python values were valid >=3.10. The parser fix should nevertheless cover any HTML-origin Astral pages.
  • /pypi/web/simple proxies upstream HTML without parsing/re-rendering it and preserves requires-python correctly.
  • /pypi-packages is an artifact route, not an index, and does not itself carry requires-python.

@definfo
definfo enabled auto-merge (rebase) September 1, 2026 08:12
@definfo
definfo merged commit 730f01c into master Sep 1, 2026
1 check passed
@definfo
definfo deleted the fix/pypa-index-spec branch September 1, 2026 08:24
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.

1 participant