Fully implement modern type hinting, checked with ty in CI#50
Merged
Conversation
Closes the typing item of the 1.0.0 roadmap (Track C), following fork-tongue/observ#184/#185. Typing: - Operation TypedDicts in types.py (AddOperation, RemoveOperation, ReplaceOperation and the Operation union), used across diff, apply, serialize and produce signatures: diff() and produce() now advertise tuple[..., list[Operation], list[Operation]] - PEP 604 unions and builtin generics everywhere via from __future__ import annotations (the runtime floor stays Python 3.9; typing-only imports live in a TYPE_CHECKING block) - py.typed marker shipped in the wheel, Typing :: Typed classifier - Genuine annotation bugs fixed: Pointer.evaluate returned tuple[Diffable, ...] but parent is None at the root; PatchRecorder.record_add annotated reverse_path: Pointer with a None default - Duck-typed code kept honest instead of over-narrowed: the iapply interpreter and the diff() dispatch unpack into Any/cast at the boundary, with comments explaining why Toolchain: - ty in a dedicated dependency group (and in dev), [tool.ty] config scoped to patchdiff/ with python-version = "3.9" so 3.9-incompatible typing constructs are caught - Typecheck job in CI, added to publish's needs Runtime changes (annotation-driven, behavior-preserving): - _Proxy._detach makes its caller-guarded invariant explicit with an assert - pyproject metadata fix: description was literally "MIT"; now a real description plus license = "MIT" ty check: 26 diagnostics on the previous code, 0 after. Tests pass at 100% coverage on 3.10-3.14 locally; docs build stays warning-free with the new signatures. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Mu9vEBwU4fQLi8ZgkgdS2
This was referenced Jul 11, 2026
Korijn
pushed a commit
that referenced
this pull request
Jul 11, 2026
PR #51 added int(key) in Pointer.evaluate before PR #50's typing landed; merged together they leave master's Typecheck job red (key is Hashable, int() wants str-ish). Cast at the conversion site — the retry only runs for parsed string tokens. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Mu9vEBwU4fQLi8ZgkgdS2
Korijn
pushed a commit
that referenced
this pull request
Jul 11, 2026
PR #51 added int(key) in Pointer.evaluate before PR #50's typing landed; merged together they leave master's Typecheck job red (key is Hashable, int() wants str-ish). Cast at the conversion site — the retry only runs for parsed string tokens. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Mu9vEBwU4fQLi8ZgkgdS2
Korijn
added a commit
that referenced
this pull request
Jul 11, 2026
PR #51 added int(key) in Pointer.evaluate before PR #50's typing landed; merged together they leave master's Typecheck job red (key is Hashable, int() wants str-ish). Cast at the conversion site — the retry only runs for parsed string tokens. Claude-Session: https://claude.ai/code/session_016Mu9vEBwU4fQLi8ZgkgdS2 Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Track C of the roadmap — the analog of observ #184 + #185, delivered as one PR instead of the planned stacked pair: the runtime changes typing needed turned out to be two trivial lines (an
assertand a metadata fix), not enough to justify a standalone "runtime cleanups" PR.Typing
OperationTypedDicts intypes.py—AddOperation,RemoveOperation,ReplaceOperationand theOperationunion — used across the public signatures:diff()andproduce()now advertisetuple[..., list[Operation], list[Operation]],apply/iapplytakelist[Operation], andto_json/to_str_pathsare precisely typed.from __future__ import annotations; the runtime floor stays Python 3.9 (typing-only imports live in aTYPE_CHECKINGblock, and nothing new evaluates at runtime).py.typedmarker shipped in the wheel (verified in the built wheel) plus theTyping :: Typedclassifier.Pointer.evaluateclaimed to returntuple[Diffable, ...]butparentisNoneat the root;PatchRecorder.record_addannotatedreverse_path: Pointerwith aNonedefault.iapplyinterpreter anddiff()'s dispatch intentionally accept container look-alikes (observ proxies), so they unpack intoAny/castat one commented boundary instead of pretending to be nominally typed.Toolchain
tydependency group (and indev),[tool.ty]scoped topatchdiff/withpython-version = "3.9"so 3.9-incompatible typing constructs are caught by the checker.publish'sneeds.Runtime changes (annotation-driven, behavior-preserving)
_Proxy._detachmakes its caller-guarded invariant explicit with anassert.descriptionwas literally"MIT"; it's now a real description, pluslicense = "MIT"(the wheel now carriesLicense-Expression: MIT).Verification
ty check: 26 diagnostics on master → 0 on this branch.py.typedand metadata.🤖 Generated with Claude Code
https://claude.ai/code/session_016Mu9vEBwU4fQLi8ZgkgdS2
Generated by Claude Code