-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Fix type checking issue with model_fields
and model_computed_fields
#10911
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: |
60522af
|
Status: | ✅ Deploy successful! |
Preview URL: | https://88b7606a.pydantic-docs.pages.dev |
Branch Preview URL: | https://fix-type-checking-issue-mode.pydantic-docs.pages.dev |
CodSpeed Performance ReportMerging #10911 will not alter performanceComparing Summary
|
Coverage reportClick to see where and how coverage changed
This report was generated by python-coverage-comment-action |
We are hitting undefined behavior between pyright and mypy here, when a property is defined both on the metaclass and the class itself. I think it's a bit unfortunate to have
Code sample in pyright playground import warnings
from typing import Callable, Generic, TypeVar, overload
from typing_extensions import deprecated
from pydantic.warnings import PydanticDeprecatedSince211
ModelT = TypeVar('ModelT', bound='BaseModel')
R = TypeVar('R')
class classonlyproperty(Generic[ModelT, R]):
def __init__(self, fget: Callable[[type[ModelT]], R], /) -> None:
self.fget = fget
@overload
def __get__(self, instance: None, owner: type[ModelT]) -> R: ...
@overload
@deprecated(
"Accessing this attribute on the instance is deprecated, and will be removed in Pydantic V3.",
category=None,
)
def __get__(self, instance: ModelT, owner: type[ModelT]) -> R: ...
def __get__(self, instance: ModelT | None, owner: type[ModelT]) -> R:
if instance is not None:
warnings.warn(
"Accessing this attribute on the instance is deprecated, and will be removed in Pydantic V3.",
category=PydanticDeprecatedSince211,
)
return self.fget(owner)
class BaseModel:
@classonlyproperty
@classmethod
def model_fields(cls) -> dict[str, str]:
...
BaseModel.model_fields
BaseModel().model_fields # type checker error pyright will emit an error, and mypy
WDYT? |
Interesting idea. 2 reservations I have about this:
I sort of poorly explained this in a comment:
|
The naming of the decorator can be improved, but with this approach, accessing the property does work at runtime. However, it will emit a runtime deprecation warning and a type checker error/warning
Well the usage of the descriptor can feel a bit too much for such a small use case, but descriptor support is implemented by all major type checkers and this seems to be the only viable approach to emit a deprecation warning. I'm a bit worried that in V3 this will come as a surprise, because we currently don't emit anything (as an example, SQLModel relies on this) |
Yeah, fair point. What if:
|
Sounds good, could you please add some tests in the |
Oh so odd, I think I have them locally but didn't push... |
Co-authored-by: Victorien <65306057+Viicos@users.noreply.github.com>
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.
thanks for adding the tests
…s` (#10911) Co-authored-by: Victorien <65306057+Viicos@users.noreply.github.com>
Fix #10907