Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DelimitedDigitsPostalCode does not implement if_missing #129

Open
danclark5 opened this issue Jun 8, 2017 · 2 comments
Open

DelimitedDigitsPostalCode does not implement if_missing #129

danclark5 opened this issue Jun 8, 2017 · 2 comments

Comments

@danclark5
Copy link

For some reason DelimitedDigitsPostalCode doesn't implement if_missing. I am wondering if this was done on purpose.

A quick traversal through the classes

  • DelimitedDigitsPostalCode subclasses validators.Regex
  • Regex subclasses api.FancyValidator
  • FancyValidator subclasses api.Validator

FancyValidator sets if_missing to NoDefault, but Regex and DelimitedDigitPostalCode do not override it with anything.

A workaround is to just manually set postal_code_schema_validation_field.if_missing = None in the schema

Thanks to Vsevolod Kulaga for pointing all of this out in https://stackoverflow.com/questions/44387896/formencode-is-ignoring-if-missing/44397189#44397189

@precious
Copy link

precious commented Jun 8, 2017

I just have did double check and found that in formencode 1.3.1 validator DelimitedDigitsPostalCode handles if_missing correctly:

from formencode import national, Schema, validators

class TestValidator(Schema):
    allow_extra_fields = True
    filter_extra_fields = True
    postal_code_5_digits = national.DelimitedDigitsPostalCode(5, None, not_empty=False, if_missing='')

print(TestValidator.to_python({}))
# {'postal_code_5_digits': ''} is printed

But USPostalCode validator ignores if_missing though it's implemented as combination of two DelimitedDigitsPostalCode validators:

# from file formencode/national.py
def USPostalCode(*args, **kw):
    """
    US Postal codes (aka Zip Codes).

    ::

        >>> uspc = USPostalCode()
        >>> uspc.to_python('55555')
        '55555'
        >>> uspc.to_python('55555-5555')
        '55555-5555'
        >>> uspc.to_python('5555')
        Traceback (most recent call last):
            ...
        Invalid: Please enter a zip code (5 digits)
    """
    return Any(DelimitedDigitsPostalCode(5, None, *args, **kw),
               DelimitedDigitsPostalCode([5, 4], '-', *args, **kw))

So the root issue is in validator class Any that inherits class CompoundValidator (file formencode/compound.py). There are two validators in file formencode/compound.py that inherit CompoundValidator: Any and All. Validator class All implements its own property if_missing:

# from file formencode/compound.py
class All(CompoundValidator):

    # <...>

    @property
    def if_missing(self):
        for validator in self.validators:
            v = validator.if_missing
            if v is not NoDefault:
                return v
        return NoDefault

Meanwhile validator class Any does not have such property. That's why USPostalCode ignores if_missing -- it's just an instance of Any.


Looks like both compound validators -- All and Any should be reviewed, and all options -- if_missing, not_empty, if_empty, etc should be checked for them.

@danclark5
Copy link
Author

Thanks for pointing that out. I should have taken the time to research before opening the issue, my mistake.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants