Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions src/rune/runtime/base_data_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ def rune_serialize(
self,
*,
validate_model: bool = True,
check_rune_constraints: bool = True,
strict: bool = True,
raise_validation_errors: bool = True,
indent: int | None = None,
Expand All @@ -92,6 +93,10 @@ def rune_serialize(
serialization. It checks also all Rune type constraints.
Defaults to True.

`check_rune_constraints (bool, optional):` If `validate_model` is
set to `True`, executes all model defined Rune constraints after
deserialization. Defaults to True.

`strict (bool, optional):` Perform strict attribute validation.
Defaults to True.

Expand Down Expand Up @@ -134,8 +139,10 @@ def rune_serialize(
'''
try:
if validate_model:
self.validate_model(strict=strict,
raise_exc=raise_validation_errors)
self.validate_model(
check_rune_constraints=check_rune_constraints,
strict=strict,
raise_exc=raise_validation_errors)

root_meta = self.__dict__.setdefault(ROOT_CONTAINER, {})
root_meta['@type'] = self._FQRTN
Expand All @@ -159,6 +166,7 @@ def rune_serialize(
def rune_deserialize(cls,
rune_json: str,
validate_model: bool = True,
check_rune_constraints: bool = True,
strict: bool = True,
raise_validation_errors: bool = True) -> BaseModel:
# pylint: disable=line-too-long
Expand All @@ -171,6 +179,10 @@ def rune_deserialize(cls,
deserialization. It checks also all Rune type constraints. Defaults
to True.

`check_rune_constraints (bool, optional):` If `validate_model` is
set to `True`, executes all model defined Rune constraints after
deserialization. Defaults to True.

`strict (bool, optional):` Perform strict attribute validation.
Defaults to True.

Expand All @@ -186,7 +198,8 @@ def rune_deserialize(cls,
rune_cls = cls._type_to_cls(rune_dict)
model = rune_cls.model_validate(rune_dict, strict=strict)
if validate_model:
model.validate_model(strict=strict,
model.validate_model(check_rune_constraints=check_rune_constraints,
strict=strict,
raise_exc=raise_validation_errors)
return model

Expand All @@ -212,6 +225,7 @@ def resolve_references(self):
self.bind_property_to(prop_nm, ref)

def validate_model(self,
check_rune_constraints=True,
recursively: bool = True,
raise_exc: bool = True,
strict: bool = True) -> list:
Expand All @@ -226,8 +240,10 @@ def validate_model(self,
self.disable_meta_checks()
att_errors = self.validate_attribs(raise_exc=raise_exc,
strict=strict)
return att_errors + self.validate_conditions(
recursively=recursively, raise_exc=raise_exc)
if check_rune_constraints:
att_errors.extend(self.validate_conditions(
recursively=recursively, raise_exc=raise_exc))
return att_errors
finally:
self.enable_meta_checks()

Expand Down
2 changes: 1 addition & 1 deletion src/rune/runtime/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
# return eval(expr, globals(), {'self': obj}) # pylint: disable=eval-used


def if_cond_fn(ifexpr, thenexpr: Callable, elseexpr: Callable) -> Any:
def if_cond_fn(ifexpr: bool, thenexpr: Callable, elseexpr: Callable) -> Any:
''' A helper to return the value of the ternary operator
(functional version).
'''
Expand Down
58 changes: 58 additions & 0 deletions test/cdm/test_trade_creation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
'''test the if condition runtime functionality'''
# pylint: disable=invalid-name
from datetime import date
import pytest
try:
# pylint: disable=unused-import
# type: ignore
from cdm.event.common.Trade import Trade
from cdm.event.common.TradeIdentifier import TradeIdentifier
from cdm.product.template.TradableProduct import TradableProduct
from cdm.product.template.Product import Product
from cdm.product.template.TradeLot import TradeLot
from cdm.product.common.settlement.PriceQuantity import PriceQuantity
from cdm.base.staticdata.party.Party import Party
from cdm.base.staticdata.party.PartyIdentifier import PartyIdentifier
from cdm.base.staticdata.party.Counterparty import Counterparty
from cdm.base.staticdata.party.CounterpartyRoleEnum import CounterpartyRoleEnum
from cdm.base.staticdata.asset.common.Index import Index
from cdm.base.staticdata.identifier.AssignedIdentifier import AssignedIdentifier
NO_SER_TEST_MOD = False
except ImportError:
NO_SER_TEST_MOD = True


@pytest.mark.skipif(NO_SER_TEST_MOD, reason='CDM package not found')
def test_simple_trade():
'''Constructs a simple Trade in memory and validates the model.'''
price_quantity = PriceQuantity()
trade_lot = TradeLot(priceQuantity=[price_quantity])
product = Product(index=Index())
counterparty = [
Counterparty(role=CounterpartyRoleEnum.PARTY_1,
partyReference=Party(
partyId=[PartyIdentifier(identifier='Acme Corp')])),
Counterparty(
role=CounterpartyRoleEnum.PARTY_2,
partyReference=Party(
partyId=[PartyIdentifier(identifier='Wile E. Coyote')]))
]
tradable_product = TradableProduct(product=product,
tradeLot=[trade_lot],
counterparty=counterparty)
assigned_identifier = AssignedIdentifier(identifier='BIG DEAL!')
trade_identifier = [
TradeIdentifier(issuer='Acme Corp',
assignedIdentifier=[assigned_identifier])
]

# t = Trade(tradeDate=DateWithMeta(str(date(2023, 1, 1))),
t = Trade(tradeDate=date(2023, 1, 1),
tradableProduct=tradable_product,
tradeIdentifier=trade_identifier)
with pytest.raises(NameError):
exceptions = t.validate_model(raise_exc=False)
exceptions = t.validate_model(raise_exc=False, check_rune_constraints=False)
assert not exceptions

# EOF