GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — fix(pypi): resolve name and version for PEP 658 metadata sidecars by wickedOne · Pull Request #222 · git-pkgs/proxy

Conversation

@wickedOne

@wickedOne wickedOne commented Jul 30, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

hi,

i was experiencing this while caching pypi dependencies

image

once again i left the fix to claude (opus), but please challenge me if you have any questions

Problem

PyPI packages sometimes appear in the package overview under a synthetic name like pkg:pypi/_hash_164a211cb654c0d4@0.

These are PEP 658/714 core-metadata sidecar files. When an index advertises data-core-metadata (simple API) or core-metadata (JSON API) for a file, pip fetches .metadata to resolve dependencies without downloading the full wheel. parseFilename only recognised .whl and four sdist extensions, so foo-1.2.0-py3-none-any.whl.metadata matched none of them and returned an empty name. handleDownload then fell back to a hash-derived identifier:

name = fmt.Sprintf("_hash_%s", hashPath(path))
version = "0"

Reproduced against the reported entry — hashPath of the request path for backports_asyncio_runner-1.2.0-py3-none-any.whl.metadata yields exactly 164a211cb654c0d4.

It looks intermittent because the sidecar fetch depends on the index advertising core metadata per-file and pip choosing metadata-only resolution. For backports_asyncio_runner 1.2.0, upstream advertises core metadata on the wheel but not the sdist.

Changes

  • Strip the .metadata suffix before parsing, so sidecars resolve to the distribution they describe. This is the actual fix.
  • Parse wheels per PEP 427 using the spec-guaranteed field positions instead of scanning for a python tag. The name and version fields have hyphens escaped to _, so parts[0]/parts[1] are authoritative. Fixes build-tagged wheels: foo-1.0-1-py3-none-any.whl previously parsed as name foo-1.0, version 1. Removes the now-unused isPythonTag.
  • Recognise more distribution formats — .tar.xz, .tar.Z, .tgz as sdist archives, and .egg/.exe/.msi as tagged formats. All previously hit the same hash fallback. The legacy bdists use the first-two-fields path deliberately: under the sdist heuristic, numpy-1.8.0-py2.7-macosx-10.9-x86_64.egg would parse as name numpy-1.8.0-py2.7-macosx, version 10.9-x86_64.

Testing

  • Extended TestPyPIParseFilename with sidecars, build-tagged wheels, the new extensions, and legacy bdists.
  • Added TestPyPIParseFilenameNoHashFallback, asserting the three real backports_asyncio_runner filenames all resolve to the same name/version — the property whose failure produces the bogus PURLs.
  • go build ./... && go vet ./... && go test ./... pass; gofmt clean.

Note

This stops new hash* entries from being created but does not clean up existing ones. The cache is keyed on (package PURL, version PURL, filename), so already-cached sidecars keep their old identity and remain visible in the overview until purged.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@andrew
andrew requested a review from Copilot July 31, 2026 09:18
Copilot started reviewing on behalf of andrew July 31, 2026 09:18
View session
Copilot AI reviewed Jul 31, 2026
View reviewed changes

Copilot AI left a comment

Copy link
Copy Markdown

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes PyPI filename parsing so PEP 658/714 core-metadata sidecar downloads (*.metadata) resolve to the correct package name/version instead of creating synthetic _hash_*@0 identifiers, improving cache key stability and package overview correctness.

Changes:

  • Strip the .metadata suffix before parsing distribution filenames (PEP 658/714 sidecars).
  • Rework wheel parsing to use spec-guaranteed field positions (PEP 427), correctly handling build-tagged wheels.
  • Expand recognized distribution extensions (more sdist archives + legacy bdists) and extend unit tests accordingly.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
internal/handler/pypi.go Updates parseFilename to handle .metadata sidecars and broaden filename parsing across more PyPI distribution formats.
internal/handler/pypi_test.go Extends TestPyPIParseFilename and adds a regression test to prevent _hash_* fallback for sidecars.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread internal/handler/pypi_test.go Outdated
Comment on lines +50 to +53
// Legacy bdist formats
{"numpy-1.8.0-py2.7-macosx-10.9-x86_64.egg", "numpy", "1.8.0"},
{"pywin32-223.win32-py2.7.exe", "pywin32", "223.win32"},

Comment thread internal/handler/pypi.go Outdated
Comment on lines 473 to 482
for _, format := range taggedExtensions {
if !strings.HasSuffix(filename, format.ext) {
continue
}
parts := strings.Split(strings.TrimSuffix(filename, format.ext), "-")
if len(parts) < format.minParts {
return "", ""
}
return parts[0], parts[1]
}
andrew
andrew requested changes Jul 31, 2026
View reviewed changes

@andrew andrew left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new .exe handling parses Windows installer filenames incorrectly. For foo-1.0.win32-py2.0.exe, parseFilename returns version 1.0.win32, but win32 is the platform and the version is 1.0. The pywin32 test currently codifies the same error. Please parse Windows installers separately or remove .exe support, and add a regression test using the documented filename form.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@wickedOne
resolve name and version for PEP 658 metadata sidecars
4083718
@wickedOne
wickedOne force-pushed the pypi-fix branch from f746e7d to 4083718 Compare August 1, 2026 13:41
@wickedOne @claude
fix(pypi): parse Windows installer and egg filenames separately
780e53f
The bdist_wininst and bdist_msi layout joins the platform to the version
with a '.' rather than a '-', so treating .exe/.msi like a wheel folded
the platform into the version: foo-1.0.win32-py2.0.exe resolved to
version "1.0.win32". Eggs shared the problem, as setuptools' hyphen
escaping is not universal: aws-sdk-1.0.0-py3.11.egg resolved to name
"aws", version "sdk".

Give each format its own parser. Wheels keep the PEP 427
spec-guaranteed field positions, eggs locate the version relative to the
py{X.Y} interpreter field, and Windows installers strip the platform and
interpreter fields before splitting name from version.

A PEP 658 sidecar resolves to the same name and version as the
distribution it describes, so it is cached under that version. Browse and
compare took the first cached artifact without checking its extension,
handing openArchive plain text: a version pip had only fetched metadata
for reported hasCached and then 500'd.

Add firstBrowsableArtifact, replacing five duplicated selection loops,
and export PyPIMetadataSuffix so the suffix has a single definition.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
@wickedOne

wickedOne commented Aug 1, 2026

Copy link
Copy Markdown
Contributor Author

according to claude all issues have been addressed...

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@wickedOne
wickedOne requested a review from andrew August 1, 2026 16:55
andrew
andrew approved these changes Aug 3, 2026
View reviewed changes
@andrew
andrew merged commit 63f0efd into git-pkgs:main Aug 3, 2026
5 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@wickedOne
wickedOne deleted the pypi-fix branch August 3, 2026 19:07
@wickedOne

wickedOne commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

@andrew is there a way we can get a release?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@andrew

andrew commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

@wickedOne yep I'll get a release out shortly

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@andrew

andrew commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Oh, actions is broken, may have to wait until tomorrow.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@andrew

andrew commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

https://github.com/git-pkgs/proxy/releases/tag/v0.6.1

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@wickedOne

wickedOne commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

you're my hero! thanks

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

Copilot code review Copilot
Copilot review effort
Applies to this pull request for everyone.Learn more about Copilot code review.
Copilot left review comments
@andrew andrew andrew approved these changes

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

3 participants

@wickedOne @andrew
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.