Ejemplo n.º 1
0
def test_validators():
    # Validators may be inherited or supplied at construction.
    el = Element()
    assert not el.validators

    # argument is transformed into a list copy
    el = Element(validators=(123, 456))
    eq_(el.validators, [123, 456])

    el = Element(validators=xrange(3))
    eq_(el.validators, list(xrange(3)))

    schema = Element.using(validators=xrange(3))
    eq_(schema.validators, list(xrange(3)))
Ejemplo n.º 2
0
    def set_default(self):
        """set() the element to the schema default.

        List's set_default supports two modes for
        :attr:`~flatland.schema.base.Element.default` values:

        - If default is an integer, the List will be filled with that many
          elements.  Each element will then have
          :meth:`~flatland.schema.base.Element.set_default` called on it.

        - Otherwise if default has a value, the list will be :meth:`set` with
          it.

        """
        default = self.default_value
        if default is None or default is Unspecified:
            return

        del self[:]
        if isinstance(default, int):
            for _ in xrange(0, default):
                slot = self._new_slot()
                list.append(self, slot)
                slot.element.set_default()
        else:
            self.set(default)
Ejemplo n.º 3
0
def test_set():
    schema = List.of(Integer)

    el = schema()
    assert list(el) == []

    el = schema()
    assert not el.set(1)
    assert el.value == []

    el = schema()
    assert not el.set(None)
    assert el.value == []

    el = schema()
    assert el.set(range(3))
    assert el.value == [0, 1, 2]

    el = schema()
    assert el.set(xrange(3))
    assert el.value == [0, 1, 2]

    el = schema([0, 1, 2])
    assert el.value == [0, 1, 2]

    el = schema()
    el.extend([1, 2, 3])
    assert el.value == [1, 2, 3]
    el.set([4, 5, 6])
    assert el.value == [4, 5, 6]
    assert el.set([])
    assert el.value == []
Ejemplo n.º 4
0
    def set_default(self):
        """set() the element to the schema default.

        List's set_default supports two modes for
        :attr:`~flatland.schema.base.Element.default` values:

        - If default is an integer, the List will be filled with that many
          elements.  Each element will then have
          :meth:`~flatland.schema.base.Element.set_default` called on it.

        - Otherwise if default has a value, the list will be :meth:`set` with
          it.

        """
        default = self.default_value
        if default is None or default is Unspecified:
            return

        del self[:]
        if isinstance(default, int):
            for _ in xrange(0, default):
                slot = self._new_slot()
                list.append(self, slot)
                slot.element.set_default()
        else:
            self.set(default)
Ejemplo n.º 5
0
    def _set_flat(self, pairs, sep):
        del self[:]

        if not pairs:
            return

        if self.name:
            regex = re.compile(
                u'^%s(\\d+)(?:%s|$)' %
                (re_uescape(self.name + sep), re_uescape(sep)), re.UNICODE)
        else:
            regex = re.compile(u'^(\\d+)(?:%s|$)' % (re_uescape(sep)),
                               re.UNICODE)

        indexes = defaultdict(list)
        prune = self.prune_empty

        for key, value in pairs:
            if value == u'' and prune:
                continue
            m = regex.match(key)
            if not m:
                continue
            try:
                index = int(m.group(1))
            except TypeError:
                # Ignore keys with outrageously large indexes- they
                # aren't valid data for us.
                pass
            else:
                child_key = key[len(m.group(0)):] or None
                indexes[index].append((child_key, value))

        if not indexes:
            return

        # lossy: missing (or empty-valued) indexes are omitted.
        #        the python indexes may not match the flat indexes
        if prune:
            for offset, index in enumerate(sorted(indexes)):
                if offset == self.maximum_set_flat_members:
                    break
                slot = self._new_slot()
                list.append(self, slot)
                slot.element.set_flat(indexes[index], sep)
        # lossless: elements are built up to the highest seen index or a
        #           schema-configured maximum. flat + python indexes match.
        else:
            max_index = min(max(indexes) + 1, self.maximum_set_flat_members)
            for index in xrange(0, max_index):
                slot = self._new_slot()
                list.append(self, slot)
                flat = indexes.get(index, None)
                if flat:
                    slot.element.set_flat(flat, sep)
