def _numeric( o: Union[int, float], repl_ctx: context.ReplContext, render_ctx: RenderContext, buf: terminal.Buffer ) -> None: buf.write(str(o), style.code_number)
def _bool( o: bool, repl_ctx: context.ReplContext, render_ctx: RenderContext, buf: terminal.Buffer ) -> None: buf.write(str(o).lower(), style.code_constant)
def walk(o: Any, repl_ctx: context.ReplContext, render_ctx: RenderContext, buf: terminal.Buffer) -> None: # The default renderer. Shouldn't be ever called, # but if for some reason we haven't defined a renderer # for some edgedb type it's better to render something # than crash. buf.write(str(o))
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 _str( o: str, repl_ctx: context.ReplContext, render_ctx: RenderContext, buf: terminal.Buffer ) -> None: o = str(o) buf.write(_encode_str(str(o)), style.code_string)
def _enum(o: edgedb.EnumValue, repl_ctx: context.ReplContext, buf: terminal.Buffer) -> None: if not repl_ctx.introspect_types: typename = 'enum' else: assert repl_ctx.typenames typename = repl_ctx.typenames.get(o.__tid__, 'enum') buf.write(f"<{typename}>", style.code_comment) buf.write(f"'{o}'", style.code_string)
def _datetime(o: datetime.datetime, repl_ctx: context.ReplContext, buf: terminal.Buffer) -> None: if o.tzinfo: buf.write("<datetime>", style.code_comment) else: buf.write("<local_datetime>", style.code_comment) buf.write(repr(o.isoformat()), style.code_string)
def _empty(o: None, repl_ctx: context.ReplContext, buf: terminal.Buffer) -> None: buf.write('null', style.code_constant)
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 _bigint(o: utils.BigInt, repl_ctx: context.ReplContext, buf: terminal.Buffer) -> None: buf.write(f'{o}n', style.code_number)
def _uuid(o: uuid.UUID, repl_ctx: context.ReplContext, buf: terminal.Buffer) -> None: buf.write(f'<uuid>{repr(str(o))}', style.code_comment)
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 _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)
def _str(o: str, repl_ctx: context.ReplContext, buf: terminal.Buffer) -> None: if "'" in o: rs = '"' + o.replace('"', r'\"') + '"' else: rs = "'" + o.replace("'", r"\'") + "'" buf.write(rs, style.code_string)
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 _bytes(o: bytes, repl_ctx: context.ReplContext, buf: terminal.Buffer) -> None: buf.write(repr(o), style.code_string)
def _empty(o: None, repl_ctx: context.ReplContext, buf: terminal.Buffer) -> None: buf.write('{}', style.bracket)
def _decimal(o: decimal.Decimal, repl_ctx: context.ReplContext, buf: terminal.Buffer) -> None: buf.write(f'{o}n', style.code_number)
def _duration(o: datetime.timedelta, repl_ctx: context.ReplContext, buf: terminal.Buffer) -> None: buf.write("<duration>", style.code_comment) buf.write(repr(str(o)), style.code_string)
def _object(o: edgedb.Object, repl_ctx: context.ReplContext, buf: terminal.Buffer) -> None: with buf.foldable_lines(): buf.write(_object_name(o, repl_ctx), style.tree_node) buf.write(' {', style.tree_node) buf.folded_space() with buf.indent(): non_empty = _object_guts(o, repl_ctx, buf, include_id_when_empty=True) if non_empty: buf.folded_space() buf.write('}', style.tree_node)