Skip to content

[BUG] 26.6.1: import autobahn.wamp.cryptosign fails with TypeError on CPython 3.11–3.13 (regression from #1843) #1878

Description

@oberstet

Summary

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

Reproduction

python3.11 -m venv /tmp/v && /tmp/v/bin/pip install "autobahn==26.6.1" pynacl
/tmp/v/bin/python -c "import autobahn.wamp.cryptosign"
  File ".../autobahn/wamp/cryptosign.py", line 498, in CryptosignKey
    def security_module(self) -> "ISecurityModule" | None:
                                 ~~~~~~~~~~~~~~~~~~^~~~~~
TypeError: unsupported operand type(s) for |: 'str' and 'NoneType'

Root cause

src/autobahn/wamp/cryptosign.py:498:

def security_module(self) -> "ISecurityModule" | None:

The first operand is a string forward-reference ("ISecurityModule"), and the
file has no from __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)":

  • v25.12.2 (correct): def security_module(self) -> Optional["ISecurityModule"]:
  • v26.6.1 (broken): def security_module(self) -> "ISecurityModule" | None:

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)

  1. 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).
  2. 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.
  3. Consider re-checking the rest of the Chore: Conform src/autobahn to ruff's UP rules #1843 UP007 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
  • I have provided a minimal reproducible example
  • I have included version information
  • I have included error messages/logs

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions