🐛 Fix type annotation in SQLModel.__new__, avoid explicitly returning Any#1846
Merged
tiangolo merged 1 commit intofastapi:mainfrom Apr 2, 2026
Merged
🐛 Fix type annotation in SQLModel.__new__, avoid explicitly returning Any#1846tiangolo merged 1 commit intofastapi:mainfrom
SQLModel.__new__, avoid explicitly returning Any#1846tiangolo merged 1 commit intofastapi:mainfrom
Conversation
tiangolo
approved these changes
Apr 2, 2026
Member
tiangolo
left a comment
There was a problem hiding this comment.
Thanks Carl! I'm flattered to get a PR from you here. ✨
Thanks for the detailed explanation, super clear.
This will be available in SQLModel 0.0.38, released in the next few hours. 🚀
SQLModel.__new__, avoid explicitly returning Any
Contributor
Author
|
Wow, awesome, thank you @tiangolo for the speedy merge and release! It will be great to get the |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Hello!
I work on the ty type checker, and I am implementing support for the part of the typing spec regarding
__new__methods. I noticed that implementing the specification will result in a regression for SQLModel users; it causes all construction of instances of SQLModel model classes to be inferred asAny. For example:The reason for this is that the typing spec says that if a
__new__method is explicitly annotated to returnAny, that annotation should override the usual constructor type inference, and be taken as-is. (See the sentence in the https://typing.python.org/en/latest/spec/constructors.html#new-method section which begins "For purposes of this test,".)And
SQLModel.__new__is currently annotated to explicitly returnAny.As of this writing, Pyrefly type checker also has this behavior of inferring
Anyfor all SQLModel instances. Mypy and pyright do not, for different reasons. Mypy does not follow the specified handling of constructors; in fact it doesn't even support__new__ever returning a non-instance type. Pyright does follow the specified handling of constructors, but its dataclass-transform support acts as if the dataclass transformation of aSQLModelsubclass synthesizes and adds a__new__method, which overridesSQLModel.__new__, rendering it irrelevant. This is not accurate to what actually happens at runtime (no__new__method is synthesized), so I would not like to take this route in ty.I don't see a good option for how to handle this in ty while both conforming to the typing spec and avoiding this Any inference. So I'd like to suggest that the simplest solution is to remove the
Anyreturn annotation onSQLModel.__new__.There are two options for how to replace it. This PR takes the minimally risky approach of just removing the return annotation altogether. This is semantically the same as an
-> Anyannotation, except that it doesn't override the normal constructor behavior like anAnyannotation does. The only downside is that it requires suppressingno-untyped-defson that line.The other option would be to use
-> Self, which I believe is accurate and should work well, but it is a stricter annotation thanAny, so could carry some risk of new type errors in user code. (I haven't deeply investigated the actual consequences, so this is just "in theory".)(Personally, I don't like that the specification mandates different behavior for an explicit
Anyreturn vs "no annotation" -- I believe those should be treated the same. But it may be difficult to change the spec in this area, given possible backward-compatibility concerns.)Thanks for considering this PR!