Exemplo n.º 1
0
    def _walk(datatype, value, callback, path='', options=None):
        options = options or []
        if isinstance(datatype, str):
            datatype, parsed_options = parse_primitive(datatype)
            options += parsed_options

        # Transform special types:
        dt_type = typename(datatype)
        if dt_type == 'choice':
            datatype = Choice(datatype.get('choices'))
        elif dt_type == 'reference':
            datatype = named_types[datatype['name']]
        elif dt_type == 'literal':
            datatype = Literal(datatype.get('value'))

        new_value = callback(path, datatype, value, options)

        # Are we replacing the value?
        if isinstance(new_value, NewValue):
            value = new_value.value

        # Walk lists and tuples
        if are_type(list, datatype, value):
            dt_len = len(datatype)
            mk_path = lambda i: joinpaths(path, '[%d]' % i)

            if dt_len == 1:   # list of `a`
                value = [_walk(datatype[0], v, callback, mk_path(i))
                         for i, v in enumerate(value)]
            elif dt_len > 1:  # tuple
                value = [_walk(d, v, callback, mk_path(i))
                         for i, d, v in zip(count(), datatype, value)]

        # Walk objects (dictionaries)
        elif are_type(dict, datatype, value):
            key_dts = dict_datatypes(datatype)
            mk_path = lambda k: joinpaths(path, k, '.')

            value = dict((k, _walk(key_dts[k], v, callback, mk_path(k)))
                for k, v in value.iteritems())

        return value
Exemplo n.º 2
0
def extract_named_types(datatype):
    """Walks the given datatype, removes the named-wrappers from around the
    types and returns a dictionary of names -> types as well as the cleaned
    datatype."""
    named_types = {}

    if typename(datatype) == 'named':
        named_types[datatype['name']] = datatype['value']
        datatype = datatype['value']

    dt_type = type(datatype)
    if dt_type in (list, dict):
        generators = {
                list: lambda: enumerate(datatype),
                dict: lambda: datatype.iteritems(),
            }
        for key, subtype in generators[dt_type]():
            sub_named_types, subtype = extract_named_types(subtype)
            named_types.update(sub_named_types)
            datatype[key] = subtype

    return named_types, datatype
Exemplo n.º 3
0
def test_typename():
    assert typename('int') == 'type'
    assert typename({'_type_': 'choice'}) == 'choice'
    assert typename({'_type_': 'foo'}) == 'foo'
    assert typename({}) == 'type'
    assert typename([]) == 'type'