Ejemplo n.º 6
0
    def _set_flat(self, pairs, sep):
        del self[:]

        if not pairs:
            return

        if self.name:
            regex = re.compile(u'^%s(\\d+)(?:%s|$)' % (
                re_uescape(self.name + sep), re_uescape(sep)), re.UNICODE)
        else:
            regex = re.compile(u'^(\\d+)(?:%s|$)' % (
                re_uescape(sep)), re.UNICODE)

        indexes = defaultdict(list)
        prune = self.prune_empty

        for key, value in pairs:
            if value == u'' and prune:
                continue
            m = regex.match(key)
            if not m:
                continue
            try:
                index = int(m.group(1))
            except TypeError:
                # Ignore keys with outrageously large indexes- they
                # aren't valid data for us.
                pass
            else:
                child_key = key[len(m.group(0)):] or None
                indexes[index].append((child_key, value))

        if not indexes:
            return

        # lossy: missing (or empty-valued) indexes are omitted.
        #        the python indexes may not match the flat indexes
        if prune:
            for offset, index in enumerate(sorted(indexes)):
                if offset == self.maximum_set_flat_members:
                    break
                slot = self._new_slot()
                list.append(self, slot)
                slot.element.set_flat(indexes[index], sep)
        # lossless: elements are built up to the highest seen index or a
        #           schema-configured maximum. flat + python indexes match.
        else:
            max_index = min(max(indexes) + 1, self.maximum_set_flat_members)
            for index in xrange(0, max_index):
                slot = self._new_slot()
                list.append(self, slot)
                flat = indexes.get(index, None)
                if flat:
                    slot.element.set_flat(flat, sep)
Ejemplo n.º 7
0
    def __call__(self, element, strict=False):
        found = []
        contexts = [(self.ops, element)]

        for _ops, el in contexts:
            for idx in xrange(len(_ops)):
                op, data = _ops[idx]
                if op is TOP:
                    el = el.root
                elif op is UP:
                    if el.parent:
                        el = el.parent
                elif op is HERE:
                    pass
                elif op is NAME:
                    try:
                        el = el._index(data)
                    except (LookupError, TypeError):
                        if strict:
                            if el.name:
                                type_ = '%s element %s' % (
                                    el.__class__.__name__, decode_repr(
                                        el.name))
                            else:
                                type_ = 'Unnamed element %s' % (
                                    el.__class__.__name__)
                            raise LookupError(
                                "%s has no child %s in expression %s" %
                                (type_, decode_repr(data),
                                 decode_repr(self.expr)))
                        break
                elif op is SLICE:
                    children = list(el.children)[data]
                    contexts.extend(
                        (_ops[idx + 1:], child) for child in children)
                    break
            else:
                found.append(el)
        return found
Ejemplo n.º 8
0
    def __call__(self, element, strict=False):
        found = []
        contexts = [(self.ops, element)]

        for _ops, el in contexts:
            for idx in xrange(len(_ops)):
                op, data = _ops[idx]
                if op is TOP:
                    el = el.root
                elif op is UP:
                    if el.parent:
                        el = el.parent
                elif op is HERE:
                    pass
                elif op is NAME:
                    try:
                        el = el._index(data)
                    except (LookupError, TypeError):
                        if strict:
                            if el.name:
                                type_ = '%s element %r' % (
                                    el.__class__.__name__, el.name)
                            else:
                                type_ = 'Unnamed element %s' % (
                                    el.__class__.__name__)
                            raise LookupError(
                                "%s has no child %r in expression %r" % (
                                    type_, data, self.expr))
                        break
                elif op is SLICE:
                    children = list(el.children)[data]
                    contexts.extend((_ops[idx + 1:], child)
                                    for child in children)
                    break
            else:
                found.append(el)
        return found