Skip to content

Commit 68b1700

Browse files
committed
starting prettier print
1 parent c61c373 commit 68b1700

1 file changed

Lines changed: 102 additions & 0 deletions

File tree

devtools/prettier.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import io
2+
import textwrap
3+
import collections
4+
from typing import Any
5+
6+
7+
PARENTHESES_LOOKUP = [
8+
(list, '[', ']'),
9+
(set, '{', '}'),
10+
]
11+
12+
13+
class PrettyFormat:
14+
def __init__(self,
15+
indent_step=4,
16+
indent_char=' ',
17+
repr_strings=False,
18+
yield_from_generators=True):
19+
# TODO colours
20+
self._indent_step = indent_step
21+
self._c = indent_char
22+
self._repr_strings = repr_strings
23+
self._repr_generators = not yield_from_generators
24+
self._type_lookup = [
25+
(dict, self._format_dict),
26+
((tuple, list, set), self._format_list_like),
27+
(str, self._format_str),
28+
(collections.Generator, self._format_generators),
29+
]
30+
31+
def __call__(self, value: Any, *, indent_current: int=0):
32+
self._stream = io.StringIO()
33+
self._format(value, indent_current=indent_current, indent_first=True)
34+
return self._stream.getvalue()
35+
36+
def _format(self, value: Any, indent_current: int, indent_first: bool):
37+
if indent_first:
38+
self._stream.write(indent_current * self._c)
39+
40+
indent_new = indent_current + self._indent_step
41+
for t, func in self._type_lookup:
42+
if isinstance(value, t):
43+
func(value, indent_current, indent_new)
44+
return
45+
46+
value_s = repr(value)
47+
if '\n' in value_s:
48+
value_s = textwrap.indent(value_s, indent_new * self._c).lstrip(' ')
49+
self._stream.write(value_s)
50+
51+
def _format_dict(self, value, indent_current, indent_new):
52+
self._stream.write('{\n')
53+
for k, v in value.items():
54+
self._format(k, indent_new, True)
55+
self._stream.write(': ')
56+
self._format(v, indent_new, False)
57+
self._stream.write(',\n')
58+
self._stream.write(indent_current * self._c + '}')
59+
60+
def _format_list_like(self, value, indent_current, indent_new):
61+
open_, close_ = '(', ')'
62+
for t, *oc in PARENTHESES_LOOKUP:
63+
if isinstance(value, t):
64+
open_, close_ = oc
65+
break
66+
67+
self._stream.write(open_ + '\n')
68+
for v in value:
69+
self._format(v, indent_new, True)
70+
self._stream.write(',\n')
71+
self._stream.write(indent_current * self._c + close_)
72+
73+
def _format_str(self, value, indent_current, indent_new):
74+
if self._repr_strings:
75+
self._stream.write(repr(value))
76+
else:
77+
lines = value.splitlines(True)
78+
if len(lines) > 1:
79+
self._stream.write('(\n')
80+
prefix = indent_new * self._c
81+
for line in lines:
82+
self._stream.write(prefix + repr(line) + '\n')
83+
self._stream.write(indent_current * self._c + ')')
84+
else:
85+
self._stream.write(repr(value))
86+
87+
def _format_generators(self, value, indent_current, indent_new):
88+
if self._repr_generators:
89+
self._stream.write(repr(value))
90+
else:
91+
self._stream.write('(\n')
92+
for v in value:
93+
self._format(v, indent_new, True)
94+
self._stream.write(',\n')
95+
self._stream.write(indent_current * self._c + ')')
96+
97+
98+
pformat = PrettyFormat()
99+
100+
101+
def pprint(s):
102+
print(pformat(s), flush=True)

0 commit comments

Comments
 (0)