Skip to content

Hold the package to the promises it already makes - #4

Merged
neosergio merged 1 commit into
mainfrom
chore/tighten-test-typing
Jul 13, 2026
Merged

neosergio merged 1 commit into
mainfrom
chore/tighten-test-typing

Conversation

@neosergio

@neosergio neosergio commented Jul 13, 2026 •

Copy link
Copy Markdown
Owner

Three guards, all for claims compactref makes and nothing checked.

The package ships py.typed, and that file is the whole of the promise: it is what tells a downstream mypy the annotations are real. twine validates metadata, not contents, and passes a wheel missing it without a word. Losing it does not fail loudly either -- mypy stops analyzing compactref, falls back to Any, and a project with ignore_missing_imports set, which is most of them, reports "Success: no issues found" on code calling generate_reference with a list. The hints are gone and nothing says so.

So CI installs the built wheel where there is no source tree to fall back on, makes it produce a reference, and makes mypy reject a call the annotations forbid. That check is run with --ignore-missing-imports and greps for the arg-type diagnostic by name: a non-zero exit does not distinguish "rejected the bad call" from "could not read the module at all", and written the obvious way the check passed against a wheel with py.typed stripped out -- the exact wheel it exists to reject. Both directions are tested now.

Warnings are errors under pytest. The package has no runtime dependencies, so a warning during a test run is either this code or the standard library deprecating something out from under it. random-address was one importlib.abc import away from a broken 3.14 job with the DeprecationWarning sitting unread in the pytest output; the same trap was open here.

The parametrized source in the 0.1.0 compatibility test was typed object, which is not what generate_reference accepts, so the call needed a type: ignore to get past mypy. SourceIdentifier is exported for exactly this. The test now checks the signature it exercises rather than opting out of it. The one remaining suppression stays: test_rejects_unsupported_source_type passes a list on purpose to prove the TypeError.

Summary by CodeRabbit

  • Documentation

    • Added requirements, changelog, and contribution information to the README.
    • Added a step-by-step release and publishing guide.
    • Added a link to the project changelog in package metadata.
  • Quality Improvements

    • Enhanced package verification to test installed wheels and bundled type hints.
    • Added support for validating publishing setup against PyPI or Test PyPI.
    • Configured warnings to fail automated tests.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@neosergio, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 28 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: df3ed42e-b1e4-4c0e-9384-c01a2decff4c

📥 Commits

Reviewing files that changed from the base of the PR and between 3061bcb and b7e0643.

📒 Files selected for processing (6)
  • .github/workflows/ci.yml
  • .github/workflows/verify-publish.yml
  • README.md
  • RELEASING.md
  • pyproject.toml
  • tests/test_core.py
📝 Walkthrough

Walkthrough

The changes strengthen wheel runtime and type-hint validation, parameterize Trusted Publisher verification for PyPI and TestPyPI, add release and contribution documentation, expose changelog metadata, and tighten pytest warning handling and test typing.

Changes

Package validation

Layer / File(s) Summary
Wheel installation and type validation
.github/workflows/ci.yml, tests/test_core.py, pyproject.toml
CI installs the wheel in an isolated environment, checks generate_reference, and verifies shipped type hints with mypy. The related test uses SourceIdentifier, while pytest warnings now fail the run.

Trusted Publisher verification

Layer / File(s) Summary
Multi-index OIDC verification
.github/workflows/verify-publish.yml
Manual workflow runs can target PyPI or TestPyPI, dynamically obtain the target audience, and display environment-specific OIDC claims.

Release documentation and metadata

