From 4d905ce7f9bc2e64b05c134f8ab0529a06cc5ed4 Mon Sep 17 00:00:00 2001 From: Viicos <65306057+Viicos@users.noreply.github.com> Date: Sun, 3 Dec 2023 21:15:57 +0100 Subject: [PATCH 01/13] Fix usage of `@deprecated` --- pydantic/_internal/_model_construction.py | 1 - pydantic/deprecated/decorator.py | 15 +++++---------- pydantic/deprecated/json.py | 14 +++++--------- pydantic/deprecated/parse.py | 7 ++----- pydantic/deprecated/tools.py | 23 +++++++++-------------- 5 files changed, 21 insertions(+), 39 deletions(-) diff --git a/pydantic/_internal/_model_construction.py b/pydantic/_internal/_model_construction.py index 1d7fbf788a..fd2d6f70b8 100644 --- a/pydantic/_internal/_model_construction.py +++ b/pydantic/_internal/_model_construction.py @@ -246,7 +246,6 @@ def _collect_bases_data(bases: tuple[type[Any], ...]) -> tuple[set[str], set[str 'The `__fields__` attribute is deprecated, use `model_fields` instead.', category=PydanticDeprecatedSince20 ) def __fields__(self) -> dict[str, FieldInfo]: - warnings.warn('The `__fields__` attribute is deprecated, use `model_fields` instead.', DeprecationWarning) return self.model_fields # type: ignore diff --git a/pydantic/deprecated/decorator.py b/pydantic/deprecated/decorator.py index 11244ba19f..21bc088db1 100644 --- a/pydantic/deprecated/decorator.py +++ b/pydantic/deprecated/decorator.py @@ -1,4 +1,3 @@ -import warnings from functools import wraps from typing import TYPE_CHECKING, Any, Callable, Dict, List, Mapping, Optional, Tuple, Type, TypeVar, Union, overload @@ -26,26 +25,22 @@ @overload -@deprecated( - 'The `validate_arguments` method is deprecated; use `validate_call` instead.', category=PydanticDeprecatedSince20 -) def validate_arguments(func: None = None, *, config: 'ConfigType' = None) -> Callable[['AnyCallableT'], 'AnyCallableT']: ... @overload -@deprecated( - 'The `validate_arguments` method is deprecated; use `validate_call` instead.', category=PydanticDeprecatedSince20 -) def validate_arguments(func: 'AnyCallableT') -> 'AnyCallableT': ... +@deprecated( + 'The `validate_arguments` method is deprecated; use `validate_call` instead.', + category=PydanticDeprecatedSince20, + stacklevel=2, +) def validate_arguments(func: Optional['AnyCallableT'] = None, *, config: 'ConfigType' = None) -> Any: """Decorator to validate the arguments passed to a function.""" - warnings.warn( - 'The `validate_arguments` method is deprecated; use `validate_call` instead.', DeprecationWarning, stacklevel=2 - ) def validate(_func: 'AnyCallable') -> 'AnyCallable': vd = ValidatedFunction(_func, config) diff --git a/pydantic/deprecated/json.py b/pydantic/deprecated/json.py index d06735327f..49762c8ec2 100644 --- a/pydantic/deprecated/json.py +++ b/pydantic/deprecated/json.py @@ -1,5 +1,4 @@ import datetime -import warnings from collections import deque from decimal import Decimal from enum import Enum @@ -79,14 +78,15 @@ def decimal_encoder(dec_value: Decimal) -> Union[int, float]: @deprecated( - 'pydantic_encoder is deprecated, use pydantic_core.to_jsonable_python instead.', category=PydanticDeprecatedSince20 + 'pydantic_encoder is deprecated, use pydantic_core.to_jsonable_python instead.', + category=PydanticDeprecatedSince20, + stacklevel=2, ) def pydantic_encoder(obj: Any) -> Any: from dataclasses import asdict, is_dataclass from ..main import BaseModel - warnings.warn('pydantic_encoder is deprecated, use BaseModel.model_dump instead.', DeprecationWarning, stacklevel=2) if isinstance(obj, BaseModel): return obj.model_dump() elif is_dataclass(obj): @@ -104,12 +104,9 @@ def pydantic_encoder(obj: Any) -> Any: # TODO: Add a suggested migration path once there is a way to use custom encoders -@deprecated('custom_pydantic_encoder is deprecated.', category=PydanticDeprecatedSince20) +@deprecated('custom_pydantic_encoder is deprecated.', category=PydanticDeprecatedSince20, stacklevel=2) def custom_pydantic_encoder(type_encoders: Dict[Any, Callable[[Type[Any]], Any]], obj: Any) -> Any: # Check the class type and its superclasses for a matching encoder - warnings.warn( - 'custom_pydantic_encoder is deprecated, use BaseModel.model_dump instead.', DeprecationWarning, stacklevel=2 - ) for base in obj.__class__.__mro__[:-1]: try: encoder = type_encoders[base] @@ -121,10 +118,9 @@ def custom_pydantic_encoder(type_encoders: Dict[Any, Callable[[Type[Any]], Any]] return pydantic_encoder(obj) -@deprecated('timedelta_isoformat is deprecated.', category=PydanticDeprecatedSince20) +@deprecated('timedelta_isoformat is deprecated.', category=PydanticDeprecatedSince20, stacklevel=2) def timedelta_isoformat(td: datetime.timedelta) -> str: """ISO 8601 encoding for Python timedelta object.""" - warnings.warn('timedelta_isoformat is deprecated.', DeprecationWarning, stacklevel=2) minutes, seconds = divmod(td.seconds, 60) hours, minutes = divmod(minutes, 60) return f'{"-" if td.days < 0 else ""}P{abs(td.days)}DT{hours:d}H{minutes:d}M{seconds:d}.{td.microseconds:06d}S' diff --git a/pydantic/deprecated/parse.py b/pydantic/deprecated/parse.py index 126d6aae85..7e02d6c018 100644 --- a/pydantic/deprecated/parse.py +++ b/pydantic/deprecated/parse.py @@ -2,7 +2,6 @@ import json import pickle -import warnings from enum import Enum from pathlib import Path from typing import TYPE_CHECKING, Any, Callable @@ -22,7 +21,7 @@ class Protocol(str, Enum): pickle = 'pickle' -@deprecated('load_str_bytes is deprecated.', category=PydanticDeprecatedSince20) +@deprecated('load_str_bytes is deprecated.', category=PydanticDeprecatedSince20, stacklevel=2) def load_str_bytes( b: str | bytes, *, @@ -32,7 +31,6 @@ def load_str_bytes( allow_pickle: bool = False, json_loads: Callable[[str], Any] = json.loads, ) -> Any: - warnings.warn('load_str_bytes is deprecated.', DeprecationWarning, stacklevel=2) if proto is None and content_type: if content_type.endswith(('json', 'javascript')): pass @@ -56,7 +54,7 @@ def load_str_bytes( raise TypeError(f'Unknown protocol: {proto}') -@deprecated('load_file is deprecated.', category=PydanticDeprecatedSince20) +@deprecated('load_file is deprecated.', category=PydanticDeprecatedSince20, stacklevel=2) def load_file( path: str | Path, *, @@ -66,7 +64,6 @@ def load_file( allow_pickle: bool = False, json_loads: Callable[[str], Any] = json.loads, ) -> Any: - warnings.warn('load_file is deprecated.', DeprecationWarning, stacklevel=2) path = Path(path) b = path.read_bytes() if content_type is None: diff --git a/pydantic/deprecated/tools.py b/pydantic/deprecated/tools.py index 2b05d38ef2..4ea6fff1cc 100644 --- a/pydantic/deprecated/tools.py +++ b/pydantic/deprecated/tools.py @@ -24,14 +24,11 @@ @deprecated( - 'parse_obj_as is deprecated. Use pydantic.TypeAdapter.validate_python instead.', category=PydanticDeprecatedSince20 + 'parse_obj_as is deprecated. Use pydantic.TypeAdapter.validate_python instead.', + category=PydanticDeprecatedSince20, + stacklevel=2, ) def parse_obj_as(type_: type[T], obj: Any, type_name: NameFactory | None = None) -> T: - warnings.warn( - 'parse_obj_as is deprecated. Use pydantic.TypeAdapter.validate_python instead.', - DeprecationWarning, - stacklevel=2, - ) if type_name is not None: # pragma: no cover warnings.warn( 'The type_name parameter is deprecated. parse_obj_as no longer creates temporary models', @@ -42,7 +39,9 @@ def parse_obj_as(type_: type[T], obj: Any, type_name: NameFactory | None = None) @deprecated( - 'schema_of is deprecated. Use pydantic.TypeAdapter.json_schema instead.', category=PydanticDeprecatedSince20 + 'schema_of is deprecated. Use pydantic.TypeAdapter.json_schema instead.', + category=PydanticDeprecatedSince20, + stacklevel=2, ) def schema_of( type_: Any, @@ -53,9 +52,6 @@ def schema_of( schema_generator: type[GenerateJsonSchema] = GenerateJsonSchema, ) -> dict[str, Any]: """Generate a JSON schema (as dict) for the passed model or dynamically generated one.""" - warnings.warn( - 'schema_of is deprecated. Use pydantic.TypeAdapter.json_schema instead.', DeprecationWarning, stacklevel=2 - ) res = TypeAdapter(type_).json_schema( by_alias=by_alias, schema_generator=schema_generator, @@ -75,7 +71,9 @@ def schema_of( @deprecated( - 'schema_json_of is deprecated. Use pydantic.TypeAdapter.json_schema instead.', category=PydanticDeprecatedSince20 + 'schema_json_of is deprecated. Use pydantic.TypeAdapter.json_schema instead.', + category=PydanticDeprecatedSince20, + stacklevel=2, ) def schema_json_of( type_: Any, @@ -87,9 +85,6 @@ def schema_json_of( **dumps_kwargs: Any, ) -> str: """Generate a JSON schema (as JSON) for the passed model or dynamically generated one.""" - warnings.warn( - 'schema_json_of is deprecated. Use pydantic.TypeAdapter.json_schema instead.', DeprecationWarning, stacklevel=2 - ) return json.dumps( schema_of(type_, title=title, by_alias=by_alias, ref_template=ref_template, schema_generator=schema_generator), **dumps_kwargs, From 4d4f35a778b81969b4ab1b151671615c1b4e29be Mon Sep 17 00:00:00 2001 From: Viicos <65306057+Viicos@users.noreply.github.com> Date: Mon, 4 Dec 2023 17:44:01 +0100 Subject: [PATCH 02/13] Remove missed calls --- pydantic/main.py | 49 ------------------------------------------------ 1 file changed, 49 deletions(-) diff --git a/pydantic/main.py b/pydantic/main.py index b0377afb4d..a51acc6061 100644 --- a/pydantic/main.py +++ b/pydantic/main.py @@ -987,7 +987,6 @@ def __str__(self) -> str: 'The `__fields__` attribute is deprecated, use `model_fields` instead.', category=PydanticDeprecatedSince20 ) def __fields__(self) -> dict[str, FieldInfo]: - warnings.warn('The `__fields__` attribute is deprecated, use `model_fields` instead.', DeprecationWarning) return self.model_fields @property @@ -996,9 +995,6 @@ def __fields__(self) -> dict[str, FieldInfo]: category=PydanticDeprecatedSince20, ) def __fields_set__(self) -> set[str]: - warnings.warn( - 'The `__fields_set__` attribute is deprecated, use `model_fields_set` instead.', DeprecationWarning - ) return self.__pydantic_fields_set__ @typing_extensions.deprecated( @@ -1014,7 +1010,6 @@ def dict( # noqa: D102 exclude_defaults: bool = False, exclude_none: bool = False, ) -> typing.Dict[str, Any]: # noqa UP006 - warnings.warn('The `dict` method is deprecated; use `model_dump` instead.', DeprecationWarning) return self.model_dump( include=include, exclude=exclude, @@ -1040,7 +1035,6 @@ def json( # noqa: D102 models_as_dict: bool = PydanticUndefined, # type: ignore[assignment] **dumps_kwargs: Any, ) -> str: - warnings.warn('The `json` method is deprecated; use `model_dump_json` instead.', DeprecationWarning) if encoder is not PydanticUndefined: raise TypeError('The `encoder` argument is no longer supported; use field serializers instead.') if models_as_dict is not PydanticUndefined: @@ -1061,7 +1055,6 @@ def json( # noqa: D102 'The `parse_obj` method is deprecated; use `model_validate` instead.', category=PydanticDeprecatedSince20 ) def parse_obj(cls: type[Model], obj: Any) -> Model: # noqa: D102 - warnings.warn('The `parse_obj` method is deprecated; use `model_validate` instead.', DeprecationWarning) return cls.model_validate(obj) @classmethod @@ -1079,11 +1072,6 @@ def parse_raw( # noqa: D102 proto: DeprecatedParseProtocol | None = None, allow_pickle: bool = False, ) -> Model: # pragma: no cover - warnings.warn( - 'The `parse_raw` method is deprecated; if your data is JSON use `model_validate_json`, ' - 'otherwise load the data then use `model_validate` instead.', - DeprecationWarning, - ) from .deprecated import parse try: @@ -1132,11 +1120,6 @@ def parse_file( # noqa: D102 proto: DeprecatedParseProtocol | None = None, allow_pickle: bool = False, ) -> Model: - warnings.warn( - 'The `parse_file` method is deprecated; load the data from file, then if your data is JSON ' - 'use `model_validate_json` otherwise `model_validate` instead.', - DeprecationWarning, - ) from .deprecated import parse obj = parse.load_file( @@ -1155,11 +1138,6 @@ def parse_file( # noqa: D102 category=PydanticDeprecatedSince20, ) def from_orm(cls: type[Model], obj: Any) -> Model: # noqa: D102 - warnings.warn( - 'The `from_orm` method is deprecated; set `model_config["from_attributes"]=True` ' - 'and use `model_validate` instead.', - DeprecationWarning, - ) if not cls.model_config.get('from_attributes', None): raise PydanticUserError( 'You must set the config attribute `from_attributes=True` to use from_orm', code=None @@ -1171,7 +1149,6 @@ def from_orm(cls: type[Model], obj: Any) -> Model: # noqa: D102 'The `construct` method is deprecated; use `model_construct` instead.', category=PydanticDeprecatedSince20 ) def construct(cls: type[Model], _fields_set: set[str] | None = None, **values: Any) -> Model: # noqa: D102 - warnings.warn('The `construct` method is deprecated; use `model_construct` instead.', DeprecationWarning) return cls.model_construct(_fields_set=_fields_set, **values) @typing_extensions.deprecated( @@ -1210,11 +1187,6 @@ def copy( Returns: A copy of the model with included, excluded and updated fields as specified. """ - warnings.warn( - 'The `copy` method is deprecated; use `model_copy` instead. ' - 'See the docstring of `BaseModel.copy` for details about how to handle `include` and `exclude`.', - DeprecationWarning, - ) from .deprecated import copy_internals values = dict( @@ -1258,7 +1230,6 @@ def copy( def schema( # noqa: D102 cls, by_alias: bool = True, ref_template: str = DEFAULT_REF_TEMPLATE ) -> typing.Dict[str, Any]: # noqa UP006 - warnings.warn('The `schema` method is deprecated; use `model_json_schema` instead.', DeprecationWarning) return cls.model_json_schema(by_alias=by_alias, ref_template=ref_template) @classmethod @@ -1271,10 +1242,6 @@ def schema_json( # noqa: D102 ) -> str: # pragma: no cover import json - warnings.warn( - 'The `schema_json` method is deprecated; use `model_json_schema` and json.dumps instead.', - DeprecationWarning, - ) from .deprecated.json import pydantic_encoder return json.dumps( @@ -1288,7 +1255,6 @@ def schema_json( # noqa: D102 'The `validate` method is deprecated; use `model_validate` instead.', category=PydanticDeprecatedSince20 ) def validate(cls: type[Model], value: Any) -> Model: # noqa: D102 - warnings.warn('The `validate` method is deprecated; use `model_validate` instead.', DeprecationWarning) return cls.model_validate(value) @classmethod @@ -1297,9 +1263,6 @@ def validate(cls: type[Model], value: Any) -> Model: # noqa: D102 category=PydanticDeprecatedSince20, ) def update_forward_refs(cls, **localns: Any) -> None: # noqa: D102 - warnings.warn( - 'The `update_forward_refs` method is deprecated; use `model_rebuild` instead.', DeprecationWarning - ) if localns: # pragma: no cover raise TypeError('`localns` arguments are not longer accepted.') cls.model_rebuild(force=True) @@ -1308,8 +1271,6 @@ def update_forward_refs(cls, **localns: Any) -> None: # noqa: D102 'The private method `_iter` will be removed and should no longer be used.', category=PydanticDeprecatedSince20 ) def _iter(self, *args: Any, **kwargs: Any) -> Any: - warnings.warn('The private method `_iter` will be removed and should no longer be used.', DeprecationWarning) - from .deprecated import copy_internals return copy_internals._iter(self, *args, **kwargs) @@ -1319,10 +1280,6 @@ def _iter(self, *args: Any, **kwargs: Any) -> Any: category=PydanticDeprecatedSince20, ) def _copy_and_set_values(self, *args: Any, **kwargs: Any) -> Any: - warnings.warn( - 'The private method `_copy_and_set_values` will be removed and should no longer be used.', - DeprecationWarning, - ) from .deprecated import copy_internals return copy_internals._copy_and_set_values(self, *args, **kwargs) @@ -1333,9 +1290,6 @@ def _copy_and_set_values(self, *args: Any, **kwargs: Any) -> Any: category=PydanticDeprecatedSince20, ) def _get_value(cls, *args: Any, **kwargs: Any) -> Any: - warnings.warn( - 'The private method `_get_value` will be removed and should no longer be used.', DeprecationWarning - ) from .deprecated import copy_internals @@ -1346,9 +1300,6 @@ def _get_value(cls, *args: Any, **kwargs: Any) -> Any: category=PydanticDeprecatedSince20, ) def _calculate_keys(self, *args: Any, **kwargs: Any) -> Any: - warnings.warn( - 'The private method `_calculate_keys` will be removed and should no longer be used.', DeprecationWarning - ) from .deprecated import copy_internals From a266b9cdaa4a15066ada9b752ae8edc41c6b043b Mon Sep 17 00:00:00 2001 From: Viicos <65306057+Viicos@users.noreply.github.com> Date: Mon, 4 Dec 2023 18:04:24 +0100 Subject: [PATCH 03/13] Some fixes --- pydantic/main.py | 2 -- tests/test_deprecated.py | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/pydantic/main.py b/pydantic/main.py index a51acc6061..21bf1a2abe 100644 --- a/pydantic/main.py +++ b/pydantic/main.py @@ -1290,7 +1290,6 @@ def _copy_and_set_values(self, *args: Any, **kwargs: Any) -> Any: category=PydanticDeprecatedSince20, ) def _get_value(cls, *args: Any, **kwargs: Any) -> Any: - from .deprecated import copy_internals return copy_internals._get_value(cls, *args, **kwargs) @@ -1300,7 +1299,6 @@ def _get_value(cls, *args: Any, **kwargs: Any) -> Any: category=PydanticDeprecatedSince20, ) def _calculate_keys(self, *args: Any, **kwargs: Any) -> Any: - from .deprecated import copy_internals return copy_internals._calculate_keys(self, *args, **kwargs) diff --git a/tests/test_deprecated.py b/tests/test_deprecated.py index 5c422fb760..1b3c55aa46 100644 --- a/tests/test_deprecated.py +++ b/tests/test_deprecated.py @@ -41,7 +41,7 @@ def deprecated_from_orm(model_type: Type[BaseModel], obj: Any) -> Any: with pytest.warns( PydanticDeprecatedSince20, match=re.escape( - 'The `from_orm` method is deprecated; set `model_config["from_attributes"]=True` ' + "The `from_orm` method is deprecated; set `model_config['from_attributes']=True` " 'and use `model_validate` instead.' ), ): @@ -746,7 +746,7 @@ class Model(BaseModel): assert hasattr(pydantic_encoder, '__deprecated__') with pytest.warns( - PydanticDeprecatedSince20, match='pydantic_encoder is deprecated, use BaseModel.model_dump instead.' + PydanticDeprecatedSince20, match='pydantic_encoder is deprecated, use pydantic_core.to_jsonable_python instead.' ): pydantic_encoder(Model(x=1)) From 4f59a92cad9a0184260151daf24f98a76880be37 Mon Sep 17 00:00:00 2001 From: Viicos <65306057+Viicos@users.noreply.github.com> Date: Fri, 8 Dec 2023 17:19:13 +0100 Subject: [PATCH 04/13] more fixes --- pydantic/main.py | 4 +++- tests/test_deprecated.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pydantic/main.py b/pydantic/main.py index 21bf1a2abe..1f31a1d79a 100644 --- a/pydantic/main.py +++ b/pydantic/main.py @@ -1152,7 +1152,9 @@ def construct(cls: type[Model], _fields_set: set[str] | None = None, **values: A return cls.model_construct(_fields_set=_fields_set, **values) @typing_extensions.deprecated( - 'The copy method is deprecated; use `model_copy` instead.', category=PydanticDeprecatedSince20 + 'The `copy` method is deprecated; use `model_copy` instead. ' + 'See the docstring of `BaseModel.copy` for details about how to handle `include` and `exclude`.', + category=PydanticDeprecatedSince20, ) def copy( self: Model, diff --git a/tests/test_deprecated.py b/tests/test_deprecated.py index 1b3c55aa46..446cd151f2 100644 --- a/tests/test_deprecated.py +++ b/tests/test_deprecated.py @@ -689,7 +689,7 @@ def test_update_forward_refs(): def test_copy_and_set_values(): m = SimpleModel(x=1) with pytest.warns( - PydanticDeprecatedSince20, match='^The private method `_copy_and_set_values` will be removed and ' + PydanticDeprecatedSince20, match='^The private method `_copy_and_set_values` will be removed and ' ): m2 = m._copy_and_set_values(values={'x': 2}, fields_set={'x'}, deep=False) From 0fad7d081484d1bfc7a20c52e63448598472553b Mon Sep 17 00:00:00 2001 From: Viicos <65306057+Viicos@users.noreply.github.com> Date: Fri, 8 Dec 2023 17:26:58 +0100 Subject: [PATCH 05/13] Final fixes --- pydantic/deprecated/json.py | 8 ++++++-- pydantic/deprecated/parse.py | 2 +- pydantic/deprecated/tools.py | 6 +++--- tests/test_deprecated.py | 19 +++++++++++-------- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/pydantic/deprecated/json.py b/pydantic/deprecated/json.py index 49762c8ec2..c7fe924a52 100644 --- a/pydantic/deprecated/json.py +++ b/pydantic/deprecated/json.py @@ -78,7 +78,7 @@ def decimal_encoder(dec_value: Decimal) -> Union[int, float]: @deprecated( - 'pydantic_encoder is deprecated, use pydantic_core.to_jsonable_python instead.', + '`pydantic_encoder` is deprecated, use `pydantic_core.to_jsonable_python` instead.', category=PydanticDeprecatedSince20, stacklevel=2, ) @@ -104,7 +104,11 @@ def pydantic_encoder(obj: Any) -> Any: # TODO: Add a suggested migration path once there is a way to use custom encoders -@deprecated('custom_pydantic_encoder is deprecated.', category=PydanticDeprecatedSince20, stacklevel=2) +@deprecated( + '`custom_pydantic_encoder` is deprecated, use `BaseModel.model_dump` instead.', + category=PydanticDeprecatedSince20, + stacklevel=2, +) def custom_pydantic_encoder(type_encoders: Dict[Any, Callable[[Type[Any]], Any]], obj: Any) -> Any: # Check the class type and its superclasses for a matching encoder for base in obj.__class__.__mro__[:-1]: diff --git a/pydantic/deprecated/parse.py b/pydantic/deprecated/parse.py index 7e02d6c018..445bc451ec 100644 --- a/pydantic/deprecated/parse.py +++ b/pydantic/deprecated/parse.py @@ -54,7 +54,7 @@ def load_str_bytes( raise TypeError(f'Unknown protocol: {proto}') -@deprecated('load_file is deprecated.', category=PydanticDeprecatedSince20, stacklevel=2) +@deprecated('`load_file` is deprecated.', category=PydanticDeprecatedSince20, stacklevel=2) def load_file( path: str | Path, *, diff --git a/pydantic/deprecated/tools.py b/pydantic/deprecated/tools.py index 4ea6fff1cc..000a7e813a 100644 --- a/pydantic/deprecated/tools.py +++ b/pydantic/deprecated/tools.py @@ -24,7 +24,7 @@ @deprecated( - 'parse_obj_as is deprecated. Use pydantic.TypeAdapter.validate_python instead.', + '`parse_obj_as` is deprecated. Use `pydantic.TypeAdapter.validate_python` instead.', category=PydanticDeprecatedSince20, stacklevel=2, ) @@ -39,7 +39,7 @@ def parse_obj_as(type_: type[T], obj: Any, type_name: NameFactory | None = None) @deprecated( - 'schema_of is deprecated. Use pydantic.TypeAdapter.json_schema instead.', + '`schema_of` is deprecated. Use `pydantic.TypeAdapter.json_schema` instead.', category=PydanticDeprecatedSince20, stacklevel=2, ) @@ -71,7 +71,7 @@ def schema_of( @deprecated( - 'schema_json_of is deprecated. Use pydantic.TypeAdapter.json_schema instead.', + '`schema_json_of` is deprecated. Use `pydantic.TypeAdapter.json_schema` instead.', category=PydanticDeprecatedSince20, stacklevel=2, ) diff --git a/tests/test_deprecated.py b/tests/test_deprecated.py index 446cd151f2..fd05ce2923 100644 --- a/tests/test_deprecated.py +++ b/tests/test_deprecated.py @@ -698,7 +698,7 @@ def test_copy_and_set_values(): def test_get_value(): m = SimpleModel(x=1) - with pytest.warns(PydanticDeprecatedSince20, match='^The private method `_get_value` will be removed and '): + with pytest.warns(PydanticDeprecatedSince20, match='^The private method `_get_value` will be removed and '): v = m._get_value( [1, 2, 3], to_dict=False, @@ -718,41 +718,44 @@ class Model(BaseModel): assert hasattr(parse_obj_as, '__deprecated__') with pytest.warns( - PydanticDeprecatedSince20, match='parse_obj_as is deprecated. Use pydantic.TypeAdapter.validate_python instead.' + PydanticDeprecatedSince20, + match='`parse_obj_as` is deprecated. Use `pydantic.TypeAdapter.validate_python` instead.', ): parse_obj_as(Model, {'x': 1}) assert hasattr(schema_json_of, '__deprecated__') with pytest.warns( - PydanticDeprecatedSince20, match='schema_json_of is deprecated. Use pydantic.TypeAdapter.json_schema instead.' + PydanticDeprecatedSince20, + match='`schema_json_of` is deprecated. Use `pydantic.TypeAdapter.json_schema` instead.', ): schema_json_of(Model) assert hasattr(schema_of, '__deprecated__') with pytest.warns( - PydanticDeprecatedSince20, match='schema_of is deprecated. Use pydantic.TypeAdapter.json_schema instead.' + PydanticDeprecatedSince20, match='`schema_of` is deprecated. Use `pydantic.TypeAdapter.json_schema` instead.' ): schema_of(Model) assert hasattr(load_str_bytes, '__deprecated__') - with pytest.warns(PydanticDeprecatedSince20, match='load_str_bytes is deprecated.'): + with pytest.warns(PydanticDeprecatedSince20, match='`load_str_bytes` is deprecated.'): load_str_bytes('{"x": 1}') assert hasattr(load_file, '__deprecated__') file = tmp_path / 'main.py' file.write_text('{"x": 1}') - with pytest.warns(PydanticDeprecatedSince20, match='load_file is deprecated.'): + with pytest.warns(PydanticDeprecatedSince20, match='`load_file` is deprecated.'): load_file(file) assert hasattr(pydantic_encoder, '__deprecated__') with pytest.warns( - PydanticDeprecatedSince20, match='pydantic_encoder is deprecated, use pydantic_core.to_jsonable_python instead.' + PydanticDeprecatedSince20, + match='`pydantic_encoder` is deprecated, use `pydantic_core.to_jsonable_python` instead.', ): pydantic_encoder(Model(x=1)) assert hasattr(custom_pydantic_encoder, '__deprecated__') with pytest.warns( - PydanticDeprecatedSince20, match='custom_pydantic_encoder is deprecated, use BaseModel.model_dump instead.' + PydanticDeprecatedSince20, match='`custom_pydantic_encoder` is deprecated, use `BaseModel.model_dump` instead.' ): custom_pydantic_encoder({int: lambda x: str(x)}, Model(x=1)) From c52a122f71cfa19c6126c63da394d1fff60a7073 Mon Sep 17 00:00:00 2001 From: Viicos <65306057+Viicos@users.noreply.github.com> Date: Fri, 8 Dec 2023 17:27:33 +0100 Subject: [PATCH 06/13] Missed one --- pydantic/deprecated/parse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydantic/deprecated/parse.py b/pydantic/deprecated/parse.py index 445bc451ec..f055b84490 100644 --- a/pydantic/deprecated/parse.py +++ b/pydantic/deprecated/parse.py @@ -21,7 +21,7 @@ class Protocol(str, Enum): pickle = 'pickle' -@deprecated('load_str_bytes is deprecated.', category=PydanticDeprecatedSince20, stacklevel=2) +@deprecated('`load_str_bytes` is deprecated.', category=PydanticDeprecatedSince20, stacklevel=2) def load_str_bytes( b: str | bytes, *, From f7085042c634e3c65415d2c4af6761adef848c33 Mon Sep 17 00:00:00 2001 From: Viicos <65306057+Viicos@users.noreply.github.com> Date: Fri, 8 Dec 2023 17:31:11 +0100 Subject: [PATCH 07/13] Fix filter match --- tests/test_parse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_parse.py b/tests/test_parse.py index 60f568ba4a..93bbe5ced2 100644 --- a/tests/test_parse.py +++ b/tests/test_parse.py @@ -168,7 +168,7 @@ class MyModel(BaseModel): assert isinstance(m.nested.root[0], NestedData) -@pytest.mark.filterwarnings('ignore:parse_obj_as is deprecated.*:DeprecationWarning') +@pytest.mark.filterwarnings('ignore:`parse_obj_as` is deprecated.*:DeprecationWarning') def test_parse_nested_root_tuple(): class NestedData(BaseModel): id: str From 77ba925615ec3ad222805ed9774b4dad5a1caaf3 Mon Sep 17 00:00:00 2001 From: Viicos <65306057+Viicos@users.noreply.github.com> Date: Fri, 8 Dec 2023 17:51:46 +0100 Subject: [PATCH 08/13] Use `overload` from `typing_extensions` --- pydantic/deprecated/decorator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pydantic/deprecated/decorator.py b/pydantic/deprecated/decorator.py index 21bc088db1..d014a4d78a 100644 --- a/pydantic/deprecated/decorator.py +++ b/pydantic/deprecated/decorator.py @@ -1,7 +1,7 @@ from functools import wraps -from typing import TYPE_CHECKING, Any, Callable, Dict, List, Mapping, Optional, Tuple, Type, TypeVar, Union, overload +from typing import TYPE_CHECKING, Any, Callable, Dict, List, Mapping, Optional, Tuple, Type, TypeVar, Union -from typing_extensions import deprecated +from typing_extensions import deprecated, overload from .._internal import _config, _typing_extra from ..alias_generators import to_pascal From c300dbaba39b0307987fa5935c55133be61ba253 Mon Sep 17 00:00:00 2001 From: Viicos <65306057+Viicos@users.noreply.github.com> Date: Sun, 10 Dec 2023 20:55:28 +0100 Subject: [PATCH 09/13] Revert change on overload --- pydantic/deprecated/decorator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pydantic/deprecated/decorator.py b/pydantic/deprecated/decorator.py index d014a4d78a..21bc088db1 100644 --- a/pydantic/deprecated/decorator.py +++ b/pydantic/deprecated/decorator.py @@ -1,7 +1,7 @@ from functools import wraps -from typing import TYPE_CHECKING, Any, Callable, Dict, List, Mapping, Optional, Tuple, Type, TypeVar, Union +from typing import TYPE_CHECKING, Any, Callable, Dict, List, Mapping, Optional, Tuple, Type, TypeVar, Union, overload -from typing_extensions import deprecated, overload +from typing_extensions import deprecated from .._internal import _config, _typing_extra from ..alias_generators import to_pascal From f2670bd44af18916ca13a06a56f448f5423a562a Mon Sep 17 00:00:00 2001 From: Viicos <65306057+Viicos@users.noreply.github.com> Date: Sun, 10 Dec 2023 20:58:24 +0100 Subject: [PATCH 10/13] Remove assert --- tests/test_deprecated.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_deprecated.py b/tests/test_deprecated.py index fd05ce2923..3d6fc2e26b 100644 --- a/tests/test_deprecated.py +++ b/tests/test_deprecated.py @@ -763,7 +763,6 @@ class Model(BaseModel): with pytest.warns(PydanticDeprecatedSince20, match='timedelta_isoformat is deprecated.'): timedelta_isoformat(timedelta(seconds=1)) - assert all(hasattr(func, '__deprecated__') for func in get_overloads(validate_arguments)) with pytest.warns( PydanticDeprecatedSince20, match='The `validate_arguments` method is deprecated; use `validate_call` instead.' ): From b791cc02cc05c00ca9cf53a6e36aa77d8c43a175 Mon Sep 17 00:00:00 2001 From: Viicos <65306057+Viicos@users.noreply.github.com> Date: Sun, 10 Dec 2023 21:03:34 +0100 Subject: [PATCH 11/13] lint and update typing-extensions --- pdm.lock | 11 +++++------ tests/test_deprecated.py | 6 ------ 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/pdm.lock b/pdm.lock index b1c66e8f5c..360ba5894d 100644 --- a/pdm.lock +++ b/pdm.lock @@ -3,9 +3,8 @@ [metadata] groups = ["default", "docs", "email", "linting", "memray", "mypy", "testing", "testing-extra"] -cross_platform = true -static_urls = false -lock_version = "4.3" +strategy = ["cross_platform"] +lock_version = "4.4" content_hash = "sha256:140881c62bd18f4e3ad6e493e91b1058461fb64d32ceb785cb726ad5b4433bbc" [[package]] @@ -1694,12 +1693,12 @@ files = [ [[package]] name = "typing-extensions" -version = "4.8.0" +version = "4.9.0" requires_python = ">=3.8" summary = "Backported and Experimental Type Hints for Python 3.8+" files = [ - {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"}, - {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, + {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"}, + {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"}, ] [[package]] diff --git a/tests/test_deprecated.py b/tests/test_deprecated.py index 3d6fc2e26b..b7206605f6 100644 --- a/tests/test_deprecated.py +++ b/tests/test_deprecated.py @@ -1,6 +1,5 @@ import platform import re -import sys from datetime import date, timedelta from pathlib import Path from types import SimpleNamespace @@ -31,11 +30,6 @@ from pydantic.json_schema import JsonSchemaValue from pydantic.type_adapter import TypeAdapter -if sys.version_info < (3, 11): - from typing_extensions import get_overloads -else: - from typing import get_overloads - def deprecated_from_orm(model_type: Type[BaseModel], obj: Any) -> Any: with pytest.warns( From a7b9620b92e2d35573464d31aa48905e59423d84 Mon Sep 17 00:00:00 2001 From: Viicos <65306057+Viicos@users.noreply.github.com> Date: Fri, 15 Dec 2023 17:54:37 +0100 Subject: [PATCH 12/13] Restore runtime warnings, set decorator category to None --- pydantic/_internal/_model_construction.py | 7 +- pydantic/deprecated/decorator.py | 9 +- pydantic/deprecated/json.py | 20 +++- pydantic/deprecated/parse.py | 7 +- pydantic/deprecated/tools.py | 24 +++-- pydantic/main.py | 115 ++++++++++++++++------ 6 files changed, 134 insertions(+), 48 deletions(-) diff --git a/pydantic/_internal/_model_construction.py b/pydantic/_internal/_model_construction.py index fd2d6f70b8..e14202116c 100644 --- a/pydantic/_internal/_model_construction.py +++ b/pydantic/_internal/_model_construction.py @@ -242,10 +242,11 @@ def _collect_bases_data(bases: tuple[type[Any], ...]) -> tuple[set[str], set[str return field_names, class_vars, private_attributes @property - @deprecated( - 'The `__fields__` attribute is deprecated, use `model_fields` instead.', category=PydanticDeprecatedSince20 - ) + @deprecated('The `__fields__` attribute is deprecated, use `model_fields` instead.', category=None) def __fields__(self) -> dict[str, FieldInfo]: + warnings.warn( + 'The `__fields__` attribute is deprecated, use `model_fields` instead.', PydanticDeprecatedSince20 + ) return self.model_fields # type: ignore diff --git a/pydantic/deprecated/decorator.py b/pydantic/deprecated/decorator.py index 21bc088db1..36bd069001 100644 --- a/pydantic/deprecated/decorator.py +++ b/pydantic/deprecated/decorator.py @@ -1,3 +1,4 @@ +import warnings from functools import wraps from typing import TYPE_CHECKING, Any, Callable, Dict, List, Mapping, Optional, Tuple, Type, TypeVar, Union, overload @@ -36,11 +37,15 @@ def validate_arguments(func: 'AnyCallableT') -> 'AnyCallableT': @deprecated( 'The `validate_arguments` method is deprecated; use `validate_call` instead.', - category=PydanticDeprecatedSince20, - stacklevel=2, + category=None, ) def validate_arguments(func: Optional['AnyCallableT'] = None, *, config: 'ConfigType' = None) -> Any: """Decorator to validate the arguments passed to a function.""" + warnings.warn( + 'The `validate_arguments` method is deprecated; use `validate_call` instead.', + PydanticDeprecatedSince20, + stacklevel=2, + ) def validate(_func: 'AnyCallable') -> 'AnyCallable': vd = ValidatedFunction(_func, config) diff --git a/pydantic/deprecated/json.py b/pydantic/deprecated/json.py index c7fe924a52..8a02c1e583 100644 --- a/pydantic/deprecated/json.py +++ b/pydantic/deprecated/json.py @@ -1,6 +1,7 @@ import datetime from collections import deque from decimal import Decimal +import warnings from enum import Enum from ipaddress import IPv4Address, IPv4Interface, IPv4Network, IPv6Address, IPv6Interface, IPv6Network from pathlib import Path @@ -79,10 +80,14 @@ def decimal_encoder(dec_value: Decimal) -> Union[int, float]: @deprecated( '`pydantic_encoder` is deprecated, use `pydantic_core.to_jsonable_python` instead.', - category=PydanticDeprecatedSince20, - stacklevel=2, + category=None, ) def pydantic_encoder(obj: Any) -> Any: + warnings.warn( + '`pydantic_encoder` is deprecated, use `pydantic_core.to_jsonable_python` instead.', + category=PydanticDeprecatedSince20, + stacklevel=2, + ) from dataclasses import asdict, is_dataclass from ..main import BaseModel @@ -106,10 +111,14 @@ def pydantic_encoder(obj: Any) -> Any: # TODO: Add a suggested migration path once there is a way to use custom encoders @deprecated( '`custom_pydantic_encoder` is deprecated, use `BaseModel.model_dump` instead.', - category=PydanticDeprecatedSince20, - stacklevel=2, + category=None, ) def custom_pydantic_encoder(type_encoders: Dict[Any, Callable[[Type[Any]], Any]], obj: Any) -> Any: + warnings.warn( + '`custom_pydantic_encoder` is deprecated, use `BaseModel.model_dump` instead.', + category=PydanticDeprecatedSince20, + stacklevel=2, + ) # Check the class type and its superclasses for a matching encoder for base in obj.__class__.__mro__[:-1]: try: @@ -122,9 +131,10 @@ def custom_pydantic_encoder(type_encoders: Dict[Any, Callable[[Type[Any]], Any]] return pydantic_encoder(obj) -@deprecated('timedelta_isoformat is deprecated.', category=PydanticDeprecatedSince20, stacklevel=2) +@deprecated('`timedelta_isoformat` is deprecated.', category=None) def timedelta_isoformat(td: datetime.timedelta) -> str: """ISO 8601 encoding for Python timedelta object.""" + warnings.warn('`timedelta_isoformat` is deprecated.', category=PydanticDeprecatedSince20, stacklevel=2) minutes, seconds = divmod(td.seconds, 60) hours, minutes = divmod(minutes, 60) return f'{"-" if td.days < 0 else ""}P{abs(td.days)}DT{hours:d}H{minutes:d}M{seconds:d}.{td.microseconds:06d}S' diff --git a/pydantic/deprecated/parse.py b/pydantic/deprecated/parse.py index f055b84490..88db208787 100644 --- a/pydantic/deprecated/parse.py +++ b/pydantic/deprecated/parse.py @@ -1,5 +1,6 @@ from __future__ import annotations +import warnings import json import pickle from enum import Enum @@ -21,7 +22,7 @@ class Protocol(str, Enum): pickle = 'pickle' -@deprecated('`load_str_bytes` is deprecated.', category=PydanticDeprecatedSince20, stacklevel=2) +@deprecated('`load_str_bytes` is deprecated.', category=None) def load_str_bytes( b: str | bytes, *, @@ -31,6 +32,7 @@ def load_str_bytes( allow_pickle: bool = False, json_loads: Callable[[str], Any] = json.loads, ) -> Any: + warnings.warn('`load_str_bytes` is deprecated.', category=PydanticDeprecatedSince20, stacklevel=2) if proto is None and content_type: if content_type.endswith(('json', 'javascript')): pass @@ -54,7 +56,7 @@ def load_str_bytes( raise TypeError(f'Unknown protocol: {proto}') -@deprecated('`load_file` is deprecated.', category=PydanticDeprecatedSince20, stacklevel=2) +@deprecated('`load_file` is deprecated.', category=None) def load_file( path: str | Path, *, @@ -64,6 +66,7 @@ def load_file( allow_pickle: bool = False, json_loads: Callable[[str], Any] = json.loads, ) -> Any: + warnings.warn('`load_file` is deprecated.', category=PydanticDeprecatedSince20, stacklevel=2) path = Path(path) b = path.read_bytes() if content_type is None: diff --git a/pydantic/deprecated/tools.py b/pydantic/deprecated/tools.py index 000a7e813a..b04eae400f 100644 --- a/pydantic/deprecated/tools.py +++ b/pydantic/deprecated/tools.py @@ -25,10 +25,14 @@ @deprecated( '`parse_obj_as` is deprecated. Use `pydantic.TypeAdapter.validate_python` instead.', - category=PydanticDeprecatedSince20, - stacklevel=2, + category=None, ) def parse_obj_as(type_: type[T], obj: Any, type_name: NameFactory | None = None) -> T: + warnings.warn( + '`parse_obj_as` is deprecated. Use `pydantic.TypeAdapter.validate_python` instead.', + category=PydanticDeprecatedSince20, + stacklevel=2, + ) if type_name is not None: # pragma: no cover warnings.warn( 'The type_name parameter is deprecated. parse_obj_as no longer creates temporary models', @@ -40,8 +44,7 @@ def parse_obj_as(type_: type[T], obj: Any, type_name: NameFactory | None = None) @deprecated( '`schema_of` is deprecated. Use `pydantic.TypeAdapter.json_schema` instead.', - category=PydanticDeprecatedSince20, - stacklevel=2, + category=None, ) def schema_of( type_: Any, @@ -52,6 +55,11 @@ def schema_of( schema_generator: type[GenerateJsonSchema] = GenerateJsonSchema, ) -> dict[str, Any]: """Generate a JSON schema (as dict) for the passed model or dynamically generated one.""" + warnings.warn( + '`schema_of` is deprecated. Use `pydantic.TypeAdapter.json_schema` instead.', + category=PydanticDeprecatedSince20, + stacklevel=2, + ) res = TypeAdapter(type_).json_schema( by_alias=by_alias, schema_generator=schema_generator, @@ -72,8 +80,7 @@ def schema_of( @deprecated( '`schema_json_of` is deprecated. Use `pydantic.TypeAdapter.json_schema` instead.', - category=PydanticDeprecatedSince20, - stacklevel=2, + category=None, ) def schema_json_of( type_: Any, @@ -85,6 +92,11 @@ def schema_json_of( **dumps_kwargs: Any, ) -> str: """Generate a JSON schema (as JSON) for the passed model or dynamically generated one.""" + warnings.warn( + '`schema_json_of` is deprecated. Use `pydantic.TypeAdapter.json_schema` instead.', + category=PydanticDeprecatedSince20, + stacklevel=2, + ) return json.dumps( schema_of(type_, title=title, by_alias=by_alias, ref_template=ref_template, schema_generator=schema_generator), **dumps_kwargs, diff --git a/pydantic/main.py b/pydantic/main.py index 1f31a1d79a..f433e74f59 100644 --- a/pydantic/main.py +++ b/pydantic/main.py @@ -984,22 +984,27 @@ def __str__(self) -> str: # ##### Deprecated methods from v1 ##### @property @typing_extensions.deprecated( - 'The `__fields__` attribute is deprecated, use `model_fields` instead.', category=PydanticDeprecatedSince20 + 'The `__fields__` attribute is deprecated, use `model_fields` instead.', category=None ) def __fields__(self) -> dict[str, FieldInfo]: + warnings.warn( + 'The `__fields__` attribute is deprecated, use `model_fields` instead.', category=PydanticDeprecatedSince20 + ) return self.model_fields @property @typing_extensions.deprecated( 'The `__fields_set__` attribute is deprecated, use `model_fields_set` instead.', - category=PydanticDeprecatedSince20, + category=None, ) def __fields_set__(self) -> set[str]: + warnings.warn( + 'The `__fields_set__` attribute is deprecated, use `model_fields_set` instead.', + category=PydanticDeprecatedSince20, + ) return self.__pydantic_fields_set__ - @typing_extensions.deprecated( - 'The `dict` method is deprecated; use `model_dump` instead.', category=PydanticDeprecatedSince20 - ) + @typing_extensions.deprecated('The `dict` method is deprecated; use `model_dump` instead.', category=None) def dict( # noqa: D102 self, *, @@ -1010,6 +1015,7 @@ def dict( # noqa: D102 exclude_defaults: bool = False, exclude_none: bool = False, ) -> typing.Dict[str, Any]: # noqa UP006 + warnings.warn('The `dict` method is deprecated; use `model_dump` instead.', category=PydanticDeprecatedSince20) return self.model_dump( include=include, exclude=exclude, @@ -1019,9 +1025,7 @@ def dict( # noqa: D102 exclude_none=exclude_none, ) - @typing_extensions.deprecated( - 'The `json` method is deprecated; use `model_dump_json` instead.', category=PydanticDeprecatedSince20 - ) + @typing_extensions.deprecated('The `json` method is deprecated; use `model_dump_json` instead.', category=None) def json( # noqa: D102 self, *, @@ -1035,6 +1039,9 @@ def json( # noqa: D102 models_as_dict: bool = PydanticUndefined, # type: ignore[assignment] **dumps_kwargs: Any, ) -> str: + warnings.warn( + 'The `json` method is deprecated; use `model_dump_json` instead.', category=PydanticDeprecatedSince20 + ) if encoder is not PydanticUndefined: raise TypeError('The `encoder` argument is no longer supported; use field serializers instead.') if models_as_dict is not PydanticUndefined: @@ -1051,17 +1058,18 @@ def json( # noqa: D102 ) @classmethod - @typing_extensions.deprecated( - 'The `parse_obj` method is deprecated; use `model_validate` instead.', category=PydanticDeprecatedSince20 - ) + @typing_extensions.deprecated('The `parse_obj` method is deprecated; use `model_validate` instead.', category=None) def parse_obj(cls: type[Model], obj: Any) -> Model: # noqa: D102 + warnings.warn( + 'The `parse_obj` method is deprecated; use `model_validate` instead.', category=PydanticDeprecatedSince20 + ) return cls.model_validate(obj) @classmethod @typing_extensions.deprecated( 'The `parse_raw` method is deprecated; if your data is JSON use `model_validate_json`, ' 'otherwise load the data then use `model_validate` instead.', - category=PydanticDeprecatedSince20, + category=None, ) def parse_raw( # noqa: D102 cls: type[Model], @@ -1072,6 +1080,11 @@ def parse_raw( # noqa: D102 proto: DeprecatedParseProtocol | None = None, allow_pickle: bool = False, ) -> Model: # pragma: no cover + warnings.warn( + 'The `parse_raw` method is deprecated; if your data is JSON use `model_validate_json`, ' + 'otherwise load the data then use `model_validate` instead.', + category=PydanticDeprecatedSince20, + ) from .deprecated import parse try: @@ -1109,7 +1122,7 @@ def parse_raw( # noqa: D102 @typing_extensions.deprecated( 'The `parse_file` method is deprecated; load the data from file, then if your data is JSON ' 'use `model_validate_json`, otherwise `model_validate` instead.', - category=PydanticDeprecatedSince20, + category=None, ) def parse_file( # noqa: D102 cls: type[Model], @@ -1120,6 +1133,11 @@ def parse_file( # noqa: D102 proto: DeprecatedParseProtocol | None = None, allow_pickle: bool = False, ) -> Model: + warnings.warn( + 'The `parse_file` method is deprecated; load the data from file, then if your data is JSON ' + 'use `model_validate_json`, otherwise `model_validate` instead.', + category=PydanticDeprecatedSince20, + ) from .deprecated import parse obj = parse.load_file( @@ -1135,9 +1153,14 @@ def parse_file( # noqa: D102 @typing_extensions.deprecated( 'The `from_orm` method is deprecated; set ' "`model_config['from_attributes']=True` and use `model_validate` instead.", - category=PydanticDeprecatedSince20, + category=None, ) def from_orm(cls: type[Model], obj: Any) -> Model: # noqa: D102 + warnings.warn( + 'The `from_orm` method is deprecated; set ' + "`model_config['from_attributes']=True` and use `model_validate` instead.", + category=PydanticDeprecatedSince20, + ) if not cls.model_config.get('from_attributes', None): raise PydanticUserError( 'You must set the config attribute `from_attributes=True` to use from_orm', code=None @@ -1145,16 +1168,17 @@ def from_orm(cls: type[Model], obj: Any) -> Model: # noqa: D102 return cls.model_validate(obj) @classmethod - @typing_extensions.deprecated( - 'The `construct` method is deprecated; use `model_construct` instead.', category=PydanticDeprecatedSince20 - ) + @typing_extensions.deprecated('The `construct` method is deprecated; use `model_construct` instead.', category=None) def construct(cls: type[Model], _fields_set: set[str] | None = None, **values: Any) -> Model: # noqa: D102 + warnings.warn( + 'The `construct` method is deprecated; use `model_construct` instead.', category=PydanticDeprecatedSince20 + ) return cls.model_construct(_fields_set=_fields_set, **values) @typing_extensions.deprecated( 'The `copy` method is deprecated; use `model_copy` instead. ' 'See the docstring of `BaseModel.copy` for details about how to handle `include` and `exclude`.', - category=PydanticDeprecatedSince20, + category=None, ) def copy( self: Model, @@ -1189,6 +1213,11 @@ def copy( Returns: A copy of the model with included, excluded and updated fields as specified. """ + warnings.warn( + 'The `copy` method is deprecated; use `model_copy` instead. ' + 'See the docstring of `BaseModel.copy` for details about how to handle `include` and `exclude`.', + category=PydanticDeprecatedSince20, + ) from .deprecated import copy_internals values = dict( @@ -1226,22 +1255,27 @@ def copy( return copy_internals._copy_and_set_values(self, values, fields_set, extra, private, deep=deep) @classmethod - @typing_extensions.deprecated( - 'The `schema` method is deprecated; use `model_json_schema` instead.', category=PydanticDeprecatedSince20 - ) + @typing_extensions.deprecated('The `schema` method is deprecated; use `model_json_schema` instead.', category=None) def schema( # noqa: D102 cls, by_alias: bool = True, ref_template: str = DEFAULT_REF_TEMPLATE ) -> typing.Dict[str, Any]: # noqa UP006 + warnings.warn( + 'The `schema` method is deprecated; use `model_json_schema` instead.', category=PydanticDeprecatedSince20 + ) return cls.model_json_schema(by_alias=by_alias, ref_template=ref_template) @classmethod @typing_extensions.deprecated( 'The `schema_json` method is deprecated; use `model_json_schema` and json.dumps instead.', - category=PydanticDeprecatedSince20, + category=None, ) def schema_json( # noqa: D102 cls, *, by_alias: bool = True, ref_template: str = DEFAULT_REF_TEMPLATE, **dumps_kwargs: Any ) -> str: # pragma: no cover + warnings.warn( + 'The `schema_json` method is deprecated; use `model_json_schema` and json.dumps instead.', + category=PydanticDeprecatedSince20, + ) import json from .deprecated.json import pydantic_encoder @@ -1253,35 +1287,48 @@ def schema_json( # noqa: D102 ) @classmethod - @typing_extensions.deprecated( - 'The `validate` method is deprecated; use `model_validate` instead.', category=PydanticDeprecatedSince20 - ) + @typing_extensions.deprecated('The `validate` method is deprecated; use `model_validate` instead.', category=None) def validate(cls: type[Model], value: Any) -> Model: # noqa: D102 + warnings.warn( + 'The `validate` method is deprecated; use `model_validate` instead.', category=PydanticDeprecatedSince20 + ) return cls.model_validate(value) @classmethod @typing_extensions.deprecated( 'The `update_forward_refs` method is deprecated; use `model_rebuild` instead.', - category=PydanticDeprecatedSince20, + category=None, ) def update_forward_refs(cls, **localns: Any) -> None: # noqa: D102 + warnings.warn( + 'The `update_forward_refs` method is deprecated; use `model_rebuild` instead.', + category=PydanticDeprecatedSince20, + ) if localns: # pragma: no cover raise TypeError('`localns` arguments are not longer accepted.') cls.model_rebuild(force=True) @typing_extensions.deprecated( - 'The private method `_iter` will be removed and should no longer be used.', category=PydanticDeprecatedSince20 + 'The private method `_iter` will be removed and should no longer be used.', category=None ) def _iter(self, *args: Any, **kwargs: Any) -> Any: + warnings.warn( + 'The private method `_iter` will be removed and should no longer be used.', + category=PydanticDeprecatedSince20, + ) from .deprecated import copy_internals return copy_internals._iter(self, *args, **kwargs) @typing_extensions.deprecated( 'The private method `_copy_and_set_values` will be removed and should no longer be used.', - category=PydanticDeprecatedSince20, + category=None, ) def _copy_and_set_values(self, *args: Any, **kwargs: Any) -> Any: + warnings.warn( + 'The private method `_copy_and_set_values` will be removed and should no longer be used.', + category=PydanticDeprecatedSince20, + ) from .deprecated import copy_internals return copy_internals._copy_and_set_values(self, *args, **kwargs) @@ -1289,18 +1336,26 @@ def _copy_and_set_values(self, *args: Any, **kwargs: Any) -> Any: @classmethod @typing_extensions.deprecated( 'The private method `_get_value` will be removed and should no longer be used.', - category=PydanticDeprecatedSince20, + category=None, ) def _get_value(cls, *args: Any, **kwargs: Any) -> Any: + warnings.warn( + 'The private method `_get_value` will be removed and should no longer be used.', + category=PydanticDeprecatedSince20, + ) from .deprecated import copy_internals return copy_internals._get_value(cls, *args, **kwargs) @typing_extensions.deprecated( 'The private method `_calculate_keys` will be removed and should no longer be used.', - category=PydanticDeprecatedSince20, + category=None, ) def _calculate_keys(self, *args: Any, **kwargs: Any) -> Any: + warnings.warn( + 'The private method `_calculate_keys` will be removed and should no longer be used.', + category=PydanticDeprecatedSince20, + ) from .deprecated import copy_internals return copy_internals._calculate_keys(self, *args, **kwargs) From 215e8b7039209c9f82bd6fe47e23518dda25240d Mon Sep 17 00:00:00 2001 From: Viicos <65306057+Viicos@users.noreply.github.com> Date: Thu, 21 Dec 2023 10:46:04 +0100 Subject: [PATCH 13/13] last fixes --- pydantic/deprecated/json.py | 2 +- pydantic/deprecated/parse.py | 2 +- tests/test_deprecated.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pydantic/deprecated/json.py b/pydantic/deprecated/json.py index 8a02c1e583..79e2f44a9d 100644 --- a/pydantic/deprecated/json.py +++ b/pydantic/deprecated/json.py @@ -1,7 +1,7 @@ import datetime +import warnings from collections import deque from decimal import Decimal -import warnings from enum import Enum from ipaddress import IPv4Address, IPv4Interface, IPv4Network, IPv6Address, IPv6Interface, IPv6Network from pathlib import Path diff --git a/pydantic/deprecated/parse.py b/pydantic/deprecated/parse.py index 88db208787..2a92e62b7b 100644 --- a/pydantic/deprecated/parse.py +++ b/pydantic/deprecated/parse.py @@ -1,8 +1,8 @@ from __future__ import annotations -import warnings import json import pickle +import warnings from enum import Enum from pathlib import Path from typing import TYPE_CHECKING, Any, Callable diff --git a/tests/test_deprecated.py b/tests/test_deprecated.py index b7206605f6..55ee14aa75 100644 --- a/tests/test_deprecated.py +++ b/tests/test_deprecated.py @@ -754,7 +754,7 @@ class Model(BaseModel): custom_pydantic_encoder({int: lambda x: str(x)}, Model(x=1)) assert hasattr(timedelta_isoformat, '__deprecated__') - with pytest.warns(PydanticDeprecatedSince20, match='timedelta_isoformat is deprecated.'): + with pytest.warns(PydanticDeprecatedSince20, match='`timedelta_isoformat` is deprecated.'): timedelta_isoformat(timedelta(seconds=1)) with pytest.warns(