Closed funkyfuture closed 8 years ago
Design/usage example? Thanks!
class MyValidator(Validator):
def _corce_none_to_string(self, field, value):
if value is None:
self.document[field] = "N/A"
def _coerce_expand_avatar_path(self, field, value):
self.document[field] = os.path.join(self.avatar_dir, value)
schema = {'avatar': {'coerce': 'expand_avatar_path', 'type': 'accessible_image_file'},
'phone': {'coerce': 'none_to_string'}}
:+1:
Type coercion allows this already, as you can pass any callable to the coerce
method. You can also confine coercion within a custom validator:
class MyValidator(Validator):
def __init__(self, *args, **kwargs):
super(MyValidator, self).__init__(*args, **kwargs)
self.avatar_dir = '~/avatars'
def _validate_expand_avatar(self, expand_avatar, field, value):
self.document[field] = os.path.join(self.avatar_dir, value)
s = {'a': {'type': 'string', 'expand_avatar': True}
Alternatively you could create a new avatar
type:
class MyValidator(Validator):
def __init__(self, *args, **kwargs):
super(MyValidator, self).__init__(*args, **kwargs)
self.avatar_dir = '~/avatars'
def _validate_type_avatar(self, field, value):
self.document[field] = os.path.join(self.avatar_dir, value)
s = {'a': {'type': 'avatar'}}
Do we really need to add yet another way to achieve this?
imo yes, as i think that normalization and validation should be clearer segregated in the code. you're proposal is more a workaround where normalization is applied while validation, right?
Yes, I think you are right.
:+1:
One example would be for those fields in which you want a default value.
Since there is no default
keyword this could be easily implemented with coerce.
Also, i agree that makes sense the separation of validation (no data changes) versus coerce (data is modified).
i wouldn't see why a default
-normalization-rule shouldn't be contributed with the vanilla Validator.
it could, but it is more aligned with coerce
in which it would silently alter the original data.
i don't understand. i thought you mean:
>>> schema = {'amount': {'default': 1}}
>>> document = {'amount': None}
>>> v.validated(document, schema)
{'amount': 1}
>>> document = {'model': 'The Robots'}
>>> v.normalized(document, schema)
{'model': 'The Robots', 'amount': 1}
yes, it alters values like coerce
, but in a different way.
yeah that's what i meant. I guess both coerce
and default
are same level citizens.
I'd take advantage of this: I'm loading the schema from an external file (actually, from a schema
in a RAML
document), and there's no easy way to express a callable (although I could use a YAML
tag like {a: !!python/name:__builtin__.int}
, that's quite ugly, difficult to understand to non-Python-introduced people who read the schema, and most Python RAML loaders use yaml.SafeLoader
so that's not a generic option even).
Ideally I'd like to have a way to inject custom coercer functions on Validator
, that _coerce_values()
could lookup by name.
closing this in favor of #188 where i argue that this is a 1.0-must-have.
i think it's better to include this feature before 0.9 is released. and as there is a reliable pattern for types, it wouldn't be much effort i guess.
one could also add an example to the docs and tests that illustrates a subclassed Validator that makes use of coercing in conjunction with contextual instance-properties.