deps: bump pydantic floor to >=2.4 for money-safety invariants#370
Conversation
The SDK's money-safety invariants depend on Pydantic v2 behaviors that stabilized after 2.0: - StrictInt boolean rejection (relied on by #295) was tightened in 2.4. - model_validator(mode='before') inheritance semantics changed through 2.3. - Decimal coercion edge cases (negative-zero, scientific input) used by _coerce_decimal (#270) were fixed across 2.4/2.5. Allowing 2.0-2.3 lets resolvers land a runtime with subtler validators than the test matrix exercises, quietly undermining #225 / #243 / #295. Bump the floor to pydantic>=2.4,<3 so the installed runtime always matches the invariants the changelog advertises. Verified: ruff, mypy, and tests/test_models.py + tests/test_types.py all pass under the regenerated lock (pydantic 2.13.4 resolved). Closes #346
Code Review — PR #370: Bump pydantic floor to >=2.4OverviewSingle-line dependency floor bump in What's Good
Issues / Suggestions1. Technical justification partially overstated (informational, not a blocker)The PR description frames three pydantic-version dependencies:
The actual reason the bump is defensible is simpler: pydantic 2.0–2.3 are old, have known bugs across the ecosystem, and nobody running Python 3.12 should be on them. That's sufficient justification on its own. The current description may cause confusion if someone reads it alongside 2. Issue #346 recommends 2.5; PR lands on 2.4The referenced issue states:
The PR chose 2.4 without explaining why 2.5 was passed over. Since
Neither 2.4 nor 2.5 would have any practical impact on users, so erring toward 2.5 (the issue's preferred floor) costs nothing. 3. CHANGELOG not updatedBumping a dependency floor is a dependency change that narrows what resolvers can install — it's a visible external contract change. …under an VerdictApprove with minor notes. The change is correct and safe; the notes above are informational. If the author wants to tighten before merge: clarify why 2.4 (vs the issue's 2.5 recommendation) and add a CHANGELOG line. Neither is a blocker. |
Closes #346
The SDK pinned
pydantic>=2.0,<3while relying on validator behaviors that only stabilized in 2.4+:int-typed request fields silently coercebool(subaccount routing, transfers, counts) #295 fence) was tightened in 2.4.model_validator(mode='before')inheritance semantics changed through 2.3._coerce_decimalinvariants (Polish bundle: model small items (AwareDatetime in WS, V1 Literal, default=None, timestamp typing, Decimal NaN) #270) depend onDecimalnegative-zero / scientific-input fixes shipped in 2.4/2.5.Allowing 2.0-2.3 lets the resolver land a runtime with subtler validators than the test matrix exercises, quietly undermining #225 / #243 / #295. The SDK code itself has no bug — only the floor is inconsistent with what the changelog advertises.
Change
pyproject.toml:Lockfile (gitignored) regenerated via
uv lock; resolvedpydantic==2.13.4.Verification
No new test needed — existing model/type tests cover the StrictInt and
_coerce_decimalinvariants and now run against a guaranteed-2.4+ pydantic.