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
Use from __future__ import annotations in every module, enforced by ruff #1962
Both happen because, before Python 3.14, annotations on module-level functions and classes are
evaluated eagerly when the def / class statement runs. Any expression in an annotation that
does not work at runtime on that Python, with those dependency versions, becomes an import error. from __future__ import annotations (PEP 563) makes every annotation in the module a string that is
never evaluated at import time, which removes this whole class of failure rather than one instance.
#1955 already named this as the complementary measure to the fix.
ruff check src/autobahn --select I002 with required-imports = ["from __future__ import annotations"]
reports 91 files without it (39 of them test modules). Generated and vendored code is already
excluded by the existing ruff config (src/autobahn/wamp/gen/*, src/autobahn/flatbuffers/*, src/autobahn/wamp/message_fbs.py).
Change
Enforce it, so it stays consistent without anyone remembering:
Apply it once, mechanically: ruff check src/autobahn --select I002 --fix, then ruff format
on the touched files. I002 inserts the import without the blank line after it, which the
formatter adds.
Is it safe?
Trial on a scratch copy of master, CPython 3.14: the import inserted into all 91 files, then both
suites run:
just test-twisted cpy314: PASSED (skips=32, successes=325)
just test-asyncio cpy314: 275 passed, 6 skipped
test_import_all.py: all passed
Why it should be safe in general:
The only place autobahn reads annotations at runtime is the check_types type check
(ApplicationSession.type_check in autobahn/wamp/protocol.py). It reads the annotations of the user's registered functions, not of autobahn's own modules, so this change does not affect
it. (Related, separate issue below.)
No name becomes unavailable: every name used in an annotation today is imported at runtime,
because the annotation is currently evaluated. Code that later calls typing.get_type_hints()
on autobahn classes resolves the strings against the same module globals.
On Python 3.14, annotation evaluation is deferred natively (PEP 649 / PEP 749) and the __future__ import keeps working. When autobahn's minimum becomes 3.14, the import can be
dropped again; the ruff setting then goes with it.
Also to check in the PR: the documentation build (Sphinx autodoc renders the string annotations).
Out of scope
The pre-existing ruff format drift: with the current floating ruff (0.16.10), ruff format --check src/autobahn already reports 42 files on master. That is a separate,
tool-drift matter; this change should only format the lines it touches.
Related latent bug, for its own issue:type_check uses func.__annotations__ directly and
compares with isinstance(value, annotation). In a user module that itself uses from __future__ import annotations (or any string annotation), those are strings, and the check
fails. It should resolve them, e.g. via typing.get_type_hints(func) or inspect.get_annotations(func, eval_str=True).
Acceptance
Every module under src/autobahn (except generated/vendored code) starts with from __future__ import annotations.
ruff enforces it (I002), so a new module without it fails just check-format.
Why
Twice now, a type annotation that is fine for type checkers broke
import autobahn...at runtimeon CPython 3.11–3.13, and both times it shipped:
import autobahn.wamp.cryptosignfails withTypeErroron CPython 3.11–3.13 (regression from #1843) #1878: a string forward reference combined with| None("ISecurityModule" | None) raisedTypeErrorat class-definition time inautobahn.wamp.cryptosign.autobahn.twistedimport fails on CPython 3.11–3.13 withzope.interface < 6.2(gap in #1878) #1955:ITransport | IProcessTransportraisedTypeErrorinautobahn.twisted.util/.wamp,because zope.interface's
InterfaceClasssupports|only from 6.2 on (fixed by Update zope.interface dependency and add future annotations import #1959).Both happen because, before Python 3.14, annotations on module-level functions and classes are
evaluated eagerly when the
def/classstatement runs. Any expression in an annotation thatdoes not work at runtime on that Python, with those dependency versions, becomes an import error.
from __future__ import annotations(PEP 563) makes every annotation in the module a string that isnever evaluated at import time, which removes this whole class of failure rather than one instance.
#1955 already named this as the complementary measure to the fix.
Current state (master ca1e60c)
src/autobahnhave the import; Update zope.interface dependency and add future annotations import #1959 adds 2 more.ruff check src/autobahn --select I002withrequired-imports = ["from __future__ import annotations"]reports 91 files without it (39 of them test modules). Generated and vendored code is already
excluded by the existing ruff config (
src/autobahn/wamp/gen/*,src/autobahn/flatbuffers/*,src/autobahn/wamp/message_fbs.py).Change
Enforce it, so it stays consistent without anyone remembering:
Apply it once, mechanically:
ruff check src/autobahn --select I002 --fix, thenruff formaton the touched files. I002 inserts the import without the blank line after it, which the
formatter adds.
Is it safe?
Trial on a scratch copy of master, CPython 3.14: the import inserted into all 91 files, then both
suites run:
just test-twisted cpy314:PASSED (skips=32, successes=325)just test-asyncio cpy314:275 passed, 6 skippedtest_import_all.py: all passedWhy it should be safe in general:
check_typestype check(
ApplicationSession.type_checkinautobahn/wamp/protocol.py). It reads the annotations of theuser's registered functions, not of autobahn's own modules, so this change does not affect
it. (Related, separate issue below.)
because the annotation is currently evaluated. Code that later calls
typing.get_type_hints()on autobahn classes resolves the strings against the same module globals.
__future__import keeps working. When autobahn's minimum becomes 3.14, the import can bedropped again; the ruff setting then goes with it.
Also to check in the PR: the documentation build (Sphinx autodoc renders the string annotations).
Out of scope
ruff formatdrift: with the current floating ruff (0.16.10),ruff format --check src/autobahnalready reports 42 files on master. That is a separate,tool-drift matter; this change should only format the lines it touches.
type_checkusesfunc.__annotations__directly andcompares with
isinstance(value, annotation). In a user module that itself usesfrom __future__ import annotations(or any string annotation), those are strings, and the checkfails. It should resolve them, e.g. via
typing.get_type_hints(func)orinspect.get_annotations(func, eval_str=True).Acceptance
src/autobahn(except generated/vendored code) starts withfrom __future__ import annotations.I002), so a new module without it failsjust check-format.Update zope.interface dependency and add future annotations import #1959) and the docs build are green.
Note: This issue was drafted with AI assistance (Claude Code).