-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Add deprecated
marker for fields in a model
#2255
Comments
deprecation
marker for fields in a modeldeprecated
marker for fields in a model
I would find this extremely useful as I often encounter usage that is still accepted but discouraged in favour of other approaches. |
Doesn't this work out of the box? The Field docs explain that any keyword arguments are added verbatim to the field's schema. |
As per @lsorber, the schema gets updated with keyword arguments like from pydantic import BaseModel, Field
from typing import Optional, Dict
class MyModel(BaseModel):
oldField: Optional[int] = Field(
None, deprecated=True, description="Use `newField` instead of this"
)
newField: Dict[str, int] = Field(
{},
description="New field to accept string to key values",
my_keyword_arg="my_keyword_value",
)
print(MyModel.schema_json(indent=2)) {
"title": "MyModel",
"type": "object",
"properties": {
"oldField": {
"title": "Oldfield",
"description": "Use `newField` instead of this",
"deprecated": true,
"type": "integer"
},
"newField": {
"title": "Newfield",
"description": "New field to accept string to key values",
"default": {},
"my_keyword_arg": "my_keyword_value",
"type": "object",
"additionalProperties": {
"type": "integer"
}
}
}
} |
Before stumbling upon pydantic, I've implemented something very similar (not as awesome as pydantic of course), but with this deprecation feature and I found this extremely useful. Now we'd like to migrate to pydantic and I'm looking for a way to reproduce this behavior. Specifically, we had the following features:
It looked similar to this: class DeprecatedField(Field):
...
class DeprecatedAlias(DeprecatedField):
....
class MyModel(BaseModel):
version = "0.1.0"
to_be_removed_field: str = DeprecatedField(warn_version="0.1.0", remove_version="1.0.0", reason="for a very good reason")
renamed_field: str = DeprecatedAlias(alias="new_field", warn_version=.... )
new_field: str = Field({}, description="New field to accept string to key values") Could this be implemented by automatically inserting validators for those fields in the |
Maybe this implementation should emit a If so, it may also be convenient a method to easily distinguish the deprecation warnings, e.g. a global var or a specific Pydantic warning. import pydantic
class MyLibDeprecation(DeprecationWarning): ...
pydantic.DEPRECATION_WARNING = MyLibDeprecation Also, @dominikandreas I think this option would probably work better just as an annotation to be implemented at a validation level. A field can be deprecated by several fields or by none at all. Also, |
Any update regarding this? Can be very helpful. |
It will remain possible to set the Regarding emitting DeprecationWarnings, IDE-integration, etc., I think that's a bigger discussion. You could definitely create a reusable validator that would emit a DeprecationWarning on initialization and use it in your own code. Based on the suggestions already received in this thread (most of which I do think are reasonable), I think if we try to provide built-in support there will be a lot of debate about exactly how it should work, and it will come with a significant maintenance burden. I think we'd need to wait until v2 is released to look at this more seriously, but in principle I'd be open to a PR if whoever wants to open it can establish consensus on how the functionality would work. (That would also assume, and maybe this is a big assumption, that the implementation doesn't require adding a significant amount of complexity/maintenance burden to the library.) |
@dmontagu There's an open PEP (PEP 702) to marking deprecations using I think that enabling a similar approach through
The implementation could be something like: def Field(
...
deprecated: bool | str = False,
):
...
if deprecated is not False:
if isinstance(deprecated, str):
_deprecated_msg = deprecated
else:
_deprecated_msg = f'{alias!r} is deprecated'
# wraps the field as in typing.deprecated
... I would be happy to submit a PR if you are open to consider this alternative :) |
Well, if that PEP gets accepted, that would definitely offload the burden of figuring out how it should work; I'd be inclined to follow similar patterns as Given that there is a PEP, I'm pretty reluctant to implement our own approach until we see how that shakes out because the last thing I'd want is to have our own approach that ends up incompatible with how that PEP works (especially if |
Glad to hear you will follow this pattern if the PEP is accepted :) And yes, it makes perfect sense to wait for the acceptance of the PEP before making a decision. But although
|
Yes, I understand this. I'm hoping that it either ends up being clear that Either way, I think it will make sense to add support for deprecating fields (beyond just on the level of JSON schema) once there is a little more clarity around the right behavior. |
**Note:** This PR is based on changes added by #2545 so please review #2545 first. In this PR I'm adding `first_name` and `last_name` to `User` Pydantic schema. I have not found a proper way to deprecate `full_name` field (I have only found this pydantic/pydantic#2255). @frascuchon if you know of some proper way to deprecate this field and automagically show that on swagger docs please tell me.
Our plan is to add this to annotated-types, then respect that. |
This would be nice to have in V2, but since adding it should be entirely backwards compatible, it's not a blocker for V2 - can easily be added in 2.1 etc. |
The page is gone/moved and shows 404. |
Great! I'll open a follow up issue to track remaining features that I had in mind |
Checks
Feature Request
Pydantic Fields should have a boolean option
deprecated
(default False) which can be used to mark deprecated fields. Pydantic plugin for Pycharm can also use this field to see if the field should be used any longer, and show code hints if someone is trying to interact with deprecated fields.Output of
python -c "import pydantic.utils; print(pydantic.utils.version_info())"
:Sample Code Snippet
The text was updated successfully, but these errors were encountered: