def _set(o: Sequence[Any], repl_ctx: context.ReplContext, render_ctx: RenderContext, buf: terminal.Buffer) -> None: with buf.foldable_lines(): buf.write('[', style.bracket) with buf.indent(): for idx, el in enumerate(o): new_ctx = RenderContext(path=render_ctx.path + ((str(idx), 'index'), )) walk(el, repl_ctx, new_ctx, buf) if idx < (len(o) - 1): buf.write(',') buf.mark_line_break() if (repl_ctx.implicit_limit and (idx + 1) == repl_ctx.implicit_limit): # Unlike regular render mode, we treat implicit # limit overflow as an error, because the purpose # of JSON mode output is to be copy-pastable, and # neither rendering ellipses, nor rendering an # incorrect result are OK. steps = [] for deref, deref_kind in render_ctx.path: if deref_kind == 'index': steps.append(f'[{deref}]') elif deref_kind == 'key': steps.append(f'.{deref}') else: raise AssertionError( 'invalid path in RenderContext') raise JSONRenderingError( f"Cannot render JSON result: `.{''.join(steps)}` " f"is too long. Consider putting an explicit LIMIT " f"clause, or increase the implicit limit using " f"\\limit.") buf.write(']', style.bracket)
def _object_guts(o: edgedb.Object, repl_ctx: context.ReplContext, buf: terminal.Buffer, *, include_id_when_empty: bool) -> bool: pointers = introspect.introspect_object(o).pointers if not repl_ctx.show_implicit_fields: pointers = tuple(ptr for ptr in pointers if not ptr.implicit) pointers_len = len(pointers) pointers_rendered = 0 for ptr in pointers: buf.write(ptr.name, style.key) buf.write(': ') if ptr.kind is introspect.PointerKind.LINK: link = o[ptr.name] walk(link, repl_ctx, buf) else: val = getattr(o, ptr.name) walk(val, repl_ctx, buf) pointers_rendered += 1 if pointers_rendered < pointers_len: buf.write(',') buf.mark_line_break() if pointers_rendered == 0 and include_id_when_empty: buf.write('id', style.key) buf.write(': ') walk(o.id, repl_ctx, buf) pointers_rendered = 1 return pointers_rendered > 0
def _set(o: Union[edgedb.Array, edgedb.Tuple, edgedb.Set, edgedb.LinkSet], repl_ctx: context.ReplContext, buf: terminal.Buffer) -> None: if isinstance(o, edgedb.Array): begin, end = '[', ']' elif isinstance(o, edgedb.Tuple): begin, end = '(', ')' else: begin, end = '{', '}' last_idx = len(o) - 1 with buf.foldable_lines(): buf.write(begin, style.bracket) with buf.indent(): for idx, el in enumerate(o): walk(el, repl_ctx, buf) if idx < last_idx: buf.write(',') buf.mark_line_break() if (repl_ctx.implicit_limit and (idx + 1) == repl_ctx.implicit_limit): if idx == last_idx: buf.write(',') buf.mark_line_break() buf.write('...') if repl_ctx.implicit_limit > 10: buf.write(f'(further results hidden ' f'\\limit {repl_ctx.implicit_limit})') break buf.write(end, style.bracket)
def _dict(o: Mapping[str, Any], repl_ctx: context.ReplContext, render_ctx: RenderContext, buf: terminal.Buffer) -> None: with buf.foldable_lines(): buf.write('{', style.bracket) with buf.indent(): for idx, (key, el) in enumerate(o.items()): walk(key, repl_ctx, render_ctx, buf) buf.write(': ') new_ctx = RenderContext(path=render_ctx.path + ((str(key), 'key'), )) walk(el, repl_ctx, new_ctx, buf) if idx < (len(o) - 1): buf.write(',') buf.mark_line_break() buf.write('}', style.bracket)
def _namedtuple(o: edgedb.NamedTuple, repl_ctx: context.ReplContext, buf: terminal.Buffer) -> None: with buf.foldable_lines(): buf.write('(', style.bracket) with buf.indent(): # Call __dir__ directly as dir() scrambles the order. for idx, name in enumerate(o.__dir__()): val = getattr(o, name) buf.write(name) buf.write(' := ') walk(val, repl_ctx, buf) if idx < (len(o) - 1): buf.write(',') buf.mark_line_break() buf.write(')', style.bracket)
def _link( o: edgedb.Link, repl_ctx: context.ReplContext, buf: terminal.Buffer, ) -> None: with buf.foldable_lines(): buf.write(_object_name(o.target, repl_ctx), style.tree_node) buf.write(' {', style.tree_node) buf.folded_space() with buf.indent(): pointers = o.__dir__() pointers = tuple(ptr for ptr in pointers if ptr not in {'source', 'target'}) pointers_len = len(pointers) non_empty = _object_guts(o.target, repl_ctx, buf, include_id_when_empty=pointers_len == 0) if pointers_len > 0: if non_empty: buf.write(',') buf.mark_line_break() i = 0 for name in pointers: val = getattr(o, name) buf.write(f'@{name}', style.code_tag) buf.write(': ') walk(val, repl_ctx, buf) non_empty = True i += 1 if i < pointers_len: buf.write(',') buf.mark_line_break() if non_empty: buf.folded_space() buf.write('}', style.tree_node)