Skip to content

deps: refresh the lock, and fix the two breakages it surfaced - #54

Merged
sethbang merged 1 commit into
mainfrom
deps/refresh-2026-08-31
Sep 1, 2026
Merged

deps: refresh the lock, and fix the two breakages it surfaced#54
sethbang merged 1 commit into
mainfrom
deps/refresh-2026-08-31

Conversation

@sethbang

@sethbang sethbang commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Refreshes 34 packages — notably cryptography 50.0.1, click 8.5.0, idna 3.19, pydantic 2.13.5, dcap-qvl 0.6.3 and filelock 3.32.5 — and fixes the two things that broke as a result.

abnf capped below 2.9

A plain poetry update broke SIWE outright. siwe accepts abnf >=2.2,<3, but 2.9.0 made redefining an RFC 5234 core rule a hard error, and siwe's own rfc5234 grammar redefines ALPHA — so import siwe raised GrammarError, taking the whole SIWE and x402 authentication path with it. Capped here rather than waiting on siwe, which is already at its latest release. Bisected against published versions: 2.8.3 is the last good one.

Dict content parts coerce to typed objects again

UserMessage(content=[{"type": "text", ...}]) returned plain dict parts instead of TextContent/ImageContent/AudioContent/VideoContent/FileContent, so msg.content[0].text raised AttributeError. Serialization was unaffected, so the request put on the wire stayed correct — this was an attribute-access break only.

MessageContentPartParam unions the discriminated MessageContentPart with TypedDict mirrors of the same shapes, which exist only so callers can pass plain dicts without type-checker complaints. Smart mode picks a union member by score rather than by order, and the mirrors describe the same shapes by construction, so nothing but a scoring tiebreak ever separated them. pydantic 2.13.5 shipped #13731 "Count validated model fields once in smart unions" and the TypedDict members began winning.

That is an intentional upstream fix, not a regression awaiting revert, so pinning pydantic <2.13.5 would have been a symptom fix with no end date. The union is now pinned to union_mode="left_to_right", which drops the dependency on scoring altogether.

Verified across a behavior matrix on both versions — identical in every case:

input 2.13.4 before 2.13.5 before after (both)
clean text/image dict TextContent dict TextContent
extra key dict dict dict
invalid part (text="") dict dict dict
unknown type raises raises raises
typed instance TextContent TextContent TextContent

Click deprecation

click 8.5.0 deprecates CliRunner.isolated_filesystem, which emitted seven DeprecationWarnings from one helper. Fixture files now go into pytest's tmp_path and are passed as absolute paths, as the deprecation message recommends. The chdir it provided was not load-bearing: the CLI reads its config from ~/.venice-py and none of these commands touch Path.cwd().

Notes for review

  • MessageContentPartParam is exported in __all__, and its runtime value is now Annotated[...] rather than a bare union — get_args() and TypeAdapter() on it see a different shape.
  • The matrix's columns 3 and 4 show a pre-existing validation hole: dict parts with an extra key, or invalid content like {"type": "text", "text": ""} (violating min_length=1), fall through to raw dicts instead of raising. This behaves the same on 2.13.4, so it predates this branch and is deliberately left alone here — closing it means auditing every dict-form content=[...] call site. Worth a separate issue.
  • web3 8, eth-account 0.14, websockets 17 and chardet 7 stay put: siwe 4.4.0 pins web3 <8 and eth-account <0.14, web3 7 pins websockets <16, cyclonedx-bom 7.3.1 pins chardet <6 — all at their latest releases, so these are ecosystem ceilings, not deferred work.
  • hexbytes, eth-abi, rlp and eth-rlp crossed majors because web3 7.16.0 and eth-account 0.13.7 declare them uncapped. Safe here for a specific reason: this SDK imports nothing from web3/hexbytes/eth_abi/rlp directly, and the one hexbytes 2.0 change that reaches it — .hex() no longer returning a 0x prefix — is already normalised at every call site. EIP-712 signing and SIWE verify were both checked end to end.
  • Security advisories GHSA-5p2g-fcmc-qvqq and GHSA-w3rx-r6r6-pgpr (image-size <= 2.0.2, both unpatched upstream) were dismissed as tolerable_risk — build-time only, static output, no attacker-supplied input. 0 open alerts.
  • Also runs the suite on 4 xdist workers instead of 6.

Verification

Full suite green, no failures and no warnings. make check-all clean — mypy Success: no issues found in 190 source files, pyright 0 errors.

Closes on merge

Supersedes Dependabot #43, #44, #45, #47, #50, #51, #52. #46 (tiktoken) is not covered — it bumps the ^0.13.0 constraint in pyproject.toml, which a lock refresh cannot do; merge it after this lands. #48 and #41 are workflow-only and independent.

🤖 Generated with Claude Code

Refreshes 34 packages, notably cryptography 50.0.1, click 8.5.0, idna 3.19,
pydantic 2.13.5, dcap-qvl 0.6.3 and filelock 3.32.5. Three of the changes
needed more than a version bump.

abnf is capped below 2.9 on the x402 extra. siwe accepts abnf >=2.2,<3, but
2.9.0 made redefining an RFC 5234 core rule a hard error and siwe's own
rfc5234 grammar redefines ALPHA, so `import siwe` raised GrammarError and took
the whole SIWE and x402 authentication path with it. Capped here rather than
waiting on siwe, which is already at its latest release. Bisected against
published versions: 2.8.3 is the last good one.

MessageContentPartParam is pinned to union_mode="left_to_right". It unions the
discriminated MessageContentPart with TypedDict mirrors of the same shapes,
which exist only so callers can pass plain dicts without type-checker
complaints. Smart mode picks a union member by score rather than by order, and
the mirrors describe the same shapes by construction, so nothing but a scoring
tiebreak separated them; pydantic 2.13.5 adjusted that scoring
(pydantic/pydantic#13731) and the TypedDict members began winning, leaving dict
content parts as dicts instead of TextContent/ImageContent/AudioContent/
VideoContent/FileContent. Serialization was unaffected, so the request put on
the wire stayed correct, but msg.content[0].text raised AttributeError.
left_to_right drops the dependency on scoring altogether and was verified
identical on 2.13.4 and 2.13.5 across clean dicts, extra keys, invalid parts,
unknown types and typed instances.

click 8.5.0 deprecates CliRunner.isolated_filesystem, which emitted seven
DeprecationWarnings from one helper. The fixture files now go into pytest's
tmp_path and are passed as absolute paths, as the deprecation message
recommends. The chdir it provided was not load-bearing: the CLI reads its
config from ~/.venice-py and none of these commands touch Path.cwd().

web3 8, eth-account 0.14, websockets 17 and chardet 7 stay where they are.
siwe 4.4.0 pins web3 <8 and eth-account <0.14, web3 7 pins websockets <16, and
cyclonedx-bom 7.3.1 pins chardet <6 — all already at their latest releases, so
these are ecosystem ceilings rather than deferred work. hexbytes, eth-abi, rlp
and eth-rlp did cross majors, because web3 7.16.0 and eth-account 0.13.7
declare them with no upper bound; that cohort is safe here because this SDK
imports nothing from web3, hexbytes, eth_abi or rlp directly, and the one
hexbytes 2.0 change that reaches it — .hex() no longer returning a 0x prefix —
is already normalised at every call site.

Also runs the suite on 4 xdist workers instead of 6.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@sethbang
sethbang merged commit 337d697 into main Sep 1, 2026
21 checks passed
@sethbang
sethbang deleted the deps/refresh-2026-08-31 branch September 1, 2026 03:11
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