Ejemplo n.º 1
0
    def validate(self, element, state):
        if (element.raw is Unset or element.raw is None or  # perverse case
                hasattr(element.raw, 'next')):
            return True

        try:
            set_with = list(to_pairs(element.raw))
        except TypeError:
            # wasn't iterable
            return True

        missing, unexpected = _evaluate_dict_strict_policy(element, set_with)
        if not missing and not unexpected:
            return True
        elif missing and unexpected:
            message = 'both'
        elif missing:
            message = 'missing'
        else:
            message = 'unexpected'

        n_miss, miss = len(missing), u', '.join(sorted(missing))
        n_unex, unex = len(unexpected), u', '.join(sorted(unexpected))

        return self.note_error(element,
                               state,
                               message,
                               n_missing=n_miss,
                               missing=miss,
                               n_unexpected=n_unex,
                               unexpected=unex)
Ejemplo n.º 2
0
    def set(self, value, policy=None):
        """TODO: doc set()"""
        self.raw = value
        pairs = to_pairs(value)
        self._reset()

        if policy is not None:
            assert policy in ("strict", "subset", "duck")
        else:
            policy = self.policy

        fields = self.field_schema_mapping
        seen = set()
        converted = True
        for key, value in pairs:
            if key not in fields:
                if policy != "duck":
                    raise KeyError("Dict %r schema does not allow key %r" % (self.name, key))
                continue
            if dict.__contains__(self, key):
                converted &= self[key].set(value)
            else:
                self[key] = el = fields[key]()
                converted &= el.set(value)
            seen.add(key)

        if policy == "strict":
            required = set(fields.iterkeys())
            if seen != required:
                missing = required - seen
                raise TypeError(
                    "strict-mode Dict requires all keys for "
                    "a set() operation, missing %s." % (",".join(repr(key) for key in missing))
                )
        return converted
Ejemplo n.º 3
0
    def validate(self, element, state):
        if (element.raw is Unset or
            element.raw is None or  # perverse case
            hasattr(element.raw, 'next')):
            return True

        try:
            set_with = list(to_pairs(element.raw))
        except TypeError:
            # wasn't iterable
            return True

        missing, unexpected = _evaluate_dict_strict_policy(element, set_with)
        if not missing and not unexpected:
            return True
        elif missing and unexpected:
            message = 'both'
        elif missing:
            message = 'missing'
        else:
            message = 'unexpected'

        n_miss, miss = len(missing), u', '.join(sorted(missing))
        n_unex, unex = len(unexpected), u', '.join(sorted(unexpected))

        return self.note_error(element, state, message,
                               n_missing=n_miss,
                               missing=miss,
                               n_unexpected=n_unex,
                               unexpected=unex)
Ejemplo n.º 4
0
 def update(self, *dictish, **kwargs):
     """Update with keys from dict-like *\*dictish* and *\*\*kwargs*"""
     if len(dictish) > 1:
         raise TypeError("update expected at most 1 arguments, got %s" % len(dictish))
     elif dictish:
         for key, value in to_pairs(dictish[0]):
             self[key] = value
     for key, value in kwargs.iteritems():
         self[key] = value
Ejemplo n.º 5
0
 def update(self, *dictish, **kwargs):
     """Update with keys from dict-like *\*dictish* and *\*\*kwargs*"""
     if len(dictish) > 1:
         raise TypeError("update expected at most 1 arguments, got %s" %
                         len(dictish))
     elif dictish:
         for key, value in to_pairs(dictish[0]):
             self[key] = value
     for key, value in iteritems(kwargs):
         self[key] = value
Ejemplo n.º 6
0
 def update(self, *iterable, **kwargs):
     if len(iterable):
         if len(iterable) > 1:
             raise TypeError("update expected at most 1 arguments, got %s" %
                             (len(iterable)))
         source = to_pairs(iterable[0])
         for key, value in source:
             self[key] = value
     for key, value in kwargs.iteritems():
         self[key.decode('ascii')] = value
