diff --git a/src/fmu/dataio/datastructure/meta/content.py b/src/fmu/dataio/datastructure/meta/content.py index 207475b6c..f1d57bd65 100644 --- a/src/fmu/dataio/datastructure/meta/content.py +++ b/src/fmu/dataio/datastructure/meta/content.py @@ -1,5 +1,6 @@ from __future__ import annotations +import warnings from typing import Any, Dict, List, Literal, Optional, Union from pydantic import ( @@ -9,6 +10,7 @@ GetJsonSchemaHandler, NaiveDatetime, RootModel, + field_validator, model_validator, ) from pydantic_core import CoreSchema @@ -78,6 +80,18 @@ class FluidContact(BaseModel): ) truncated: bool = Field(default=False) + @field_validator("contact", mode="before") + def contact_to_lowercase(cls, v: str) -> str: + if any(c.isupper() for c in v): + warnings.warn( + f"You've defined the fluid contact as '{v}' which contains uppercase " + "characters. In a future version we may require that fluid contacts " + "should be all lowercase. To ensure future compatibility you should " + f"change this value to '{v.lower()}'.", + UserWarning, + ) + return v.lower() + class FieldOutline(BaseModel): """ diff --git a/src/fmu/dataio/types.py b/src/fmu/dataio/types.py index 8eb337b7b..ffed03189 100644 --- a/src/fmu/dataio/types.py +++ b/src/fmu/dataio/types.py @@ -50,7 +50,6 @@ class PolygonsProxy(Polygons): ... "Collection of 'inferrable' objects with metadata deduction capabilities", ] - Parameters: TypeAlias = Annotated[ MutableMapping[str, Union[str, float, int, None, "Parameters"]], "Nested or flat configurations for dynamically structured parameters.", diff --git a/tests/test_units/test_contents.py b/tests/test_units/test_contents.py index b40f1437d..79f056bd4 100644 --- a/tests/test_units/test_contents.py +++ b/tests/test_units/test_contents.py @@ -1,6 +1,8 @@ """Explicitly test all allowed contents.""" +import pytest from fmu.dataio.dataio import ExportData +from pydantic import ValidationError # generic testing of functionality related to content is done elsewhere, # mainly in test_dataio.py. @@ -66,6 +68,28 @@ def test_content_fluid_contact(regsurf, globalconfig2): assert meta["data"]["content"] == "fluid_contact" +def test_content_fluid_contact_case_insensitive(regsurf, globalconfig2): + """Test export of the fluid_contact content.""" + with pytest.warns(UserWarning, match=r"contains uppercase.+value to 'owc'"): + meta = ExportData( + config=globalconfig2, + name="MyName", + content={"fluid_contact": {"contact": "OWC"}}, + ).generate_metadata(regsurf) + + assert meta["data"]["fluid_contact"]["contact"] == "owc" + + +def test_content_fluid_contact_raises_on_invalid_contact(regsurf, globalconfig2): + """Test export of the fluid_contact content.""" + with pytest.raises(ValidationError, match="fluid_contact"): + ExportData( + config=globalconfig2, + name="MyName", + content={"fluid_contact": {"contact": "OEC"}}, + ).generate_metadata(regsurf) + + def test_content_kh_product(regsurf, globalconfig2): """Test export of the khproduct content.""" meta = ExportData(