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

Passing args of failed validator as attributes on Errors #301

Open
ek5000 opened this issue Aug 15, 2017 · 0 comments
Open

Passing args of failed validator as attributes on Errors #301

ek5000 opened this issue Aug 15, 2017 · 0 comments

Comments

@ek5000
Copy link

ek5000 commented Aug 15, 2017

This is actually pretty closely related to #53, and may even be a duplicate of
that issue. When using a core validator, there is no way to get back to the
original attributes. For our use case, we actually want the metadata, rather
than an actual message. There are a couple of workarounds, such as the
following

from voluptuous import Invalid, Range, Schema

s = Schema(Range(0, 10, msg={'min': 0, 'max': 10}))
try:
  s(42)
except Invalid as e:
  print(e.msg['min'], e.msg['max']) # 0 10

However, this feels like it should be more core than that. I could submit a PR,
that updates most of the validator/invalid pairs to be like the following.

from voluptuous import Invalid, MultipleInvalid, Schema

class RangeInvalid(Invalid):
    """The value is not in given range."""
    def __init__(self, message, min=None, max=None, min_included=None, max_included=None, *args, **kwargs):
        super(RangeInvalid, self).__init__(message, *args, **kwargs)
        self.min = min
        self.max = max
        self.min_included = min_included
        self.max_included = max_included

class Range(object):
    def __init__(self, min=None, max=None, min_included=True, max_included=True, msg=None):
        self.min = min
        self.max = max
        self.min_included = min_included
        self.max_included = max_included
        self.msg = msg

    def __call__(self, v):
        if self.min_included:
            if self.min is not None and not v >= self.min:
                raise RangeInvalid(
                    self.msg or 'value must be at least %s' % self.min,
                    min=self.min,
                    max=self.max,
                    min_included=self.min_included,
                    max_included=self.max_included)
        else:
            if self.min is not None and not v > self.min:
                raise RangeInvalid(
                    self.msg or 'value must be higher than %s' % self.min,
                    min=self.min,
                    max=self.max,
                    min_included=self.min_included,
                    max_included=self.max_included)
        if self.max_included:
            if self.max is not None and not v <= self.max:
                raise RangeInvalid(
                    self.msg or 'value must be at most %s' % self.max,
                    min=self.min,
                    max=self.max,
                    min_included=self.min_included,
                    max_included=self.max_included)
        else:
            if self.max is not None and not v < self.max:
                raise RangeInvalid(
                    self.msg or 'value must be lower than %s' % self.max,
                    min=self.min,
                    max=self.max,
                    min_included=self.min_included,
                    max_included=self.max_included)
        return v

s = Schema(Range(0, 10))
try:
    s(42)
except MultipleInvalid as errors:
    e = errors.errors[0]
    print(e.min, e.max) # 0 10
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

1 participant