This is an automated email from the ASF dual-hosted git repository. potiuk pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push: new 30f56020f7 Use `model_validate` instead of `parse_obj` for de-serialize Pydantic V2 model (#38999) 30f56020f7 is described below commit 30f56020f74e88743eec7b225c9ac632cc356c41 Author: Andrey Anshin <andrey.ans...@taragol.is> AuthorDate: Sun Apr 14 17:16:34 2024 +0400 Use `model_validate` instead of `parse_obj` for de-serialize Pydantic V2 model (#38999) --- airflow/serialization/serialized_objects.py | 12 ++++---- tests/serialization/test_serialized_objects.py | 40 ++++++++++++++------------ 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/airflow/serialization/serialized_objects.py b/airflow/serialization/serialized_objects.py index 9cc1d41931..8dd7465c5f 100644 --- a/airflow/serialization/serialized_objects.py +++ b/airflow/serialization/serialized_objects.py @@ -702,17 +702,17 @@ class BaseSerialization: return Connection(**var) elif use_pydantic_models and _ENABLE_AIP_44: if type_ == DAT.BASE_JOB: - return JobPydantic.parse_obj(var) + return JobPydantic.model_validate(var) elif type_ == DAT.TASK_INSTANCE: - return TaskInstancePydantic.parse_obj(var) + return TaskInstancePydantic.model_validate(var) elif type_ == DAT.DAG_RUN: - return DagRunPydantic.parse_obj(var) + return DagRunPydantic.model_validate(var) elif type_ == DAT.DAG_MODEL: - return DagModelPydantic.parse_obj(var) + return DagModelPydantic.model_validate(var) elif type_ == DAT.DATA_SET: - return DatasetPydantic.parse_obj(var) + return DatasetPydantic.model_validate(var) elif type_ == DAT.LOG_TEMPLATE: - return LogTemplatePydantic.parse_obj(var) + return LogTemplatePydantic.model_validate(var) elif type_ == DAT.ARG_NOT_SET: return NOTSET else: diff --git a/tests/serialization/test_serialized_objects.py b/tests/serialization/test_serialized_objects.py index 1491a02dc2..bfeff47627 100644 --- a/tests/serialization/test_serialized_objects.py +++ b/tests/serialization/test_serialized_objects.py @@ -19,6 +19,7 @@ from __future__ import annotations import inspect import json +import warnings from datetime import datetime, timedelta from importlib import import_module @@ -311,28 +312,31 @@ sample_objects = { ) def test_serialize_deserialize_pydantic(input, pydantic_class, encoded_type, cmp_func): """If use_pydantic_models=True the objects should be serialized to Pydantic objects.""" - pytest.importorskip("pydantic", minversion="2.0.0") + pydantic = pytest.importorskip("pydantic", minversion="2.0.0") from airflow.serialization.serialized_objects import BaseSerialization - serialized = BaseSerialization.serialize(input, use_pydantic_models=True) # does not raise - # Verify the result is JSON-serializable - json.dumps(serialized) # does not raise - assert serialized["__type"] == encoded_type - assert serialized["__var"] is not None - deserialized = BaseSerialization.deserialize(serialized, use_pydantic_models=True) - assert isinstance(deserialized, pydantic_class) - assert cmp_func(input, deserialized) - - # verify that when we round trip a pydantic model we get the same thing - reserialized = BaseSerialization.serialize(deserialized, use_pydantic_models=True) - dereserialized = BaseSerialization.deserialize(reserialized, use_pydantic_models=True) - assert isinstance(dereserialized, pydantic_class) - assert dereserialized == deserialized + with warnings.catch_warnings(): + warnings.simplefilter("error", category=pydantic.warnings.PydanticDeprecationWarning) - # Verify recursive behavior - obj = [[input]] - BaseSerialization.serialize(obj, use_pydantic_models=True) # does not raise + serialized = BaseSerialization.serialize(input, use_pydantic_models=True) # does not raise + # Verify the result is JSON-serializable + json.dumps(serialized) # does not raise + assert serialized["__type"] == encoded_type + assert serialized["__var"] is not None + deserialized = BaseSerialization.deserialize(serialized, use_pydantic_models=True) + assert isinstance(deserialized, pydantic_class) + assert cmp_func(input, deserialized) + + # verify that when we round trip a pydantic model we get the same thing + reserialized = BaseSerialization.serialize(deserialized, use_pydantic_models=True) + dereserialized = BaseSerialization.deserialize(reserialized, use_pydantic_models=True) + assert isinstance(dereserialized, pydantic_class) + assert dereserialized == deserialized + + # Verify recursive behavior + obj = [[input]] + BaseSerialization.serialize(obj, use_pydantic_models=True) # does not raise def test_all_pydantic_models_round_trip():