comparison lib/python3.8/site-packages/pip/_vendor/pytoml/writer.py @ 0:9e54283cc701 draft

"planemo upload commit d12c32a45bcd441307e632fca6d9af7d60289d44"
author guerler
date Mon, 27 Jul 2020 03:47:31 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:9e54283cc701
1 from __future__ import unicode_literals
2 import io, datetime, math, string, sys
3
4 from .utils import format_rfc3339
5
6 try:
7 from pathlib import PurePath as _path_types
8 except ImportError:
9 _path_types = ()
10
11
12 if sys.version_info[0] == 3:
13 long = int
14 unicode = str
15
16
17 def dumps(obj, sort_keys=False):
18 fout = io.StringIO()
19 dump(obj, fout, sort_keys=sort_keys)
20 return fout.getvalue()
21
22
23 _escapes = {'\n': 'n', '\r': 'r', '\\': '\\', '\t': 't', '\b': 'b', '\f': 'f', '"': '"'}
24
25
26 def _escape_string(s):
27 res = []
28 start = 0
29
30 def flush():
31 if start != i:
32 res.append(s[start:i])
33 return i + 1
34
35 i = 0
36 while i < len(s):
37 c = s[i]
38 if c in '"\\\n\r\t\b\f':
39 start = flush()
40 res.append('\\' + _escapes[c])
41 elif ord(c) < 0x20:
42 start = flush()
43 res.append('\\u%04x' % ord(c))
44 i += 1
45
46 flush()
47 return '"' + ''.join(res) + '"'
48
49
50 _key_chars = string.digits + string.ascii_letters + '-_'
51 def _escape_id(s):
52 if any(c not in _key_chars for c in s):
53 return _escape_string(s)
54 return s
55
56
57 def _format_value(v):
58 if isinstance(v, bool):
59 return 'true' if v else 'false'
60 if isinstance(v, int) or isinstance(v, long):
61 return unicode(v)
62 if isinstance(v, float):
63 if math.isnan(v) or math.isinf(v):
64 raise ValueError("{0} is not a valid TOML value".format(v))
65 else:
66 return repr(v)
67 elif isinstance(v, unicode) or isinstance(v, bytes):
68 return _escape_string(v)
69 elif isinstance(v, datetime.datetime):
70 return format_rfc3339(v)
71 elif isinstance(v, list):
72 return '[{0}]'.format(', '.join(_format_value(obj) for obj in v))
73 elif isinstance(v, dict):
74 return '{{{0}}}'.format(', '.join('{} = {}'.format(_escape_id(k), _format_value(obj)) for k, obj in v.items()))
75 elif isinstance(v, _path_types):
76 return _escape_string(str(v))
77 else:
78 raise RuntimeError(v)
79
80
81 def dump(obj, fout, sort_keys=False):
82 tables = [((), obj, False)]
83
84 while tables:
85 name, table, is_array = tables.pop()
86 if name:
87 section_name = '.'.join(_escape_id(c) for c in name)
88 if is_array:
89 fout.write('[[{0}]]\n'.format(section_name))
90 else:
91 fout.write('[{0}]\n'.format(section_name))
92
93 table_keys = sorted(table.keys()) if sort_keys else table.keys()
94 new_tables = []
95 has_kv = False
96 for k in table_keys:
97 v = table[k]
98 if isinstance(v, dict):
99 new_tables.append((name + (k,), v, False))
100 elif isinstance(v, list) and v and all(isinstance(o, dict) for o in v):
101 new_tables.extend((name + (k,), d, True) for d in v)
102 elif v is None:
103 # based on mojombo's comment: https://github.com/toml-lang/toml/issues/146#issuecomment-25019344
104 fout.write(
105 '#{} = null # To use: uncomment and replace null with value\n'.format(_escape_id(k)))
106 has_kv = True
107 else:
108 fout.write('{0} = {1}\n'.format(_escape_id(k), _format_value(v)))
109 has_kv = True
110
111 tables.extend(reversed(new_tables))
112
113 if (name or has_kv) and tables:
114 fout.write('\n')