Layer / File(s) Summary
Project metadata and requirements
pyproject.toml, README.md
Project metadata links to the changelog, and README requirements document Python 3.10+ and no runtime dependencies.
Release and contribution guidance
README.md, RELEASING.md
Documentation adds changelog and contribution guidance plus versioning, CI, TestPyPI, Trusted Publishing, release, and troubleshooting procedures.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant WorkflowInput
  participant GitHubActions
  participant PackageIndex
  participant GitHubOIDC
  WorkflowInput->>GitHubActions: select publishing environment
  GitHubActions->>PackageIndex: fetch environment-specific OIDC audience
  GitHubActions->>GitHubOIDC: request token with audience
  GitHubOIDC-->>GitHubActions: return claims
  GitHubActions-->>WorkflowInput: print selected-index claims
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is clearly related to the PR’s focus on enforcing the package’s documented runtime, typing, and release promises.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/tighten-test-typing

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@neosergio
neosergio force-pushed the chore/tighten-test-typing branch from be8fa11 to 3061bcb Compare July 13, 2026 15:40

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@RELEASING.md`:
- Around line 36-47: Update the “Verify publish setup” instructions in
RELEASING.md to require running the workflow for both targets: retain the `pypi`
verification and add the equivalent verification with `target=testpypi` before
the rehearsal. Ensure the steps clearly indicate each index’s publisher
configuration must be checked independently.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9840936f-6528-4e3f-9831-b36408d7d6a4

📥 Commits

Reviewing files that changed from the base of the PR and between 1fd0409 and 3061bcb.

📒 Files selected for processing (6)
  • .github/workflows/ci.yml
  • .github/workflows/verify-publish.yml
  • README.md
  • RELEASING.md
  • pyproject.toml
  • tests/test_core.py

Comment thread RELEASING.md Outdated
The package ships py.typed, and that file is the whole of the promise: it
is what tells a downstream mypy the annotations are real. twine validates
metadata, not contents, and passes a wheel missing it without a word.
Losing it does not fail loudly either -- mypy stops analyzing compactref,
falls back to Any, and a project with ignore_missing_imports set, which is
most of them, reports "Success: no issues found" on code calling
generate_reference with a list. The hints are gone and nothing says so.

So CI installs the built wheel where there is no source tree to fall back
on, makes it produce a reference, and makes mypy reject a call the
annotations forbid. That check is run with --ignore-missing-imports and
greps for the arg-type diagnostic by name: a non-zero exit does not
distinguish "rejected the bad call" from "could not read the module at
all", and written the obvious way the check passed against a wheel with
py.typed stripped out -- the exact wheel it exists to reject.

verify-publish could only ever check PyPI. The environment was hardcoded
and the OIDC token requested with audience=pypi, so the workflow written to
debug Trusted Publishing was structurally unable to debug the TestPyPI
publisher -- which is the one that failed. It takes the index as a dispatch
input now, runs in the matching environment, and reads each index's
audience from its own /_/oidc/audience endpoint rather than assuming.

RELEASING.md writes down what the workflows enforce but nobody could read:
the version lives in pyproject.toml and __version__ and both must match the
tag; publishing is triggered by a GitHub Release, not by a tag; rehearse on
TestPyPI first because PyPI versions are immutable; and the two indexes are
separate services whose publisher configs and environment claims do not
carry over. Verify publish setup is therefore run twice, once per index --
checking only PyPI leaves the rehearsal to fail on an unconfigured TestPyPI
publisher, and checking only TestPyPI leaves the same trap waiting on the
release, where it costs far more. The two workflows name that input
differently, `environment` and `target`, which the document now says out
loud rather than leaving to be discovered.

Warnings are errors under pytest. The package has no runtime dependencies,
so a warning during a test run is either this code or the standard library
deprecating something out from under it.

The README gains a changelog section, stating that 0.1.0 references still
resolve identically under 0.2.0, and a Changelog project URL so PyPI links
it in the sidebar. The 0.1.0 compatibility test now types its source as
SourceIdentifier rather than object, dropping a type: ignore that only
existed because the annotation was wrong.
@neosergio
neosergio force-pushed the chore/tighten-test-typing branch from 3061bcb to b7e0643 Compare July 13, 2026 16:11
@neosergio
neosergio merged commit 8992ac9 into main Jul 13, 2026
8 checks passed
@neosergio
neosergio deleted the chore/tighten-test-typing branch July 13, 2026 16:23
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