Problem
Field currently validates assigned values before and after conversion. This is the behavior documented by the current "Converting values" README section, but it is not the behavior we want long-term.
The desired pipeline is:
type check -> conversion -> type check converted value -> validation -> conflicts -> action -> store
In other words, user-defined validation should validate the final converted value only. It should not have to accept both raw input and converted values.
Current behavior
Minimal example:
from skelet import Field, Storage
class Config(Storage):
value: int = Field(
1,
conversion=abs,
validation=lambda value: value >= 0,
)
config = Config()
config.value = -5
Today this raises before conversion=abs can fix the value:
ValueError: The value -5 (int) of the "value" field does not match the validation.
That happens because the current pipeline is:
type check raw value -> validation raw value -> conversion -> type check converted value -> validation converted value
So -5 is rejected by validation before abs(-5) can produce 5.
Expected future behavior
The same example should pass:
config.value = -5
assert config.value == 5
Validation should see only the converted value 5.
Notes
This is a breaking semantic change. Existing tests currently lock in the old behavior for assignments, init kwargs, literal defaults, default factories, and sources. Secret fields use the same prepare_value() pipeline, so this change should be made consistently for both regular and secret fields unless we explicitly decide to split their semantics.
Problem
Fieldcurrently validates assigned values before and after conversion. This is the behavior documented by the current "Converting values" README section, but it is not the behavior we want long-term.The desired pipeline is:
In other words, user-defined validation should validate the final converted value only. It should not have to accept both raw input and converted values.
Current behavior
Minimal example:
Today this raises before
conversion=abscan fix the value:That happens because the current pipeline is:
So
-5is rejected by validation beforeabs(-5)can produce5.Expected future behavior
The same example should pass:
Validation should see only the converted value
5.Notes
This is a breaking semantic change. Existing tests currently lock in the old behavior for assignments, init kwargs, literal defaults, default factories, and sources. Secret fields use the same
prepare_value()pipeline, so this change should be made consistently for both regular and secret fields unless we explicitly decide to split their semantics.