Skip to content

deps: bump pydantic floor to >=2.4 for money-safety invariants#370

Merged
TexasCoding merged 1 commit into
mainfrom
r3/W3-E
May 22, 2026
Merged

deps: bump pydantic floor to >=2.4 for money-safety invariants#370
TexasCoding merged 1 commit into
mainfrom
r3/W3-E

Conversation

@TexasCoding

Copy link
Copy Markdown
Owner

Closes #346

The SDK pinned pydantic>=2.0,<3 while relying on validator behaviors that only stabilized in 2.4+:

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:

-    "pydantic>=2.0,<3",
+    "pydantic>=2.4,<3",

Lockfile (gitignored) regenerated via uv lock; resolved pydantic==2.13.4.

Verification

uv lock && uv sync
uv run ruff check kalshi/ tests/     # All checks passed!
uv run mypy kalshi/                  # Success: no issues found in 76 source files
uv run pytest tests/test_models.py tests/test_types.py -q   # 182 passed in 2.36s

No new test needed — existing model/type tests cover the StrictInt and _coerce_decimal invariants and now run against a guaranteed-2.4+ pydantic.

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
@TexasCoding TexasCoding added the dependencies Dependency / version-pin updates (Dependabot, manual bumps) label May 22, 2026
@claude

claude Bot commented May 22, 2026

Copy link
Copy Markdown

Code Review — PR #370: Bump pydantic floor to >=2.4

Overview

Single-line dependency floor bump in pyproject.toml. Change is correct, safe, and well-motivated. Review notes a few areas worth considering before merge.


What's Good


Issues / Suggestions

1. Technical justification partially overstated (informational, not a blocker)

The PR description frames three pydantic-version dependencies:

Claim Actual situation
"StrictInt boolean rejection was tightened in 2.4" SDK's StrictInt is Annotated[int, BeforeValidator(_reject_bool_int)] — an explicit isinstance(value, bool) check in types.py:141. This is completely version-independent within pydantic 2.x.
"model_validator(mode='before') inheritance semantics changed through 2.3" All model_validator usage in the SDK is mode="after" (orders.py:297, orders.py:531). The 2.0–2.3 mode='before' inheritance issue doesn't apply.
"_coerce_decimal invariants depend on Decimal fixes in 2.4/2.5" _coerce_decimal is a standalone Python function using Decimal(str(value)) with explicit isinstance guards. It doesn't rely on pydantic's internal Decimal handling.

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 types.py.

2. Issue #346 recommends 2.5; PR lands on 2.4

The referenced issue states:

Raise the floor to pydantic>=2.5,<3 … If 2.4 testing exists, pydantic>=2.4,<3 is also defensible

The PR chose 2.4 without explaining why 2.5 was passed over. Since _coerce_decimal's is_finite() interaction was specifically mentioned as being fixed across "2.4/2.5," the distinction matters if that's a real concern. Either:

  • Document why 2.4 is sufficient (e.g. the specific fix landed in 2.4, or the SDK's custom validator makes it moot), or
  • Bump to 2.5 to match the more conservative recommendation.

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 updated

Bumping a dependency floor is a dependency change that narrows what resolvers can install — it's a visible external contract change. CHANGELOG.md has a 2.6.0 entry already open. A one-liner like:

- Raised `pydantic` minimum from `>=2.0` to `>=2.4` to align with invariants
  the SDK's money-safety validators have relied on since v2.5 (#346).

…under an ### Internal or ### Dependencies section would make this visible to users who read the changelog when upgrading.


Verdict

Approve 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.

@TexasCoding
TexasCoding merged commit b0861eb into main May 22, 2026
5 checks passed
@TexasCoding
TexasCoding deleted the r3/W3-E branch May 22, 2026 23:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Dependency / version-pin updates (Dependabot, manual bumps)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pyproject pins pydantic>=2.0 but money-safety invariants need 2.4+ semantics

1 participant