murano/releasenotes/notes/new-contract-framework-1ded...

39 lines
2.3 KiB
YAML

---
features:
- Implemented a new framework for MuranoPL contracts. Now, instead of several
independent implementations of the same yaql methods (string(), class()
etc.) all implementations of the same method are combined into single
class. Therefore, we now have a class per contract method. This also simplifies
development of new contracts. Each such class can provide methods for
data transformation (default contract usage), validation that is used
to decide if the method can be considered an extension method for the
value, and json schema generation method that was moved from the schema
generator script.
- Previously, when a class overrode a property from its parent
class the value was stored separately for both of them, transformed
by each of the contracts. Thus each class saw the value of its contract.
In absolute majority of the cases, the observed value was the same. However,
if the contracts were compatible on the provided value (say int() and
string() contracts on the value "123") they were different. This is
considered to be a bad pattern.
Now, the value is stored only once per object and transformed by the
contract defined in the actual object type. All base contracts are used
to validate the transformed object thus this pattern will not work
anymore.
- The value that is stored in the object's properties is obtained by
executing special "finalize" contract implementation which by default
returns the input value unmodified. Because validation happens on
the transformed value before it gets finalized it is possible for
transformation to return a value that will pass the validation though
the final value won't. This is used to relax the template() contract
limitation that prevented child class from excluding additional properties
from the template.
- The ``string()`` contract no longer converts everything to string values.
Now it only converts scalar values to strings.
Previous behavior allowed ``string()`` property to
accept lists and convert them to their Python string representation which
is clearly not what developers expected.
- Due to refactoring, contracts work a little bit faster because there is
no more need to generate yaql function definition for each contract method
on each call.