Fix Python 3.14 compatibility for modelclass decorator (KeyError: 'annotations') #932
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR addresses the breakage reported in #902, where Python 3.14's deferred annotation evaluation change (PEP 649) causes a
KeyError
when importing modules likeRESTClient
due to direct access tocls.__dict__["__annotations__"]
.Background:
In Python 3.14, PEP 649 changes how type annotations are handled: they are now evaluated lazily (deferred) rather than eagerly at definition time. Annotations are stored internally via a new
__annotate__
function (not for direct use), and the__annotations__
attribute is a descriptor that computes the annotation dictionary on access. This improves performance but alters runtime behavior. So, we currently directly checkcls.__dict__["__annotations__"]
and it fails in 3.14 withKeyError
because__annotations__
is no longer a key in the class's__dict__
since it's a computed property.Changes:
modelclass
to usetyping.get_type_hints(cls)
for version-agnostic annotation retrieval. This evaluates annotations on-demand in 3.14 while working identically in older versions (3.8+).inspect.isroutine(a)
(with a as str) always passed; now checks the actual class attribute to exclude methods properly.Testing: