From 00bbdc64835f653ab5ae1895bc030377b64a5615 Mon Sep 17 00:00:00 2001 From: David Salvisberg Date: Tue, 22 Sep 2026 16:58:43 +0200 Subject: [PATCH 1/2] Avoid accessing `__annotations__` in `clean_dispatch_methods` With PEP-649/PEP-749 semantics this may invoke `__annotate__` with the default format of `Format.VALUE`, which may raise exceptions, but also cause unnecessary work, if the annotations are never inspected. --- reg/context.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/reg/context.py b/reg/context.py index 587431a..626297b 100644 --- a/reg/context.py +++ b/reg/context.py @@ -214,6 +214,13 @@ def clean_dispatch_methods(cls: type[object]) -> None: :param cls: a class that has :class:`reg.DispatchMethod` methods on it. """ for name in dir(cls): + # NOTE: On Python 3.14+ this can invoke `__annotate__` with format + # `VALUE` which can raise a `NameError`, so it can both cause + # exceptions and also involve unnecessary work, so we explicitly + # avoid touching this attribute + if name == "__annotations__": + continue + attr = getattr(cls, name) if inspect.isfunction(attr) and hasattr(attr, "clean"): attr.clean() # pyright: ignore[reportFunctionMemberAccess] From 165ebafc7bcd0b03b5424029eafb92094f0a9a23 Mon Sep 17 00:00:00 2001 From: David Salvisberg Date: Tue, 22 Sep 2026 17:09:57 +0200 Subject: [PATCH 2/2] Excludes guard from coverage for now --- reg/context.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reg/context.py b/reg/context.py index 626297b..88bda77 100644 --- a/reg/context.py +++ b/reg/context.py @@ -218,7 +218,7 @@ def clean_dispatch_methods(cls: type[object]) -> None: # `VALUE` which can raise a `NameError`, so it can both cause # exceptions and also involve unnecessary work, so we explicitly # avoid touching this attribute - if name == "__annotations__": + if name == "__annotations__": # pragma: no cover continue attr = getattr(cls, name)