GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — Prefer valid distributions when collecting entry points by jaraco · Pull Request #553 · python/importlib_metadata Conversation
|
| benchmark | before | after |
|---|---|---|
entry_points() |
1.53 msec | 2.03 msec (+29%) |
discovery |
138 µsec | 15.5 µsec (−89%) |
cached distribution |
138 µsec | 15.6 µsec (−89%) |
uncached distribution |
236 µsec | 107 µsec (−55%) |
localize.dist passes a provider's own Distribution subclass through unadapted (#486), so it has no _has_metadata and test_conforming_provider_is_not_warned_about caught that directly.
Nothing on IDistribution is as cheap for those: locate_file returns a SimplePath, which does have exists(), but it resolves against the package root rather than the metadata, so locate_file('METADATA') names site-packages/METADATA. Every other member loads the metadata or parses it. So Distribution._has_metadata() reads, through a _metadata_text that metadata shares so neither names the files twice, and PathDistribution overrides it with the detection above. The predicate is _safe_has_metadata, which falls back for a distribution supplying neither helper.
That turns out to fix something pre-existing. Asking such a distribution for metadata raises importlib.metadata.MetadataNotFound, a different class from this package's, so it escaped ExceptionTrap(MetadataNotFound) on main and propagated out of from_name instead of marking the distribution invalid. test_dist_without_metadata_is_deferred covers it.
test_entry_points_from_valid_dist — fails before the fix with assert set() == {'ep'}. It brackets the valid distribution between two invalid ones, as test_valid_dists_preferred does, so that no file system lists it first.test_invalid_dists_deferred — the invalid distributions are moved to the end, not dropped.test_dist_without_metadata_is_deferred — the foreign-MetadataNotFound case above.tox passes on each commit separately: 260 passed, 1 skipped, 41 subtests; mypy and ruff clean.
🤖 Generated with Claude Code
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
64141d1 to
6a39aee
Compare
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
f8fa1c2 to
86e2d3a
Compare
| return distribution(distribution_name).version | ||
|
|
||
|
|
||
| def _metadata_text(dist: IDistribution) -> str | None: |
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Can this be an instance method?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Yes — _metadata_text is now Distribution._metadata_text(self), and metadata calls self._metadata_text().
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| """ | ||
| with suppress(AttributeError): | ||
| return dist._has_metadata # type: ignore[attr-defined] | ||
| return bool(_metadata_text(dist)) |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
What about instead having Distribution._has_metadata(), supplying the default behavior, have it overridden in PathDistribution, then this function is _safe_has_metadata, which suppresses the AttributeError for IDistributions not derived from Distribution?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Done, that reads better. Distribution._has_metadata() supplies the default, PathDistribution overrides it with the detection, and the predicate is _safe_has_metadata.
One wrinkle worth knowing: the fallback cannot be Distribution._has_metadata(dist), because its body is self._metadata_text(), which dispatches on the instance again and a foreign distribution has no _metadata_text either — test_conforming_provider_is_not_warned_about failed on exactly that. So the fallback is bool(Distribution._metadata_text(dist)), unbound, which needs nothing of the distribution beyond read_text.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
86e2d3a to
eba46e3
Compare
|
I think this is ready to go. I'm going to sleep on it before merging. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
On second thought, let's get it out; we can iterate later if needed. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
`_prefer_valid` decided validity by consulting `metadata`, which runs the whole METADATA file through the email parser only for the result to be discarded. Give `Distribution` a `_has_metadata` that reads no further than the text, through a `_metadata_text` that `metadata` shares so neither names the files twice, and override it in `PathDistribution` to detect the metadata file without opening it at all. An old-style egg-info file, which is itself the metadata, is detected with `is_file`; a metadata directory exists whether or not it holds anything, so its own presence says nothing. The predicate is `_safe_has_metadata`, since a provider's own `Distribution` subclass derives from `importlib.metadata` and is passed through unadapted (#486), so it supplies neither helper. Reading its metadata rather than asking it for `metadata` also closes a gap: the `MetadataNotFound` such a distribution raises is a different class from this package's, so it escaped the preference rather than marking the distribution invalid. Co-Authored-By: Claude Opus 5 <[email protected]>
Where an unclean upgrade leaves an empty metadata directory beside the valid one, `_unique` kept whichever the file system happened to list first, so the entry points of the valid distribution could go missing entirely. Closes #534. Co-Authored-By: Claude Opus 5 <[email protected]>
eba46e3 to
0aa24f3
Compare
There was an error while loading. Please reload this page.
|
Semi-related question: how often is importlib-metadata synced into python? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
entry_points doesn't handle empty .dist-info files well
There was an error while loading. Please reload this page.