Ejemplo n.º 7
0
 def update(self, *iterable, **kwargs):
     if len(iterable):
         if len(iterable) > 1:
             raise TypeError(
                 "update expected at most 1 arguments, got %s" % (
                 len(iterable)))
         source = to_pairs(iterable[0])
         for key, value in source:
             self[key] = value
     for key, value in six.iteritems(kwargs):
         self[key] = value
Ejemplo n.º 8
0
    def set(self, value, policy=None):
        self.raw = value
        pairs = list(to_pairs(value))
        self._reset()

        if policy is None:
            policy = self.policy
        if policy not in ('strict', 'subset', 'duck', None):
            raise RuntimeError("Unknown %s policy %r" % (
                self.__class__.__name__, policy))

        if policy == 'strict':
            missing, extra = _evaluate_dict_strict_policy(self, pairs)
            if missing and extra:
                raise KeyError(
                    'Strict %s %r schema does not allow keys %r and '
                    'requires keys %r' % (
                        self.__class__.__name__, self.name,
                        list(extra), list(missing)))
            elif missing:
                # match previous logic's exception type here
                raise TypeError(
                    'Strict %s %r schema requires keys %r' % (
                        self.__class__.__name__, self.name,
                        list(missing)))
            elif extra:
                raise KeyError(
                    'Strict %s %r schema does not allow keys %r' % (
                        self.__class__.__name__, self.name,
                        list(extra)))
        elif policy == 'subset':
            mismatch = _evaluate_dict_subset_policy(self, pairs)
            if mismatch:
                raise KeyError(
                    'Subset %s %r schema does not allow keys %r' % (
                        self.__class__.__name__, self.name,
                        list(mismatch)))

        fields = self.field_schema_mapping
        converted = True
        for key, value in pairs:
            if PY2 and isinstance(key, bytestring_type):
                key = key.decode('ascii', 'replace')
            if key not in fields:
                continue
            if dict.__contains__(self, key):
                converted &= self[key].set(value)
            else:
                self[key] = el = fields[key]()
                converted &= el.set(value)
        element_set.send(self, adapted=converted)
        return converted
Ejemplo n.º 9
0
    def set(self, value, policy=None):
        self.raw = value
        pairs = list(to_pairs(value))
        self._reset()

        if policy is None:
            policy = self.policy
        if policy not in ('strict', 'subset', 'duck', None):
            raise RuntimeError("Unknown %s policy %r" %
                               (self.__class__.__name__, policy))

        if policy == 'strict':
            missing, extra = _evaluate_dict_strict_policy(self, pairs)
            if missing and extra:
                raise KeyError(
                    'Strict %s %r schema does not allow keys %r and '
                    'requires keys %r' % (self.__class__.__name__, self.name,
                                          list(extra), list(missing)))
            elif missing:
                # match previous logic's exception type here
                raise TypeError(
                    'Strict %s %r schema requires keys %r' %
                    (self.__class__.__name__, self.name, list(missing)))
            elif extra:
                raise KeyError(
                    'Strict %s %r schema does not allow keys %r' %
                    (self.__class__.__name__, self.name, list(extra)))
        elif policy == 'subset':
            mismatch = _evaluate_dict_subset_policy(self, pairs)
            if mismatch:
                raise KeyError(
                    'Subset %s %r schema does not allow keys %r' %
                    (self.__class__.__name__, self.name, list(mismatch)))

        fields = self.field_schema_mapping
        converted = True
        for key, value in pairs:
            if PY2 and isinstance(key, bytestring_type):
                key = key.decode('ascii', 'replace')
            if key not in fields:
                continue
            if dict.__contains__(self, key):
                converted &= self[key].set(value)
            else:
                self[key] = el = fields[key]()
                converted &= el.set(value)
        element_set.send(self, adapted=converted)
        return converted
Ejemplo n.º 10
0
    def validate(self, element, state):
        if (element.raw is Unset or
            element.raw is None or  # perverse case
            hasattr(element.raw, 'next')):
            return True

        try:
            set_with = list(to_pairs(element.raw))
        except TypeError:
            # wasn't iterable
            return True

        unexpected = _evaluate_dict_subset_policy(element, set_with)
        if not unexpected:
            return True
        n_unex, unex = len(unexpected), u', '.join(sorted(unexpected))
        return self.note_error(element, state, 'unexpected',
                               unexpected=unex,
                               n_unexpected=n_unex)
