From cd4480ff537f1675cc306b52f00f6dc950e9ba19 Mon Sep 17 00:00:00 2001 From: Tim Jenness Date: Fri, 4 Aug 2023 16:05:46 -0700 Subject: [PATCH] Change file formatter to support v1 and v2 pydantic constructors The pydantic models that use the v1 compatibility class work fine with model_validate but there are some v1 models that do not inherit from that and also some classes like ScarletModelData that emulate the pydantic v1 methods but are not using pydantic. Therefore we need to still check parse_obj. --- python/lsst/daf/butler/formatters/file.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/python/lsst/daf/butler/formatters/file.py b/python/lsst/daf/butler/formatters/file.py index 8d6eb40ee1..a03fad5820 100644 --- a/python/lsst/daf/butler/formatters/file.py +++ b/python/lsst/daf/butler/formatters/file.py @@ -175,10 +175,12 @@ def _coerceBuiltinType(self, inMemoryDataset: Any, writeStorageClass: StorageCla and type(inMemoryDataset).__module__ == "builtins" ): # Try different ways of converting to the required type. - if hasattr(writeStorageClass.pytype, "model_validate"): - # This is for a Pydantic model. - inMemoryDataset = writeStorageClass.pytype.model_validate(inMemoryDataset) - elif isinstance(inMemoryDataset, dict): + # Pydantic v1 uses parse_obj and some non-pydantic classes + # use that convention. Pydantic v2 uses model_validate. + for method_name in ("model_validate", "parse_obj"): + if method := getattr(writeStorageClass.pytype, method_name, None): + return method(inMemoryDataset) + if isinstance(inMemoryDataset, dict): if dataclasses.is_dataclass(writeStorageClass.pytype): # Dataclasses accept key/value parameters. inMemoryDataset = writeStorageClass.pytype(**inMemoryDataset)