You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[BUG] 26.6.1: import autobahn.wamp.cryptosign fails with TypeError on CPython 3.11–3.13 (regression from #1843) #1878
In autobahn 26.6.1, importing autobahn.wamp.cryptosign raises a TypeError
on CPython 3.11, 3.12, 3.13 whenever crypto support is available
(nacl/PyNaCl installed → HAS_CRYPTOSIGN). It works on 3.14. This is live on
PyPI and breaks WAMP-cryptosign for affected users, and transitively breaks any
downstream that imports cryptosign with crypto deps present (e.g. xbr, and
Crossbar.io).
The first operand is a string forward-reference ("ISecurityModule"), and the
file has nofrom __future__ import annotations, so the annotation is
evaluated eagerly at class-definition time → str | None → str.__or__(NoneType) → TypeError. (On 3.14 it doesn't fire because PEP 649
defers annotation evaluation.)
This is a regression introduced in 26.6.1 by 1c7d45cd"Chore: Conform src/autobahn to ruff's UP rules (#1843)":
ruff's UP007 autofix rewrote Optional["X"] → "X" | None. That rewrite is
only safe with from __future__ import annotations (or when X is an imported
name, not a string); applied to a quoted forward-ref without future-annotations,
it produces a runtime TypeError.
Scope
Affected: CPython 3.11 / 3.12 / 3.13 with nacl present (the if HAS_CRYPTOSIGN: block, cryptosign.py:383, where CryptosignKey is
defined). Not 3.14 (PEP 649).
I audited src/autobahn for the same pattern ("<forwardref>" | ... in files
without from __future__ import annotations): this is the only real
occurrence — line 498. (The other "CryptosignKey" forward-refs in the file
are bare single strings and are fine.)
Impact
Anyone using WAMP-cryptosign auth on CPython 3.11–3.13 with autobahn 26.6.1.
Downstream: import xbr and Crossbar.io break on 3.11–3.13 (both pull nacl
via eth-account). This is currently blocking the coordinated 26.6.1 release
of xbr (and crossbar).
Suggested fix (patch release, e.g. 26.6.2)
Fix line 498 — either revert to Optional["ISecurityModule"], or quote the
whole union (-> "ISecurityModule | None"). Adding from __future__ import annotations at the top of cryptosign.py is the more
robust fix (makes all annotations lazy strings and prevents this whole class
of breakage).
CI guard: the test matrix didn't catch this — add a smoke test that
imports every autobahn.* submodule on 3.11 with crypto extras installed
(this exact failure would surface immediately). It appears cryptosign isn't
import-exercised in the 3.11–3.13 + nacl combination today.
Consider re-checking the rest of the Chore: Conform src/autobahn to ruff's UP rules #1843UP007 rewrites for any other Optional["X"] → "X" | None conversions in modules lacking from __future__ import annotations (audit above says cryptosign is the only
one, but worth a confirming pass given how the change was applied).
This analysis was produced with AI assistance (Claude Code) and requires human review before filing. Which I did.
Checklist
I have searched existing issues to avoid duplicates
Summary
In autobahn 26.6.1, importing
autobahn.wamp.cryptosignraises aTypeErroron CPython 3.11, 3.12, 3.13 whenever crypto support is available
(
nacl/PyNaCl installed →HAS_CRYPTOSIGN). It works on 3.14. This is live onPyPI and breaks WAMP-cryptosign for affected users, and transitively breaks any
downstream that imports cryptosign with crypto deps present (e.g.
xbr, andCrossbar.io).
Reproduction
Root cause
src/autobahn/wamp/cryptosign.py:498:The first operand is a string forward-reference (
"ISecurityModule"), and thefile has no
from __future__ import annotations, so the annotation isevaluated eagerly at class-definition time →
str | None→str.__or__(NoneType)→TypeError. (On 3.14 it doesn't fire because PEP 649defers annotation evaluation.)
This is a regression introduced in 26.6.1 by
1c7d45cd"Chore: Conform src/autobahn to ruff's UP rules (#1843)":def security_module(self) -> Optional["ISecurityModule"]:def security_module(self) -> "ISecurityModule" | None:ruff's
UP007autofix rewroteOptional["X"]→"X" | None. That rewrite isonly safe with
from __future__ import annotations(or whenXis an importedname, not a string); applied to a quoted forward-ref without future-annotations,
it produces a runtime
TypeError.Scope
naclpresent (theif HAS_CRYPTOSIGN:block, cryptosign.py:383, whereCryptosignKeyisdefined). Not 3.14 (PEP 649).
src/autobahnfor the same pattern ("<forwardref>" | ...in fileswithout
from __future__ import annotations): this is the only realoccurrence — line 498. (The other
"CryptosignKey"forward-refs in the fileare bare single strings and are fine.)
Impact
import xbrand Crossbar.io break on 3.11–3.13 (both pullnaclvia
eth-account). This is currently blocking the coordinated 26.6.1 releaseof
xbr(andcrossbar).Suggested fix (patch release, e.g. 26.6.2)
Optional["ISecurityModule"], or quote thewhole union (
-> "ISecurityModule | None"). Addingfrom __future__ import annotationsat the top ofcryptosign.pyis the morerobust fix (makes all annotations lazy strings and prevents this whole class
of breakage).
imports every
autobahn.*submodule on 3.11 with crypto extras installed(this exact failure would surface immediately). It appears cryptosign isn't
import-exercised in the 3.11–3.13 + nacl combination today.
UP007rewrites for any otherOptional["X"]→"X" | Noneconversions in modules lackingfrom __future__ import annotations(audit above says cryptosign is the onlyone, but worth a confirming pass given how the change was applied).
This analysis was produced with AI assistance (Claude Code) and requires human review before filing. Which I did.
Checklist