Skip to content

Gate ty as a third type checker and release 1.7.2#19

Merged
wlaur merged 8 commits into
mainfrom
feat/ty-third-type-checker
Jul 11, 2026
Merged

Gate ty as a third type checker and release 1.7.2#19
wlaur merged 8 commits into
mainfrom
feat/ty-third-type-checker

Conversation

@wlaur

@wlaur wlaur commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Summary

  • resolve the 71 ty diagnostics: ~11 via genuine code improvements, the rest via rule-specific # ty: ignore[...] comments where ty disagrees with pyright (the source of truth) and pyrefly — all suppressed lines pass both other checkers unmodified and are exercised at runtime by the test suite
  • gate ty check in the CI typecheck job; warnings fail too via [tool.ty.terminal] error-on-warning = true, and unused-ignore-comment is elevated to error so stale suppressions cannot linger
  • extend the doc-block tests (test_docs.py) and the static-rejection guarantees (test_static_typing.py) to ty, twinned with the existing pyright/pyrefly variants
  • add AGENTS.md documenting the three-checker protocol, executable-docs rule and library invariants, with CLAUDE.md redirecting to it
  • bump to 1.7.2

Verification

  • pyright: 0 errors, pyrefly: 0 errors, ty: 0 diagnostics (with error-on-warning)
  • full pytest suite green locally (785 tests + 217 doc-block checks)

🤖 Generated with Claude Code

wlaur and others added 8 commits July 11, 2026 11:54
- fluids: declare _composition with the Composition alias (drops a cast),
  build the Series result in one expression instead of casting through Any
- sympy: hoist the knowns|avoid union out of the closure (ty does not
  narrow captured variables, and this also avoids re-unioning per call),
  annotate _get_val with the precise Quantity[Any, ...] return
- units: cast the Series/Expr branch of _validate_magnitude like every
  sibling branch, hoist one dict[str, Any] cast in _pydantic_build_quantity
- tests: hoist the second_point declaration above both branches

Where pyright strict genuinely requires a cast() to launder Unknown but ty
resolves the type on its own, keep the cast with a ty: ignore[redundant-cast].

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
All suppressed lines pass pyright strict and pyrefly unmodified, and every
one of them is exercised at runtime by the test suite. The ignores fall into
three groups where ty disagrees with both other checkers:

- constrained-TypeVar solving: ty substitutes a union of constraints for MT
  (a constrained TypeVar must solve to exactly one constraint), rejecting
  valid Fluid/Water/HumidAir constructor calls and Quantity operator uses
- isinstance narrowing: ty materializes TypeVar defaults into the narrowed
  type (Quantity -> Quantity[UnknownDimensionality, Numpy1DArray]) and keeps
  sound-but-noisy intersections like float & ndarray that break member access
- override strictness: ty flags the intentionally-narrowed comparison and
  pickling overrides that already carry pyright/pyrefly ignores where those
  checkers flag them too

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- run `ty check --error-on-warning` in the typecheck job after pyright and
  pyrefly, so ty's own warnings (e.g. a typo'd rule in an ignore comment)
  fail the gate too
- elevate unused-ignore-comment to error, matching pyright's
  reportUnnecessaryTypeIgnoreComment and pyrefly's unused-ignore
- pin the Q("24 kg") / Q(1, Q(2, "m")) static rejections under ty in
  test_static_typing.py, twinned with the existing pyright/pyrefly tests

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Mirror the pyright/pyrefly doc-block tests with a ty variant (--project
resolves the repo config from tmp_path, --error-on-warning matches CI).
The one block ty cannot solve (mixed vector/scalar Water inputs, the same
constrained-TypeVar limitation suppressed in the test suite) carries the
same rule-specific ignore, next to the existing pyright precedent.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Documents the three-type-checker gate (pyright as source of truth, per-checker
rule-specific suppressions, unused-suppression policing), the executable-docs
rule, the library invariants (no string quantities, no implicit physical
identities, temperature-difference semantics, one CoolProp property per node),
and the build/release tooling. CLAUDE.md redirects here via @AGENTS.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
[tool.ty.terminal] error-on-warning = true makes every `ty check` invocation
(CI, doc-block tests, local runs) fail on warnings without remembering a
flag. Verified: a warning-level diagnostic exits 1 with no CLI arguments.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…check

The rename to "typecheck (pyright + pyrefly + ty)" orphaned the required
status check on main (required checks match on the exact job name), which
blocked merging. Restore the protected name and document the constraint;
the job itself still gates on all three checkers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@wlaur
wlaur merged commit 8568029 into main Jul 11, 2026
19 checks passed
@wlaur
wlaur deleted the feat/ty-third-type-checker branch July 11, 2026 10:21
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