blob: 44d4e49fbe94f285b8cc3b65a06617815c0561a2 [file] [log] [blame]
koder aka kdanilovf4b82c22015-04-11 13:35:25 +03001def dumps_simple(val):
2 bad_symbols = set(" \r\t\n,':")
3
4 if isinstance(val, basestring):
5 if len(bad_symbols & set(val)) != 0:
6 return repr(val)
7 return val
8 elif val is True:
9 return 'true'
10 elif val is False:
11 return 'false'
12 elif val is None:
13 return 'null'
14
15 return str(val)
16
17
18def is_simple(val):
19 simple_type = isinstance(val, (str, unicode, int, long, bool, float))
20 return simple_type or val is None
21
22
23def all_nums(vals):
24 return all(isinstance(val, (int, float, long)) for val in vals)
25
26
27def dumpv(data, tab_sz=4, width=120, min_width=40):
28 tab = ' ' * tab_sz
29
30 if width < min_width:
31 width = min_width
32
33 res = []
34 if is_simple(data):
35 return [dumps_simple(data)]
36
37 if isinstance(data, (list, tuple)):
38 if all(map(is_simple, data)):
39 if all_nums(data):
40 one_line = "[{}]".format(", ".join(map(dumps_simple, data)))
41 else:
42 one_line = "[{}]".format(",".join(map(dumps_simple, data)))
43 else:
44 one_line = None
45
46 if one_line is None or len(one_line) > width:
47 pref = "-" + ' ' * (tab_sz - 1)
48
49 for val in data:
50 items = dumpv(val, tab_sz, width - tab_sz, min_width)
51 items = [pref + items[0]] + \
52 [tab + item for item in items[1:]]
53 res.extend(items)
54 else:
55 res.append(one_line)
56 elif isinstance(data, dict):
57 assert all(map(is_simple, data.keys()))
58
59 for k, v in data.items():
60 key_str = dumps_simple(k) + ": "
61 val_res = dumpv(v, tab_sz, width - tab_sz, min_width)
62
63 if len(val_res) == 1 and len(key_str + val_res[0]) < width:
64 res.append(key_str + val_res[0])
65 else:
66 res.append(key_str)
67 res.extend(tab + i for i in val_res)
68 else:
69 raise ValueError("Can't pack {0!r}".format(data))
70
71 return res
72
73
74def dumps(data, tab_sz=4, width=120, min_width=40):
75 return "\n".join(dumpv(data, tab_sz, width, min_width))