We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Bad pretty printing of datetime
Here is what I get:
```
edgedb> SELECT <datetime>'2020-01-08T17:03:06.026178+00:00';
{<local_date>'2020-01-08T17:03:06.026178+00:00'}
```
Well the `datetime` in python is a subclass of `date` but `singledispatch` is supposed to handle that well. Do we have a patched singledispatch now?

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `edb/repl/render_binary.py`
Content:
```
1 #
2 # This source file is part of the EdgeDB open source project.
3 #
4 # Copyright 2019-present MagicStack Inc. and the EdgeDB authors.
5 #
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
9 #
10 #     http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17 #
18 
19 
20 from __future__ import annotations
21 from typing import *  # NoQA
22 
23 import datetime
24 import decimal
25 import functools
26 import uuid
27 
28 import edgedb
29 from edgedb import introspect
30 
31 from edb.common.markup.renderers import terminal
32 from edb.common.markup.renderers import styles
33 
34 from . import context
35 
36 
37 style = styles.Dark256
38 
39 
40 @functools.singledispatch
41 def walk(
42     o: Any,
43     repl_ctx: context.ReplContext,
44     buf: terminal.Buffer
45 ) -> None:
46     # The default renderer.  Shouldn't be ever called,
47     # but if for some reason we haven't defined a renderer
48     # for some edgedb type it's better to render something
49     # than crash.
50     buf.write(str(o))
51 
52 
53 def _object_guts(
54     o: edgedb.Object,
55     repl_ctx: context.ReplContext,
56     buf: terminal.Buffer,
57     *,
58     include_id_when_empty: bool
59 ) -> bool:
60     pointers = introspect.introspect_object(o).pointers
61     if not repl_ctx.show_implicit_fields:
62         pointers = tuple(ptr for ptr in pointers if not ptr.implicit)
63     pointers_len = len(pointers)
64 
65     pointers_rendered = 0
66     for ptr in pointers:
67         buf.write(ptr.name, style.key)
68         buf.write(': ')
69 
70         if ptr.kind is introspect.PointerKind.LINK:
71             link = o[ptr.name]
72             walk(link, repl_ctx, buf)
73         else:
74             val = getattr(o, ptr.name)
75             walk(val, repl_ctx, buf)
76 
77         pointers_rendered += 1
78         if pointers_rendered < pointers_len:
79             buf.write(',')
80             buf.mark_line_break()
81 
82     if pointers_rendered == 0 and include_id_when_empty:
83         buf.write('id', style.key)
84         buf.write(': ')
85         walk(o.id, repl_ctx, buf)
86         pointers_rendered = 1
87 
88     return pointers_rendered > 0
89 
90 
91 def _object_name(o: edgedb.Object, repl_ctx: context.ReplContext) -> str:
92     if not repl_ctx.introspect_types:
93         return 'Object'
94     assert repl_ctx.typenames
95     return repl_ctx.typenames.get(o.__tid__, 'Object')
96 
97 
98 @walk.register
99 def _link(
100     o: edgedb.Link,
101     repl_ctx: context.ReplContext,
102     buf: terminal.Buffer,
103 ) -> None:
104     with buf.foldable_lines():
105         buf.write(_object_name(o.target, repl_ctx), style.tree_node)
106         buf.write(' {', style.tree_node)
107         buf.folded_space()
108         with buf.indent():
109             pointers = o.__dir__()
110             pointers = tuple(ptr for ptr in pointers
111                              if ptr not in {'source', 'target'})
112             pointers_len = len(pointers)
113 
114             non_empty = _object_guts(
115                 o.target, repl_ctx, buf,
116                 include_id_when_empty=pointers_len == 0)
117 
118             if pointers_len > 0:
119                 if non_empty:
120                     buf.write(',')
121                     buf.mark_line_break()
122 
123                 i = 0
124                 for name in pointers:
125                     val = getattr(o, name)
126 
127                     buf.write(f'@{name}', style.code_tag)
128                     buf.write(': ')
129                     walk(val, repl_ctx, buf)
130                     non_empty = True
131 
132                     i += 1
133                     if i < pointers_len:
134                         buf.write(',')
135                         buf.mark_line_break()
136 
137         if non_empty:
138             buf.folded_space()
139         buf.write('}', style.tree_node)
140 
141 
142 @walk.register
143 def _object(
144     o: edgedb.Object,
145     repl_ctx: context.ReplContext,
146     buf: terminal.Buffer
147 ) -> None:
148     with buf.foldable_lines():
149         buf.write(_object_name(o, repl_ctx), style.tree_node)
150         buf.write(' {', style.tree_node)
151         buf.folded_space()
152         with buf.indent():
153             non_empty = _object_guts(
154                 o, repl_ctx, buf, include_id_when_empty=True)
155         if non_empty:
156             buf.folded_space()
157         buf.write('}', style.tree_node)
158 
159 
160 @walk.register
161 def _namedtuple(
162     o: edgedb.NamedTuple,
163     repl_ctx: context.ReplContext,
164     buf: terminal.Buffer
165 ) -> None:
166     with buf.foldable_lines():
167         buf.write('(', style.bracket)
168         with buf.indent():
169             # Call __dir__ directly as dir() scrambles the order.
170             for idx, name in enumerate(o.__dir__()):
171                 val = getattr(o, name)
172 
173                 buf.write(name)
174                 buf.write(' := ')
175                 walk(val, repl_ctx, buf)
176 
177                 if idx < (len(o) - 1):
178                     buf.write(',')
179                     buf.mark_line_break()
180         buf.write(')', style.bracket)
181 
182 
183 @walk.register(edgedb.Array)
184 @walk.register(edgedb.Tuple)
185 @walk.register(edgedb.Set)
186 @walk.register(edgedb.LinkSet)
187 def _set(
188     o: Union[edgedb.Array, edgedb.Tuple, edgedb.Set, edgedb.LinkSet],
189     repl_ctx: context.ReplContext,
190     buf: terminal.Buffer
191 ) -> None:
192     if isinstance(o, edgedb.Array):
193         begin, end = '[', ']'
194     elif isinstance(o, edgedb.Tuple):
195         begin, end = '(', ')'
196     else:
197         begin, end = '{', '}'
198 
199     with buf.foldable_lines():
200         buf.write(begin, style.bracket)
201         with buf.indent():
202             for idx, el in enumerate(o):
203                 walk(el, repl_ctx, buf)
204                 if idx < (len(o) - 1):
205                     buf.write(',')
206                     buf.mark_line_break()
207         buf.write(end, style.bracket)
208 
209 
210 @walk.register
211 def _uuid(
212     o: uuid.UUID,
213     repl_ctx: context.ReplContext,
214     buf: terminal.Buffer
215 ) -> None:
216     buf.write(f'<uuid>{repr(str(o))}', style.code_comment)
217 
218 
219 @walk.register(int)
220 @walk.register(float)
221 def _numeric(
222     o: Union[int, float],
223     repl_ctx: context.ReplContext,
224     buf: terminal.Buffer
225 ) -> None:
226     buf.write(str(o), style.code_number)
227 
228 
229 @walk.register
230 def _str(
231     o: str,
232     repl_ctx: context.ReplContext,
233     buf: terminal.Buffer
234 ) -> None:
235     if "'" in o:
236         rs = '"' + o.replace('"', r'\"') + '"'
237     else:
238         rs = "'" + o.replace("'", r"\'") + "'"
239     buf.write(rs, style.code_string)
240 
241 
242 @walk.register
243 def _bytes(
244     o: bytes,
245     repl_ctx: context.ReplContext,
246     buf: terminal.Buffer
247 ) -> None:
248     buf.write(repr(o), style.code_string)
249 
250 
251 @walk.register
252 def _bool(
253     o: bool,
254     repl_ctx: context.ReplContext,
255     buf: terminal.Buffer
256 ) -> None:
257     buf.write(str(o).lower(), style.code_constant)
258 
259 
260 @walk.register
261 def _decimal(
262     o: decimal.Decimal,
263     repl_ctx: context.ReplContext,
264     buf: terminal.Buffer
265 ) -> None:
266     buf.write(f'{o}n', style.code_number)
267 
268 
269 @walk.register
270 def _empty(
271     o: None,
272     repl_ctx: context.ReplContext,
273     buf: terminal.Buffer
274 ) -> None:
275     buf.write('{}', style.bracket)
276 
277 
278 def _datetime(
279     o: datetime.datetime,
280     repl_ctx: context.ReplContext,
281     buf: terminal.Buffer
282 ) -> None:
283     if o.tzinfo:
284         buf.write("<datetime>", style.code_comment)
285     else:
286         buf.write("<local_datetime>", style.code_comment)
287 
288     buf.write(repr(o.isoformat()), style.code_string)
289 
290 
291 @walk.register
292 def _date(
293     o: datetime.date,
294     repl_ctx: context.ReplContext,
295     buf: terminal.Buffer
296 ) -> None:
297     buf.write("<local_date>", style.code_comment)
298     buf.write(repr(o.isoformat()), style.code_string)
299 
300 
301 @walk.register
302 def _time(
303     o: datetime.time,
304     repl_ctx: context.ReplContext,
305     buf: terminal.Buffer
306 ) -> None:
307     buf.write("<local_time>", style.code_comment)
308     buf.write(repr(o.isoformat()), style.code_string)
309 
310 
311 @walk.register
312 def _duration(
313     o: datetime.timedelta,
314     repl_ctx: context.ReplContext,
315     buf: terminal.Buffer
316 ) -> None:
317     buf.write("<duration>", style.code_comment)
318     buf.write(repr(str(o)), style.code_string)
319 
320 
321 @walk.register
322 def _enum(
323     o: edgedb.EnumValue,
324     repl_ctx: context.ReplContext,
325     buf: terminal.Buffer
326 ) -> None:
327     if not repl_ctx.introspect_types:
328         typename = 'enum'
329     else:
330         assert repl_ctx.typenames
331         typename = repl_ctx.typenames.get(o.__tid__, 'enum')
332 
333     buf.write(f"<{typename}>", style.code_comment)
334     buf.write(f"'{o}'", style.code_string)
335
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/edb/repl/render_binary.py b/edb/repl/render_binary.py
--- a/edb/repl/render_binary.py
+++ b/edb/repl/render_binary.py
@@ -275,6 +275,7 @@
     buf.write('{}', style.bracket)
 
 
+@walk.register
 def _datetime(
     o: datetime.datetime,
     repl_ctx: context.ReplContext,

{"golden_diff": "diff --git a/edb/repl/render_binary.py b/edb/repl/render_binary.py\n--- a/edb/repl/render_binary.py\n+++ b/edb/repl/render_binary.py\n@@ -275,6 +275,7 @@\n     buf.write('{}', style.bracket)\n \n \n+@walk.register\n def _datetime(\n     o: datetime.datetime,\n     repl_ctx: context.ReplContext,\n", "issue": "Bad pretty printing of datetime\nHere is what I get:\r\n```\r\nedgedb> SELECT <datetime>'2020-01-08T17:03:06.026178+00:00';\r\n{<local_date>'2020-01-08T17:03:06.026178+00:00'}\r\n```\r\nWell the `datetime` in python is a subclass of `date` but `singledispatch` is supposed to handle that well. Do we have a patched singledispatch now?\n", "before_files": [{"content": "#\n# This source file is part of the EdgeDB open source project.\n#\n# Copyright 2019-present MagicStack Inc. and the EdgeDB authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n\nfrom __future__ import annotations\nfrom typing import *  # NoQA\n\nimport datetime\nimport decimal\nimport functools\nimport uuid\n\nimport edgedb\nfrom edgedb import introspect\n\nfrom edb.common.markup.renderers import terminal\nfrom edb.common.markup.renderers import styles\n\nfrom . import context\n\n\nstyle = styles.Dark256\n\n\n@functools.singledispatch\ndef walk(\n    o: Any,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    # The default renderer.  Shouldn't be ever called,\n    # but if for some reason we haven't defined a renderer\n    # for some edgedb type it's better to render something\n    # than crash.\n    buf.write(str(o))\n\n\ndef _object_guts(\n    o: edgedb.Object,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer,\n    *,\n    include_id_when_empty: bool\n) -> bool:\n    pointers = introspect.introspect_object(o).pointers\n    if not repl_ctx.show_implicit_fields:\n        pointers = tuple(ptr for ptr in pointers if not ptr.implicit)\n    pointers_len = len(pointers)\n\n    pointers_rendered = 0\n    for ptr in pointers:\n        buf.write(ptr.name, style.key)\n        buf.write(': ')\n\n        if ptr.kind is introspect.PointerKind.LINK:\n            link = o[ptr.name]\n            walk(link, repl_ctx, buf)\n        else:\n            val = getattr(o, ptr.name)\n            walk(val, repl_ctx, buf)\n\n        pointers_rendered += 1\n        if pointers_rendered < pointers_len:\n            buf.write(',')\n            buf.mark_line_break()\n\n    if pointers_rendered == 0 and include_id_when_empty:\n        buf.write('id', style.key)\n        buf.write(': ')\n        walk(o.id, repl_ctx, buf)\n        pointers_rendered = 1\n\n    return pointers_rendered > 0\n\n\ndef _object_name(o: edgedb.Object, repl_ctx: context.ReplContext) -> str:\n    if not repl_ctx.introspect_types:\n        return 'Object'\n    assert repl_ctx.typenames\n    return repl_ctx.typenames.get(o.__tid__, 'Object')\n\n\n@walk.register\ndef _link(\n    o: edgedb.Link,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer,\n) -> None:\n    with buf.foldable_lines():\n        buf.write(_object_name(o.target, repl_ctx), style.tree_node)\n        buf.write(' {', style.tree_node)\n        buf.folded_space()\n        with buf.indent():\n            pointers = o.__dir__()\n            pointers = tuple(ptr for ptr in pointers\n                             if ptr not in {'source', 'target'})\n            pointers_len = len(pointers)\n\n            non_empty = _object_guts(\n                o.target, repl_ctx, buf,\n                include_id_when_empty=pointers_len == 0)\n\n            if pointers_len > 0:\n                if non_empty:\n                    buf.write(',')\n                    buf.mark_line_break()\n\n                i = 0\n                for name in pointers:\n                    val = getattr(o, name)\n\n                    buf.write(f'@{name}', style.code_tag)\n                    buf.write(': ')\n                    walk(val, repl_ctx, buf)\n                    non_empty = True\n\n                    i += 1\n                    if i < pointers_len:\n                        buf.write(',')\n                        buf.mark_line_break()\n\n        if non_empty:\n            buf.folded_space()\n        buf.write('}', style.tree_node)\n\n\n@walk.register\ndef _object(\n    o: edgedb.Object,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    with buf.foldable_lines():\n        buf.write(_object_name(o, repl_ctx), style.tree_node)\n        buf.write(' {', style.tree_node)\n        buf.folded_space()\n        with buf.indent():\n            non_empty = _object_guts(\n                o, repl_ctx, buf, include_id_when_empty=True)\n        if non_empty:\n            buf.folded_space()\n        buf.write('}', style.tree_node)\n\n\n@walk.register\ndef _namedtuple(\n    o: edgedb.NamedTuple,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    with buf.foldable_lines():\n        buf.write('(', style.bracket)\n        with buf.indent():\n            # Call __dir__ directly as dir() scrambles the order.\n            for idx, name in enumerate(o.__dir__()):\n                val = getattr(o, name)\n\n                buf.write(name)\n                buf.write(' := ')\n                walk(val, repl_ctx, buf)\n\n                if idx < (len(o) - 1):\n                    buf.write(',')\n                    buf.mark_line_break()\n        buf.write(')', style.bracket)\n\n\n@walk.register(edgedb.Array)\n@walk.register(edgedb.Tuple)\n@walk.register(edgedb.Set)\n@walk.register(edgedb.LinkSet)\ndef _set(\n    o: Union[edgedb.Array, edgedb.Tuple, edgedb.Set, edgedb.LinkSet],\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    if isinstance(o, edgedb.Array):\n        begin, end = '[', ']'\n    elif isinstance(o, edgedb.Tuple):\n        begin, end = '(', ')'\n    else:\n        begin, end = '{', '}'\n\n    with buf.foldable_lines():\n        buf.write(begin, style.bracket)\n        with buf.indent():\n            for idx, el in enumerate(o):\n                walk(el, repl_ctx, buf)\n                if idx < (len(o) - 1):\n                    buf.write(',')\n                    buf.mark_line_break()\n        buf.write(end, style.bracket)\n\n\n@walk.register\ndef _uuid(\n    o: uuid.UUID,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    buf.write(f'<uuid>{repr(str(o))}', style.code_comment)\n\n\n@walk.register(int)\n@walk.register(float)\ndef _numeric(\n    o: Union[int, float],\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    buf.write(str(o), style.code_number)\n\n\n@walk.register\ndef _str(\n    o: str,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    if \"'\" in o:\n        rs = '\"' + o.replace('\"', r'\\\"') + '\"'\n    else:\n        rs = \"'\" + o.replace(\"'\", r\"\\'\") + \"'\"\n    buf.write(rs, style.code_string)\n\n\n@walk.register\ndef _bytes(\n    o: bytes,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    buf.write(repr(o), style.code_string)\n\n\n@walk.register\ndef _bool(\n    o: bool,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    buf.write(str(o).lower(), style.code_constant)\n\n\n@walk.register\ndef _decimal(\n    o: decimal.Decimal,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    buf.write(f'{o}n', style.code_number)\n\n\n@walk.register\ndef _empty(\n    o: None,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    buf.write('{}', style.bracket)\n\n\ndef _datetime(\n    o: datetime.datetime,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    if o.tzinfo:\n        buf.write(\"<datetime>\", style.code_comment)\n    else:\n        buf.write(\"<local_datetime>\", style.code_comment)\n\n    buf.write(repr(o.isoformat()), style.code_string)\n\n\n@walk.register\ndef _date(\n    o: datetime.date,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    buf.write(\"<local_date>\", style.code_comment)\n    buf.write(repr(o.isoformat()), style.code_string)\n\n\n@walk.register\ndef _time(\n    o: datetime.time,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    buf.write(\"<local_time>\", style.code_comment)\n    buf.write(repr(o.isoformat()), style.code_string)\n\n\n@walk.register\ndef _duration(\n    o: datetime.timedelta,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    buf.write(\"<duration>\", style.code_comment)\n    buf.write(repr(str(o)), style.code_string)\n\n\n@walk.register\ndef _enum(\n    o: edgedb.EnumValue,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    if not repl_ctx.introspect_types:\n        typename = 'enum'\n    else:\n        assert repl_ctx.typenames\n        typename = repl_ctx.typenames.get(o.__tid__, 'enum')\n\n    buf.write(f\"<{typename}>\", style.code_comment)\n    buf.write(f\"'{o}'\", style.code_string)\n", "path": "edb/repl/render_binary.py"}], "after_files": [{"content": "#\n# This source file is part of the EdgeDB open source project.\n#\n# Copyright 2019-present MagicStack Inc. and the EdgeDB authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n\nfrom __future__ import annotations\nfrom typing import *  # NoQA\n\nimport datetime\nimport decimal\nimport functools\nimport uuid\n\nimport edgedb\nfrom edgedb import introspect\n\nfrom edb.common.markup.renderers import terminal\nfrom edb.common.markup.renderers import styles\n\nfrom . import context\n\n\nstyle = styles.Dark256\n\n\n@functools.singledispatch\ndef walk(\n    o: Any,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    # The default renderer.  Shouldn't be ever called,\n    # but if for some reason we haven't defined a renderer\n    # for some edgedb type it's better to render something\n    # than crash.\n    buf.write(str(o))\n\n\ndef _object_guts(\n    o: edgedb.Object,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer,\n    *,\n    include_id_when_empty: bool\n) -> bool:\n    pointers = introspect.introspect_object(o).pointers\n    if not repl_ctx.show_implicit_fields:\n        pointers = tuple(ptr for ptr in pointers if not ptr.implicit)\n    pointers_len = len(pointers)\n\n    pointers_rendered = 0\n    for ptr in pointers:\n        buf.write(ptr.name, style.key)\n        buf.write(': ')\n\n        if ptr.kind is introspect.PointerKind.LINK:\n            link = o[ptr.name]\n            walk(link, repl_ctx, buf)\n        else:\n            val = getattr(o, ptr.name)\n            walk(val, repl_ctx, buf)\n\n        pointers_rendered += 1\n        if pointers_rendered < pointers_len:\n            buf.write(',')\n            buf.mark_line_break()\n\n    if pointers_rendered == 0 and include_id_when_empty:\n        buf.write('id', style.key)\n        buf.write(': ')\n        walk(o.id, repl_ctx, buf)\n        pointers_rendered = 1\n\n    return pointers_rendered > 0\n\n\ndef _object_name(o: edgedb.Object, repl_ctx: context.ReplContext) -> str:\n    if not repl_ctx.introspect_types:\n        return 'Object'\n    assert repl_ctx.typenames\n    return repl_ctx.typenames.get(o.__tid__, 'Object')\n\n\n@walk.register\ndef _link(\n    o: edgedb.Link,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer,\n) -> None:\n    with buf.foldable_lines():\n        buf.write(_object_name(o.target, repl_ctx), style.tree_node)\n        buf.write(' {', style.tree_node)\n        buf.folded_space()\n        with buf.indent():\n            pointers = o.__dir__()\n            pointers = tuple(ptr for ptr in pointers\n                             if ptr not in {'source', 'target'})\n            pointers_len = len(pointers)\n\n            non_empty = _object_guts(\n                o.target, repl_ctx, buf,\n                include_id_when_empty=pointers_len == 0)\n\n            if pointers_len > 0:\n                if non_empty:\n                    buf.write(',')\n                    buf.mark_line_break()\n\n                i = 0\n                for name in pointers:\n                    val = getattr(o, name)\n\n                    buf.write(f'@{name}', style.code_tag)\n                    buf.write(': ')\n                    walk(val, repl_ctx, buf)\n                    non_empty = True\n\n                    i += 1\n                    if i < pointers_len:\n                        buf.write(',')\n                        buf.mark_line_break()\n\n        if non_empty:\n            buf.folded_space()\n        buf.write('}', style.tree_node)\n\n\n@walk.register\ndef _object(\n    o: edgedb.Object,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    with buf.foldable_lines():\n        buf.write(_object_name(o, repl_ctx), style.tree_node)\n        buf.write(' {', style.tree_node)\n        buf.folded_space()\n        with buf.indent():\n            non_empty = _object_guts(\n                o, repl_ctx, buf, include_id_when_empty=True)\n        if non_empty:\n            buf.folded_space()\n        buf.write('}', style.tree_node)\n\n\n@walk.register\ndef _namedtuple(\n    o: edgedb.NamedTuple,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    with buf.foldable_lines():\n        buf.write('(', style.bracket)\n        with buf.indent():\n            # Call __dir__ directly as dir() scrambles the order.\n            for idx, name in enumerate(o.__dir__()):\n                val = getattr(o, name)\n\n                buf.write(name)\n                buf.write(' := ')\n                walk(val, repl_ctx, buf)\n\n                if idx < (len(o) - 1):\n                    buf.write(',')\n                    buf.mark_line_break()\n        buf.write(')', style.bracket)\n\n\n@walk.register(edgedb.Array)\n@walk.register(edgedb.Tuple)\n@walk.register(edgedb.Set)\n@walk.register(edgedb.LinkSet)\ndef _set(\n    o: Union[edgedb.Array, edgedb.Tuple, edgedb.Set, edgedb.LinkSet],\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    if isinstance(o, edgedb.Array):\n        begin, end = '[', ']'\n    elif isinstance(o, edgedb.Tuple):\n        begin, end = '(', ')'\n    else:\n        begin, end = '{', '}'\n\n    with buf.foldable_lines():\n        buf.write(begin, style.bracket)\n        with buf.indent():\n            for idx, el in enumerate(o):\n                walk(el, repl_ctx, buf)\n                if idx < (len(o) - 1):\n                    buf.write(',')\n                    buf.mark_line_break()\n        buf.write(end, style.bracket)\n\n\n@walk.register\ndef _uuid(\n    o: uuid.UUID,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    buf.write(f'<uuid>{repr(str(o))}', style.code_comment)\n\n\n@walk.register(int)\n@walk.register(float)\ndef _numeric(\n    o: Union[int, float],\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    buf.write(str(o), style.code_number)\n\n\n@walk.register\ndef _str(\n    o: str,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    if \"'\" in o:\n        rs = '\"' + o.replace('\"', r'\\\"') + '\"'\n    else:\n        rs = \"'\" + o.replace(\"'\", r\"\\'\") + \"'\"\n    buf.write(rs, style.code_string)\n\n\n@walk.register\ndef _bytes(\n    o: bytes,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    buf.write(repr(o), style.code_string)\n\n\n@walk.register\ndef _bool(\n    o: bool,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    buf.write(str(o).lower(), style.code_constant)\n\n\n@walk.register\ndef _decimal(\n    o: decimal.Decimal,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    buf.write(f'{o}n', style.code_number)\n\n\n@walk.register\ndef _empty(\n    o: None,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    buf.write('{}', style.bracket)\n\n\n@walk.register\ndef _datetime(\n    o: datetime.datetime,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    if o.tzinfo:\n        buf.write(\"<datetime>\", style.code_comment)\n    else:\n        buf.write(\"<local_datetime>\", style.code_comment)\n\n    buf.write(repr(o.isoformat()), style.code_string)\n\n\n@walk.register\ndef _date(\n    o: datetime.date,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    buf.write(\"<local_date>\", style.code_comment)\n    buf.write(repr(o.isoformat()), style.code_string)\n\n\n@walk.register\ndef _time(\n    o: datetime.time,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    buf.write(\"<local_time>\", style.code_comment)\n    buf.write(repr(o.isoformat()), style.code_string)\n\n\n@walk.register\ndef _duration(\n    o: datetime.timedelta,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    buf.write(\"<duration>\", style.code_comment)\n    buf.write(repr(str(o)), style.code_string)\n\n\n@walk.register\ndef _enum(\n    o: edgedb.EnumValue,\n    repl_ctx: context.ReplContext,\n    buf: terminal.Buffer\n) -> None:\n    if not repl_ctx.introspect_types:\n        typename = 'enum'\n    else:\n        assert repl_ctx.typenames\n        typename = repl_ctx.typenames.get(o.__tid__, 'enum')\n\n    buf.write(f\"<{typename}>\", style.code_comment)\n    buf.write(f\"'{o}'\", style.code_string)\n", "path": "edb/repl/render_binary.py"}]}