Ejemplo n.º 11
0
    def validate(self, element, state):
        if (element.raw is Unset or element.raw is None or  # perverse case
                hasattr(element.raw, 'next')):
            return True

        try:
            set_with = list(to_pairs(element.raw))
        except TypeError:
            # wasn't iterable
            return True

        unexpected = _evaluate_dict_subset_policy(element, set_with)
        if not unexpected:
            return True
        n_unex, unex = len(unexpected), u', '.join(sorted(unexpected))
        return self.note_error(element,
                               state,
                               'unexpected',
                               unexpected=unex,
                               n_unexpected=n_unex)
Ejemplo n.º 12
0
    def set(self, value):
        """TODO: doc set()"""
        self.raw = value
        pairs = to_pairs(value)
        self._reset()

        seen = set()
        converted = True
        for key, value in pairs:
            if not self.may_contain(key):
                raise KeyError("%s %r schema does not allow key %r" % (type(self).__name__, self.name, key))
            converted &= self[key].set(value)
            seen.add(key)
        required = set(self.iterkeys())
        if seen != required:
            missing = required - seen
            raise TypeError(
                "all keys required for a set() operation, missing %s." % (",".join(repr(key) for key in missing))
            )
        return converted
Ejemplo n.º 13
0
    def set(self, value):
        """TODO: doc set()"""
        pairs = to_pairs(value)
        self._reset()

        seen = set()
        converted = True
        for key, value in pairs:
            if not self.may_contain(key):
                raise KeyError(
                    '%s %r schema does not allow key %r' % (
                        type(self).__name__, self.name, key))
            converted &= self[key].set(value)
            seen.add(key)
        required = set(self.iterkeys())
        if seen != required:
            missing = required - seen
            raise TypeError(
                'all keys required for a set() operation, missing %s.' % (
                    ','.join(repr(key) for key in missing)))
        return converted
Ejemplo n.º 14
0
    def set(self, value):
        """.. TODO:: doc set()"""
        self.raw = value
        pairs = to_pairs(value)
        self._reset()

        seen = set()
        converted = True
        for key, value in pairs:
            if not self.may_contain(key):
                raise KeyError(
                    '%s %r schema does not allow key %r' % (
                        type(self).__name__, self.name, key))
            converted &= self[key].set(value)
            seen.add(key)
        required = set(iterkeys(self))
        if seen != required:
            missing = required - seen
            raise TypeError(
                'all keys required for a set() operation, missing %s.' % (
                    ','.join(repr(key) for key in missing)))
        element_set.send(self, adapted=converted)
        return converted
Ejemplo n.º 15
0
    def set(self, value, policy=None):
        """TODO: doc set()"""
        pairs = to_pairs(value)
        self._reset()

        if policy is not None:
            assert policy in ('strict', 'subset', 'duck')
        else:
            policy = self.policy

        fields = self.field_schema_mapping
        seen = set()
        converted = True
        for key, value in pairs:
            if key not in fields:
                if policy != 'duck':
                    raise KeyError(
                        'Dict %r schema does not allow key %r' % (
                            self.name, key))
                continue
            if dict.__contains__(self, key):
                converted &= self[key].set(value)
            else:
                self[key] = el = fields[key]()
                converted &= el.set(value)
            seen.add(key)

        if policy == 'strict':
            required = set(fields.iterkeys())
            if seen != required:
                missing = required - seen
                raise TypeError(
                    'strict-mode Dict requires all keys for '
                    'a set() operation, missing %s.' % (
                        ','.join(repr(key) for key in missing)))
        return converted
