Skip to content

Commit 9c95538

Browse files
committed
fix: robust synthetic property handling for mapped variants
- Refactored MappedVariant view models to ensure robust handling of synthetic and required fields for both ORM and dict contexts. - Added tests to verify all key attributes and synthetic properties are correctly handled in both construction modes. - Ensured creation from both dict and ORM contexts, mirroring the approach used for other models.
1 parent 49fe927 commit 9c95538

File tree

2 files changed

+33
-9
lines changed

2 files changed

+33
-9
lines changed

src/mavedb/view_models/mapped_variant.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,16 @@ class SavedMappedVariant(MappedVariantBase):
5555
class Config:
5656
from_attributes = True
5757

58+
# These 'synthetic' fields are generated from other model properties. Transform data from other properties as needed, setting
59+
# the appropriate field on the model itself. Then, proceed with Pydantic ingestion once fields are created. Only perform these
60+
# transformations if the relevant attributes are present on the input data (i.e., when creating from an ORM object).
5861
@model_validator(mode="before")
5962
def generate_score_set_urn_list(cls, data: Any):
60-
if not hasattr(data, "variant_urn") and hasattr(data, "variant"):
63+
if hasattr(data, "variant"):
6164
try:
6265
data.__setattr__("variant_urn", None if not data.variant else data.variant.urn)
63-
except AttributeError as exc:
64-
raise ValidationError(f"Unable to create {cls.__name__} without attribute: {exc}.") # type: ignore
66+
except (AttributeError, KeyError) as exc:
67+
raise ValidationError(f"Unable to coerce variant urn for {cls.__name__}: {exc}.") # type: ignore
6568
return data
6669

6770

@@ -97,8 +100,8 @@ def generate_score_set_urn_list(cls, data: Any):
97100

98101

99102
# ruff: noqa: E402
100-
from mavedb.view_models.clinical_control import ClinicalControlBase, ClinicalControl, SavedClinicalControl
101-
from mavedb.view_models.gnomad_variant import GnomADVariantBase, GnomADVariant, SavedGnomADVariant
103+
from mavedb.view_models.clinical_control import ClinicalControl, ClinicalControlBase, SavedClinicalControl
104+
from mavedb.view_models.gnomad_variant import GnomADVariant, GnomADVariantBase, SavedGnomADVariant
102105

103106
MappedVariantUpdate.model_rebuild()
104107
SavedMappedVariantWithControls.model_rebuild()

tests/view_models/test_mapped_variant.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import pytest
22
from pydantic import ValidationError
33

4-
from mavedb.view_models.mapped_variant import MappedVariantCreate, MappedVariant
5-
6-
from tests.helpers.util.common import dummy_attributed_object_from_dict
4+
from mavedb.view_models.mapped_variant import MappedVariant, MappedVariantCreate
75
from tests.helpers.constants import TEST_MINIMAL_MAPPED_VARIANT, TEST_MINIMAL_MAPPED_VARIANT_CREATE, VALID_VARIANT_URN
6+
from tests.helpers.util.common import dummy_attributed_object_from_dict
87

98

109
def test_minimal_mapped_variant_create():
@@ -72,10 +71,32 @@ def test_cannot_create_mapped_variant_without_variant():
7271
MappedVariantCreate(**mapped_variant_create)
7372

7473

74+
def test_can_create_saved_mapped_variant_with_variant_object():
75+
mapped_variant = TEST_MINIMAL_MAPPED_VARIANT.copy()
76+
mapped_variant["id"] = 1
77+
78+
saved_mapped_variant = MappedVariant.model_validate(
79+
dummy_attributed_object_from_dict(
80+
{**mapped_variant, "variant": dummy_attributed_object_from_dict({"urn": VALID_VARIANT_URN})}
81+
)
82+
)
83+
84+
assert all(saved_mapped_variant.__getattribute__(k) == v for k, v in mapped_variant.items())
85+
assert saved_mapped_variant.variant_urn == VALID_VARIANT_URN
86+
87+
7588
def test_cannot_save_mapped_variant_without_variant():
7689
mapped_variant = TEST_MINIMAL_MAPPED_VARIANT.copy()
7790
mapped_variant["id"] = 1
78-
mapped_variant["variant"] = dummy_attributed_object_from_dict({"urn": None})
91+
mapped_variant["variant"] = None
7992

8093
with pytest.raises(ValidationError):
8194
MappedVariant.model_validate(dummy_attributed_object_from_dict({**mapped_variant}))
95+
96+
97+
def test_can_create_mapped_variant_from_non_orm_context():
98+
mapped_variant_create = TEST_MINIMAL_MAPPED_VARIANT_CREATE.copy()
99+
mapped_variant_create["variant_urn"] = VALID_VARIANT_URN
100+
created_mapped_variant = MappedVariantCreate.model_validate(mapped_variant_create)
101+
102+
assert all(created_mapped_variant.__getattribute__(k) == v for k, v in mapped_variant_create.items())

0 commit comments

Comments
 (0)