def _finds(el, path, expected): finder = pathexpr(path) elements = finder(el) found = [e.value for e in elements] if isinstance(expected, set): found = set(found) assert found == expected
def find(self, path, single=False, strict=True): """Find child elements by string path. :param path: a /-separated string specifying elements to select, such as 'child/grandchild/great grandchild'. Relative & absolute paths are supported, as well as container expansion. See :ref:`path_lookups`. :param single: if true, return a scalar result rather than a list of elements. If no elements match *path*, ``None`` is returned. If multiple elements match, a :exc:`LookupError` is raised. If multiple elements are found and *strict* is false, an unspecified element from the result set is returned. :param strict: defaults to True. If *path* specifies children or sequence indexes that do not exist, a :exc:`LookupError` is raised. :returns: a list of :class:`Element` instances, an :class:`Element` if *single* is true, or raises :exc:`LookupError`. .. testsetup:: find from flatland import Schema, Dict, List, String class Profile(Schema): contact = Dict.of(String.named('name'), List.named('addresses'). of(Dict.of(String.named('street1'), String.named('city'))). using(default=1)) form = Profile( {'contact': {'name': 'Obed Marsh', 'addresses': [{'street1': 'Main', 'city': 'Kingsport'}, {'street1': 'Broadway', 'city': 'Dunwich'}]}}) .. doctest:: find >>> cities = form.find('/contact/addresses[:]/city') >>> [el.value for el in cities] [u'Kingsport', u'Dunwich'] >>> form.find('/contact/name', single=True) <String u'name'; value=u'Obed Marsh'> """ expr = pathexpr(path) results = expr(self, strict) if not single: return results elif not results: return None elif len(results) > 1 and strict: display_path = repr(path).lstrip('u') raise LookupError("Path %s matched multiple elements; single " "result expected." % display_path) else: return results[0]
def to(cls, path): # ensure *path* parses pathexpr(path) cls.target_path = path return cls
def test_pathexpr(): xy = pathexpr(u'x/y') assert xy is pathexpr(xy) assert xy == pathexpr([u'x', u'y'])