Ejemplo n.º 16
0
    def set_by_object(self, obj, include=None, omit=None, rename=None):
        """Set fields with an object's attributes.

        :param obj: any object
        :param include: optional, an iterable of attribute names to pull from
            *obj*, if present on the object.  Only these attributes will be
            included.
        :param omit: optional, an iterable of attribute names to ignore on
            **obj**.  All other attributes matching a named field on the Form
            will be included.
        :param rename: optional, a mapping of attribute-to-field name
            transformations.  Attributes specified in the mapping will be
            included regardless of *include* or *omit*.

        *include* and *omit* are mutually exclusive.

        Sets fields on *self*, using as many attributes as possible from
        *obj*.  Object attributes that do not correspond to field names are
        ignored.

        Mapping instances have two corresponding methods useful for
        round-tripping values in and out of your domain objects.

        .. testsetup::

          # FIXME
          from flatland import Form, String
          class UserForm(Form):
              login = String
              password = String
              verify_password = String

          class User(object):
              def __init__(self, login=None, password=None):
                  self.login = login
                  self.password = password

        :meth:`update_object` performs the inverse of :meth:`set_object`, and
        :meth:`slice` is useful for constructing new objects.

        .. doctest::

          >>> user = User('biff', 'secret')
          >>> form = UserForm()
          >>> form.set_by_object(user)
          >>> form['login'].value
          u'biff'
          >>> form['password'] = u'new-password'
          >>> form.update_object(user, omit=['verify_password'])
          >>> user.password
          u'new-password'
          >>> user_keywords = form.slice(omit=['verify_password'], key=str)
          >>> sorted(user_keywords.keys())
          ['login', 'password']
          >>> new_user = User(**user_keywords)

        """
        fields = set(self.iterkeys())
        attributes = fields.copy()
        if rename:
            rename = list(to_pairs(rename))
            attributes.update(key for key, value in rename if value in attributes)
        if omit:
            omit = list(omit)
            attributes.difference_update(omit)

        possible = ((attr, getattr(obj, attr)) for attr in attributes if hasattr(obj, attr))

        sliced = keyslice_pairs(possible, include=include, omit=omit, rename=rename)
        final = dict((key, value) for key, value in sliced if key in fields)
        self.set(final)
Ejemplo n.º 17
0
    def set_by_object(self, obj, include=None, omit=None, rename=None):
        """Set fields with an object's attributes.

        :param obj: any object
        :param include: optional, an iterable of attribute names to pull from
            *obj*, if present on the object.  Only these attributes will be
            included.
        :param omit: optional, an iterable of attribute names to ignore on
            **obj**.  All other attributes matching a named field on the
            mapping will be included.
        :param rename: optional, a mapping of attribute-to-field name
            transformations.  Attributes specified in the mapping will be
            included regardless of *include* or *omit*.

        *include* and *omit* are mutually exclusive.

        Sets fields on *self*, using as many attributes as possible from
        *obj*.  Object attributes that do not correspond to field names are
        ignored.

        Mapping instances have two corresponding methods useful for
        round-tripping values in and out of your domain objects.

        .. testsetup::

          # FIXME
          from flatland import Schema, String
          class UserForm(Schema):
              login = String
              password = String
              verify_password = String

          class User(object):
              def __init__(self, login=None, password=None):
                  self.login = login
                  self.password = password

        :meth:`update_object` performs the inverse of :meth:`set_object`, and
        :meth:`slice` is useful for constructing new objects.

        .. doctest::

          >>> user = User('biff', 'secret')
          >>> form = UserForm()
          >>> form.set_by_object(user)
          >>> form['login'].value
          u'biff'
          >>> form['password'] = u'new-password'
          >>> form.update_object(user, omit=['verify_password'])
          >>> user.password
          u'new-password'
          >>> user_keywords = form.slice(omit=['verify_password'], key=str)
          >>> sorted(user_keywords.keys())
          ['login', 'password']
          >>> new_user = User(**user_keywords)

        """
        fields = set(iterkeys(self))
        attributes = fields.copy()
        if rename:
            rename = list(to_pairs(rename))
            attributes.update(key for key, value in rename
                              if value in attributes)
        if omit:
            omit = list(omit)
            attributes.difference_update(omit)

        possible = ((attr, getattr(obj, attr)) for attr in sorted(attributes)
                    if hasattr(obj, attr))

        sliced = keyslice_pairs(possible,
                                include=include,
                                omit=omit,
                                rename=rename)
        final = dict((key, value) for key, value in sliced if key in fields)
        self.set(final)