pyeve / cerberus

Lightweight, extensible data validation library for Python
http://python-cerberus.org
ISC License
3.17k stars 240 forks source link

Regex is ignored when using custom coercion #428

Closed elben10 closed 6 years ago

elben10 commented 6 years ago

Use-case abstract

It seems like that regexes is simply ignored, when using a coercing function. I would expect that if the input is a string the regex validation shouldn't be affected by the coercion function.


Bug report / Feature request

>>> # Import library
... 
>>> from cerberus import Validator
>>> 
>>> 
>>> # Define custom coerce function
... 
>>> def custom_coerce(x):
...         if x is True:
...                 return 'true'
...         else:
...                 return 'false'
... 
>>> 
>>> # Define schemas
... 
>>> schema1 = {
...     'test': {
...         'type': 'string',
...         'regex': '^true$',
...         'coerce': (bool, custom_coerce)
...     }
... }
>>> 
>>> schema2 = {
...     'test': {
...         'type': 'string',
...         'regex': '^true$',
...     }
... }
>>> 
>>> # Initiate validator
... 
>>> v = Validator()
>>> 
>>> v.validate({'test': 'ThisShouldConflictWithRegex'}, schema1) # Should return False
True
>>> v.validate({'test': 'ThisShouldConflictWithRegex'}, schema2)
False

But it seems like that the actual coercion works with the regex. If the coercion function is supplied then {'test': True} is validated to True if the coercion function is not supplied {'test': True} is validated to false. This behaviour is as expected.

>>> v.validate({'test': True}, schema1)
True
>>> v.validate({'test': False}, schema1)
False
>>> v.validate({'test': True}, schema2)
False
>>> v.validate({'test': False}, schema2)
False
funkyfuture commented 6 years ago

i made up this test case, and it works:


def test_issue_428():
    # https://github.com/pyeve/cerberus/issues/428

    def bool_as_string(x):
        return 'true' if x is True else 'false'

    schema = {'test': {
        'coerce': (bool, bool_as_string),
        'type': 'string',
        'regex': '^true$'
    }}
    assert_normalized({'test': 'x'}, {'test': 'true'}, schema)
    assert_success({'test': 'x'}, schema)

are you missing that bool_as_string(bool('ThisShouldActuallyNotConflictWithRegex')) == 'true'?

elben10 commented 6 years ago

Yes I guess I'm missing that link. I thought that given input was bool the coercion function would apply. But what you're saying is that the coercion will be used no matter what the input type is?

funkyfuture commented 6 years ago

But what you're saying is that the coercion will be used no matter what the input type is?

do you have other expectations? where do these stem from? does the documentation have a blind spot?

elben10 commented 6 years ago

I guess I missed the link to custom coercion methods in the docs. I don't think the docs have a blind spot, I should just have read the docs more carefully. Thanks for the help.