From 0f9bfb6eeeca7a9d4d75f379b1c4512d05b32538 Mon Sep 17 00:00:00 2001 From: Sebastian Echeverria Date: Fri, 13 Dec 2024 19:20:36 -0500 Subject: [PATCH] Validator: added recording of bool expression source code as string for tracking purposes --- .../assets/schema/artifact/spec/v0.0.1/schema.json | 14 +++++++++++++- .../schema/artifact/validated/v0.0.1/schema.json | 14 +++++++++++++- mlte/schema/artifact/spec/v0.0.1/schema.json | 14 +++++++++++++- mlte/schema/artifact/validated/v0.0.1/schema.json | 14 +++++++++++++- mlte/validation/model_condition.py | 3 +++ mlte/validation/validator.py | 7 +++++++ test/spec/test_condition.py | 11 +++++++++++ test/validation/test_validator.py | 2 ++ 8 files changed, 75 insertions(+), 4 deletions(-) diff --git a/mlte/frontend/nuxt-app/assets/schema/artifact/spec/v0.0.1/schema.json b/mlte/frontend/nuxt-app/assets/schema/artifact/spec/v0.0.1/schema.json index 5e368d53..0e2037e3 100644 --- a/mlte/frontend/nuxt-app/assets/schema/artifact/spec/v0.0.1/schema.json +++ b/mlte/frontend/nuxt-app/assets/schema/artifact/spec/v0.0.1/schema.json @@ -133,13 +133,25 @@ } ], "title": "Info" + }, + "bool_exp_str": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Bool Exp Str" } }, "required": [ "bool_exp", "success", "failure", - "info" + "info", + "bool_exp_str" ], "title": "ValidatorModel", "type": "object" diff --git a/mlte/frontend/nuxt-app/assets/schema/artifact/validated/v0.0.1/schema.json b/mlte/frontend/nuxt-app/assets/schema/artifact/validated/v0.0.1/schema.json index 5e346a5e..1c2266bb 100644 --- a/mlte/frontend/nuxt-app/assets/schema/artifact/validated/v0.0.1/schema.json +++ b/mlte/frontend/nuxt-app/assets/schema/artifact/validated/v0.0.1/schema.json @@ -231,13 +231,25 @@ } ], "title": "Info" + }, + "bool_exp_str": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Bool Exp Str" } }, "required": [ "bool_exp", "success", "failure", - "info" + "info", + "bool_exp_str" ], "title": "ValidatorModel", "type": "object" diff --git a/mlte/schema/artifact/spec/v0.0.1/schema.json b/mlte/schema/artifact/spec/v0.0.1/schema.json index 5e368d53..0e2037e3 100644 --- a/mlte/schema/artifact/spec/v0.0.1/schema.json +++ b/mlte/schema/artifact/spec/v0.0.1/schema.json @@ -133,13 +133,25 @@ } ], "title": "Info" + }, + "bool_exp_str": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Bool Exp Str" } }, "required": [ "bool_exp", "success", "failure", - "info" + "info", + "bool_exp_str" ], "title": "ValidatorModel", "type": "object" diff --git a/mlte/schema/artifact/validated/v0.0.1/schema.json b/mlte/schema/artifact/validated/v0.0.1/schema.json index 5e346a5e..1c2266bb 100644 --- a/mlte/schema/artifact/validated/v0.0.1/schema.json +++ b/mlte/schema/artifact/validated/v0.0.1/schema.json @@ -231,13 +231,25 @@ } ], "title": "Info" + }, + "bool_exp_str": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Bool Exp Str" } }, "required": [ "bool_exp", "success", "failure", - "info" + "info", + "bool_exp_str" ], "title": "ValidatorModel", "type": "object" diff --git a/mlte/validation/model_condition.py b/mlte/validation/model_condition.py index 6506de8b..4efdbc8d 100644 --- a/mlte/validation/model_condition.py +++ b/mlte/validation/model_condition.py @@ -25,6 +25,9 @@ class ValidatorModel(BaseModel): info: Optional[str] """A string to be used when recording that the validation was not checked against a condition, just recorded information.""" + bool_exp_str: Optional[str] + """A string representation of the code for the bool expression to check for.""" + class ConditionModel(BaseModel): """A description of a condition for a property.""" diff --git a/mlte/validation/validator.py b/mlte/validation/validator.py index 4b8e3bea..5b4591c0 100644 --- a/mlte/validation/validator.py +++ b/mlte/validation/validator.py @@ -6,6 +6,7 @@ from __future__ import annotations +import inspect import typing from typing import Any, Callable, Optional @@ -48,6 +49,11 @@ def __init__( self.success = success self.failure = failure self.info = info + self.bool_exp_str = ( + inspect.getsource(bool_exp).strip() + if bool_exp is not None + else None + ) def validate(self, *args, **kwargs) -> Result: """ @@ -93,6 +99,7 @@ def to_model(self) -> ValidatorModel: success=self.success, failure=self.failure, info=self.info, + bool_exp_str=self.bool_exp_str, ) @classmethod diff --git a/test/spec/test_condition.py b/test/spec/test_condition.py index 886269d0..489b7208 100644 --- a/test/spec/test_condition.py +++ b/test/spec/test_condition.py @@ -144,6 +144,17 @@ def test_round_trip() -> None: assert condition == loaded +def test_bool_exp_str() -> None: + """Condition can be converted to model and back.""" + + condition = TestValue.in_between(1, 10) + + assert ( + condition.validator.bool_exp_str + == "bool_exp=lambda real: real.value > arg1 and real.value < arg2," + ) + + def test_non_serializable_argument(): condition = TestValue.in_between_complex(1.0, TestValue()) diff --git a/test/validation/test_validator.py b/test/validation/test_validator.py index ee979428..748e96d1 100644 --- a/test/validation/test_validator.py +++ b/test/validation/test_validator.py @@ -14,6 +14,7 @@ def get_sample_validator() -> Validator: success="Test was succesful!", failure="Test failed :(", info="Only data was attached", + bool_exp_str="test()", ) return validator @@ -26,6 +27,7 @@ def test_validator_model() -> None: success="Test was succesful!", failure="Test failed :(", info="Only data was attached", + bool_exp_str="test()", ), ]