Skip to content

~45 public attributes are missing from their package __all__, invisible to star-import and to the export-integrity tests #533

Description

@JarryShaw

Summary

Roughly 45 public attributes across about 12 non-aggregator packages are absent from their package's __all__, so they are invisible to from <package> import * — and invisible to the export-integrity assertions added in #527.

Surfaced during the review of #527 and deliberately not folded into it: that PR fixes __all__ entries that name nothing (a hard AttributeError on star-import), whereas this is the inverse — real attributes that no __all__ names. Different defect, different blast radius, and folding it in would have turned a targeted fix into a wide API change inside an unrelated review.

Why the existing tests do not catch it

#527 adds a contract test over __all__, and its assertions are all of the form "every name in __all__ resolves". That is one direction only. An attribute that exists but is unlisted satisfies every one of them — the sweep has nothing to compare against, because __all__ is the input rather than the expectation.

The test's own docstring discloses this scoping, so the gap is documented rather than hidden. This issue is the follow-up it implies.

Why it is not obviously a bug

Omission from __all__ can be deliberate — it is the ordinary way to mark something as not-part-of-the-public-API while leaving it importable by path. So the 45 are a mix of genuine oversights and intentional exclusions, and the work here is triage rather than a mechanical fix:

  • decide, per package, whether each unlisted public attribute is meant to be public
  • add the genuinely public ones to __all__
  • for the intentional exclusions, consider whether a leading underscore would express the intent better than silence, since silence is indistinguishable from an oversight

The count of 45 is the reviewer's measurement and has not been independently re-derived. Re-measure before acting on it, and note the figure will move as #527 lands.

Suggested direction

A second contract assertion in the other direction — every public attribute of a package appears in its __all__, with an explicit allowlist for deliberate exclusions. That makes the intent reviewable instead of implicit, and it fails loudly when someone adds a public name and forgets the export. The allowlist is the load-bearing part: without it the assertion is unsatisfiable, and with it every exclusion becomes a decision somebody wrote down.

Notes

Aggregator packages are excluded from the count — they re-export by design and #527 already asserts their completeness separately.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementIssues requesting a new capability (set by the feature request template)

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions