示例#1
0
 def container_visit(self, node):
     result = []
     for elem in node:
         if base.is_ast_node(elem) or typeutils.is_container(elem):
             result.append(self.visit(elem))
         else:
             result.append(elem)
     return node.__class__(result)
示例#2
0
    def container_visit(self, node):
        ctxlist = []
        for el in node:
            if isinstance(el, ast.AST) or typeutils.is_container(el):
                ctx = self.visit(el)

                if isinstance(ctx, list):
                    ctxlist.extend(ctx)
                else:
                    ctxlist.append(ctx)
        return ctxlist
示例#3
0
def nodes_equal(n1, n2):
    if type(n1) is not type(n2):
        return False

    for field, value in base.iter_fields(n1, include_meta=False):
        if not n1._fields[field].hidden:
            n1v = getattr(n1, field)
            n2v = getattr(n2, field)

            if typeutils.is_container(n1v):
                n1v = list(n1v)
                if typeutils.is_container(n2v):
                    n2v = list(n2v)
                else:
                    return False

                if len(n1v) != len(n2v):
                    return False

                for i, item1 in enumerate(n1v):
                    try:
                        item2 = n2v[i]
                    except IndexError:
                        return False

                    if base.is_ast_node(item1):
                        if not nodes_equal(item1, item2):
                            return False
                    else:
                        if item1 != item2:
                            return False

            elif base.is_ast_node(n1v):
                if not nodes_equal(n1v, n2v):
                    return False

            else:
                if n1v != n2v:
                    return False

    return True
示例#4
0
 def combine_field_results(self, results, *, flatten=True):
     if flatten:
         flattened = []
         for res in results:
             if isinstance(res, Field):
                 flattened.append(res)
             elif typeutils.is_container(res):
                 flattened.extend(res)
             else:
                 flattened.append(res)
         return flattened
     else:
         return results
示例#5
0
    def _infer_nullability(self, kwargs: typing.Dict[str, object]) -> bool:
        nullable = False
        for k, v in kwargs.items():
            if typeutils.is_container(v):
                nullable = all(getattr(vv, 'nullable', False) for vv in v)

            elif getattr(v, 'nullable', None):
                nullable = True

            if nullable:
                break

        return nullable
示例#6
0
    def generic_visit(self, node):
        for field, old_value in base.iter_fields(node, include_meta=False):
            old_value = getattr(node, field, None)

            if typeutils.is_container(old_value):
                new_values = old_value.__class__(self.visit(old_value))
                setattr(node, field, old_value.__class__(new_values))

            elif isinstance(old_value, base.AST):
                new_node = self.visit(old_value)
                if new_node is not old_value:
                    if new_node is not None:
                        new_node.parent = node
                    setattr(node, field, new_node)

        return node
示例#7
0
def fix_parent_links(node):
    for field, value in iter_fields(node):
        if isinstance(value, dict):
            for n in value.values():
                if is_ast_node(n):
                    n.parent = node
                    fix_parent_links(n)

        elif typeutils.is_container(value):
            for n in value:
                if is_ast_node(n):
                    n.parent = node
                    fix_parent_links(n)

        elif is_ast_node(value):
            value.parent = node
            fix_parent_links(value)

    return node
示例#8
0
    def generic_visit(self, node, *, combine_results=None):
        field_results = []

        for field, value in base.iter_fields(node, include_meta=False):
            if typeutils.is_container(value):
                for item in value:
                    if base.is_ast_node(item):
                        res = self.visit(item)
                        if res is not None:
                            field_results.append(res)
            elif base.is_ast_node(value):
                res = self.visit(value)
                if res is not None:
                    field_results.append(res)

        if combine_results is not None:
            return combine_results(field_results)
        else:
            return self.combine_field_results(field_results)
示例#9
0
def encode_value(val: object) -> str:
    """Encode value into an appropriate SQL expression."""
    if hasattr(val, 'to_sql_expr'):
        val = val.to_sql_expr()
    elif isinstance(val, tuple):
        val_list = [encode_value(el) for el in val]
        val = f'ROW({", ".join(val_list)})'
    elif typeutils.is_container(val):
        val_list = [encode_value(el) for el in val]
        val = f'ARRAY[{", ".join(val_list)}]'
    elif val is None:
        val = 'NULL'
    elif not isinstance(val, numbers.Number):
        val = ql(str(val))
    elif isinstance(val, int):
        val = str(int(val))
    else:
        val = str(val)

    return val
示例#10
0
 def visit(self, node):
     if typeutils.is_container(node):
         return self.container_visit(node)
     else:
         return self.node_visit(node)