Cerberus 2: Proposal to change the default_setter behaviour
as #427 shows, the default_setter rule should be usable in a way that allows the used handler(s) to determine whether a field should be added to the document at all. therefore the proposed change is to delegate the responsibility of (not) adding a field to the document to the handler(s). currently it must return a value that is then set as the field's content in any case - though that can be prevented by raising an exception. #279 must be resolved as a requirement for this change.
cc @andreymal, @dkellner
related to #515 I mentioned that the functionally discussed in this issue would be very helpful. In my sub-classed validator I solved it by introducing a special NotProvided type. It looks roughly like this:
class MyValidator(Validator):
_NotProvided = type("_NotProvided", (), {})()
def _normalize_default_setter(self, mapping, schema, field):
""" {'oneof': [
{'type': 'Callable'},
{'type': 'string'}
]} """
if 'default_setter' in schema[field]:
setter = schema[field]['default_setter']
if isinstance(setter, str):
setter = self.__get_rule_handler('normalize_default_setter', setter)
tmp = setter(mapping)
if tmp != self._NotProvided:
mapping[field] = tmp
#the last three lines replace `mapping[field] = setter(mapping)` in the original code
my_custom_default_setter(mapping):
...
if # I want to set a default:
return MY_RETURN_VALUE
else:
retrun MyValidator._NotProvided
instead of always setting mapping[field] = setter(mapping) at the end of _normalize_default_setter I check for for _NotProvided first. Like this None is also a value that can be set by the provided setter.
In case this approach is considered for cerberus I suggest however to have an equivalent of _NotProvided on the module level instead of inside the validator.
closing this issue as there are currently no intentions to continue a next major release.