def same_(source, kw): el = schema(source) sliced = el.slice(**kw) wanted = dict(keyslice_pairs(el.value.items(), **kw)) eq_(sliced, wanted) eq_(set(type(_) for _ in sliced.keys()), set(type(_) for _ in wanted.keys()))
def slice(self, include=None, omit=None, rename=None, key=None): """Return a ``dict`` containing a subset of the element's values.""" pairs = ((key, element.value) for key, element in sorted(iteritems(self))) sliced = keyslice_pairs(pairs, include=include, omit=omit, rename=rename, key=key) return dict(sliced)
def slice(self, include=None, omit=None, rename=None, key=None): """Return a ``dict`` containing a subset of the element's values.""" return dict( keyslice_pairs( ((key, element.value) for key, element in self.iteritems()), include=include, omit=omit, rename=rename, key=key, ) )
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)
def _keyslice_eq_(wanted, kw={}): got = list(util.keyslice_pairs(PAIRS, **kw)) eq_(wanted, got)
def test_keyslice_pairs(): assert list(util.keyslice_pairs(PAIRS)) == PAIRS assert list(util.keyslice_pairs(tuple(PAIRS))) == PAIRS assert list(util.keyslice_pairs(iter(PAIRS))) == PAIRS
def test_keyslice_conflict(): generator = util.keyslice_pairs((), include=[1], omit=[2]) assert_raises(TypeError, list, generator)
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)
def slice(self, include=None, omit=None, rename=None, key=None): """Return a ``dict`` containing a subset of the element's values.""" return dict( keyslice_pairs( ((key, element.value) for key, element in self.iteritems()), include=include, omit=omit, rename=rename, key=key))
def _keyslice_eq_(wanted, kw={}): got = list(util.keyslice_pairs(PAIRS, **kw)) assert wanted == got
def test_keyslice_conflict(): generator = util.keyslice_pairs((), include=[1], omit=[2]) with pytest.raises(TypeError): list(generator)