-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Add initial support for Python 3.14 #11991
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Deploying pydantic-docs with
|
| Latest commit: |
26c0811
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://938ce782.pydantic-docs.pages.dev |
| Branch Preview URL: | https://3-14-initial-support.pydantic-docs.pages.dev |
Coverage reportClick to see where and how coverage changed
This report was generated by python-coverage-comment-action |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
CodSpeed Performance ReportMerging #11991 will not alter performanceComparing Summary
|
c85a95f to
6df3dfd
Compare
6df3dfd to
b4e8b0a
Compare
8ec2fbe to
06befc9
Compare
beeba50 to
bef4d6a
Compare
bef4d6a to
3acae68
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with some final nits!
| - name: Install memray system dependencies | ||
| if: ${{ matrix.python-version == '3.14' && matrix.os == 'ubuntu-latest' }} | ||
| run: sudo apt-get install libunwind-dev libdebuginfod-dev |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to build memray from source?
If so, it might be that for free-threading we can also build memray: bloomberg/memray#772
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like it doesn't build: https://github.com/pydantic/pydantic/actions/runs/16191109859/job/45706902917?pr=11991
b7fbcdb to
26c0811
Compare
Change Summary
Fixes (partially) #11613.
The remaining failing tests require:NameErrorinForwardRef.evaluate()python/cpython#135646both to be available in 3.14a4.This PR adds basic support for Python 3.14. More 3.14 specific features (e.g. python/cpython#114051) will be added in follow up PRs.
Remaining issues
Using
Field()in dataclassesTo support the following:
We currently have a somewhat hacky solution, which involves wrapping
Field(default=1)intodataclasses.field(default=Field(default=1)), and more importantly directly writing into the__annotations__dict (L184):pydantic/pydantic/dataclasses.py
Lines 153 to 184 in dac3c43
In 3.14, writing/accessing
__annotations__is no longer safe, as aNameErrorcan be raised if a an unresolvable annotation is used. In other words, this now raises:Unfortunately, I've tried hard to see if this could be supported somehow, and came to the conclusion that there is no way to do so without an unreasonable amount of workarounds. Such usage of forward references (without using stringified annotations) is only going to get more popular as 3.14 adoption grows, but it is hard to know how common this issue will be encountered. A couple notes:
This can be mitigated if we only want to support using
Field()on the class being decorated (in which case we don't need to write to__annotations__) but not on any super-classes.To support the case where
Field()is defined on a super-class, this super-class needs to be a Pydantic dataclass (in which case the previous point would have handled it). If the super-class is a stdlib dataclass, it will not be possible to reasonably support this without too much hassle:Here are the options we have:
reprandkw_onlysupport together withField()for dataclasses. I'm not a fan of this approach, as the issue only arises when using forward references as a deferred annotation, and works fine in other cases.NameErrorexceptions when trying to write to__annotations__, and raise a user warning saying the usage ofField()won't be supported if we catch one. Not a fan of this either, as the end user will only get a warning without any real explanation as to why it happened (they don't have to be aware of the Pydantic internals implemented to supportField()).I don't have any satisfactory answers for now. I have added an xfailing test for this, and we can revisit later.
Edit: tracked in #12045, a different implementation will be used.
Real deferred annotations
PEP 649/749 should now allow use cases like this:
However, trying to rebuild
Modelafter getting it fromouter()will raise an exception. This is because when we rebuild model fields, we do so individually by usingtyping._eval_type(). In reality, we should try accessing__annotations__again to let CPython internals resolve the references for us. This is far from trivial to implement, so deferred for a follow-up PR.