diff options
| author | Shubham Saini <shubham6405@gmail.com> | 2018-12-11 10:01:23 +0000 |
|---|---|---|
| committer | Shubham Saini <shubham6405@gmail.com> | 2018-12-11 10:01:23 +0000 |
| commit | 68df54d6629ec019142eb149dd037774f2d11e7c (patch) | |
| tree | 345bc22d46b4e01a4ba8303b94278952a4ed2b9e /venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml | |
First commit
Diffstat (limited to 'venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml')
4 files changed, 517 insertions, 0 deletions
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/__init__.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/__init__.py new file mode 100644 index 0000000..222a196 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/__init__.py | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | from .core import TomlError | ||
| 2 | from .parser import load, loads | ||
| 3 | from .writer import dump, dumps | ||
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/core.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/core.py new file mode 100644 index 0000000..0fcada4 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/core.py | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | class TomlError(RuntimeError): | ||
| 2 | def __init__(self, message, line, col, filename): | ||
| 3 | RuntimeError.__init__(self, message, line, col, filename) | ||
| 4 | self.message = message | ||
| 5 | self.line = line | ||
| 6 | self.col = col | ||
| 7 | self.filename = filename | ||
| 8 | |||
| 9 | def __str__(self): | ||
| 10 | return '{}({}, {}): {}'.format(self.filename, self.line, self.col, self.message) | ||
| 11 | |||
| 12 | def __repr__(self): | ||
| 13 | return 'TomlError({!r}, {!r}, {!r}, {!r})'.format(self.message, self.line, self.col, self.filename) | ||
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/parser.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/parser.py new file mode 100644 index 0000000..c416ed5 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/parser.py | |||
| @@ -0,0 +1,374 @@ | |||
| 1 | import string, re, sys, datetime | ||
| 2 | from .core import TomlError | ||
| 3 | |||
| 4 | if sys.version_info[0] == 2: | ||
| 5 | _chr = unichr | ||
| 6 | else: | ||
| 7 | _chr = chr | ||
| 8 | |||
| 9 | def load(fin, translate=lambda t, x, v: v): | ||
| 10 | return loads(fin.read(), translate=translate, filename=getattr(fin, 'name', repr(fin))) | ||
| 11 | |||
| 12 | def loads(s, filename='<string>', translate=lambda t, x, v: v): | ||
| 13 | if isinstance(s, bytes): | ||
| 14 | s = s.decode('utf-8') | ||
| 15 | |||
| 16 | s = s.replace('\r\n', '\n') | ||
| 17 | |||
| 18 | root = {} | ||
| 19 | tables = {} | ||
| 20 | scope = root | ||
| 21 | |||
| 22 | src = _Source(s, filename=filename) | ||
| 23 | ast = _p_toml(src) | ||
| 24 | |||
| 25 | def error(msg): | ||
| 26 | raise TomlError(msg, pos[0], pos[1], filename) | ||
| 27 | |||
| 28 | def process_value(v): | ||
| 29 | kind, text, value, pos = v | ||
| 30 | if kind == 'str' and value.startswith('\n'): | ||
| 31 | value = value[1:] | ||
| 32 | if kind == 'array': | ||
| 33 | if value and any(k != value[0][0] for k, t, v, p in value[1:]): | ||
| 34 | error('array-type-mismatch') | ||
| 35 | value = [process_value(item) for item in value] | ||
| 36 | elif kind == 'table': | ||
| 37 | value = dict([(k, process_value(value[k])) for k in value]) | ||
| 38 | return translate(kind, text, value) | ||
| 39 | |||
| 40 | for kind, value, pos in ast: | ||
| 41 | if kind == 'kv': | ||
| 42 | k, v = value | ||
| 43 | if k in scope: | ||
| 44 | error('duplicate_keys. Key "{0}" was used more than once.'.format(k)) | ||
| 45 | scope[k] = process_value(v) | ||
| 46 | else: | ||
| 47 | is_table_array = (kind == 'table_array') | ||
| 48 | cur = tables | ||
| 49 | for name in value[:-1]: | ||
| 50 | if isinstance(cur.get(name), list): | ||
| 51 | d, cur = cur[name][-1] | ||
| 52 | else: | ||
| 53 | d, cur = cur.setdefault(name, (None, {})) | ||
| 54 | |||
| 55 | scope = {} | ||
| 56 | name = value[-1] | ||
| 57 | if name not in cur: | ||
| 58 | if is_table_array: | ||
| 59 | cur[name] = [(scope, {})] | ||
| 60 | else: | ||
| 61 | cur[name] = (scope, {}) | ||
| 62 | elif isinstance(cur[name], list): | ||
| 63 | if not is_table_array: | ||
| 64 | error('table_type_mismatch') | ||
| 65 | cur[name].append((scope, {})) | ||
| 66 | else: | ||
| 67 | if is_table_array: | ||
| 68 | error('table_type_mismatch') | ||
| 69 | old_scope, next_table = cur[name] | ||
| 70 | if old_scope is not None: | ||
| 71 | error('duplicate_tables') | ||
| 72 | cur[name] = (scope, next_table) | ||
| 73 | |||
| 74 | def merge_tables(scope, tables): | ||
| 75 | if scope is None: | ||
| 76 | scope = {} | ||
| 77 | for k in tables: | ||
| 78 | if k in scope: | ||
| 79 | error('key_table_conflict') | ||
| 80 | v = tables[k] | ||
| 81 | if isinstance(v, list): | ||
| 82 | scope[k] = [merge_tables(sc, tbl) for sc, tbl in v] | ||
| 83 | else: | ||
| 84 | scope[k] = merge_tables(v[0], v[1]) | ||
| 85 | return scope | ||
| 86 | |||
| 87 | return merge_tables(root, tables) | ||
| 88 | |||
| 89 | class _Source: | ||
| 90 | def __init__(self, s, filename=None): | ||
| 91 | self.s = s | ||
| 92 | self._pos = (1, 1) | ||
| 93 | self._last = None | ||
| 94 | self._filename = filename | ||
| 95 | self.backtrack_stack = [] | ||
| 96 | |||
| 97 | def last(self): | ||
| 98 | return self._last | ||
| 99 | |||
| 100 | def pos(self): | ||
| 101 | return self._pos | ||
| 102 | |||
| 103 | def fail(self): | ||
| 104 | return self._expect(None) | ||
| 105 | |||
| 106 | def consume_dot(self): | ||
| 107 | if self.s: | ||
| 108 | self._last = self.s[0] | ||
| 109 | self.s = self[1:] | ||
| 110 | self._advance(self._last) | ||
| 111 | return self._last | ||
| 112 | return None | ||
| 113 | |||
| 114 | def expect_dot(self): | ||
| 115 | return self._expect(self.consume_dot()) | ||
| 116 | |||
| 117 | def consume_eof(self): | ||
| 118 | if not self.s: | ||
| 119 | self._last = '' | ||
| 120 | return True | ||
| 121 | return False | ||
| 122 | |||
| 123 | def expect_eof(self): | ||
| 124 | return self._expect(self.consume_eof()) | ||
| 125 | |||
| 126 | def consume(self, s): | ||
| 127 | if self.s.startswith(s): | ||
| 128 | self.s = self.s[len(s):] | ||
| 129 | self._last = s | ||
| 130 | self._advance(s) | ||
| 131 | return True | ||
| 132 | return False | ||
| 133 | |||
| 134 | def expect(self, s): | ||
| 135 | return self._expect(self.consume(s)) | ||
| 136 | |||
| 137 | def consume_re(self, re): | ||
| 138 | m = re.match(self.s) | ||
| 139 | if m: | ||
| 140 | self.s = self.s[len(m.group(0)):] | ||
| 141 | self._last = m | ||
| 142 | self._advance(m.group(0)) | ||
| 143 | return m | ||
| 144 | return None | ||
| 145 | |||
| 146 | def expect_re(self, re): | ||
| 147 | return self._expect(self.consume_re(re)) | ||
| 148 | |||
| 149 | def __enter__(self): | ||
| 150 | self.backtrack_stack.append((self.s, self._pos)) | ||
| 151 | |||
| 152 | def __exit__(self, type, value, traceback): | ||
| 153 | if type is None: | ||
| 154 | self.backtrack_stack.pop() | ||
| 155 | else: | ||
| 156 | self.s, self._pos = self.backtrack_stack.pop() | ||
| 157 | return type == TomlError | ||
| 158 | |||
| 159 | def commit(self): | ||
| 160 | self.backtrack_stack[-1] = (self.s, self._pos) | ||
| 161 | |||
| 162 | def _expect(self, r): | ||
| 163 | if not r: | ||
| 164 | raise TomlError('msg', self._pos[0], self._pos[1], self._filename) | ||
| 165 | return r | ||
| 166 | |||
| 167 | def _advance(self, s): | ||
| 168 | suffix_pos = s.rfind('\n') | ||
| 169 | if suffix_pos == -1: | ||
| 170 | self._pos = (self._pos[0], self._pos[1] + len(s)) | ||
| 171 | else: | ||
| 172 | self._pos = (self._pos[0] + s.count('\n'), len(s) - suffix_pos) | ||
| 173 | |||
| 174 | _ews_re = re.compile(r'(?:[ \t]|#[^\n]*\n|#[^\n]*\Z|\n)*') | ||
| 175 | def _p_ews(s): | ||
| 176 | s.expect_re(_ews_re) | ||
| 177 | |||
| 178 | _ws_re = re.compile(r'[ \t]*') | ||
| 179 | def _p_ws(s): | ||
| 180 | s.expect_re(_ws_re) | ||
| 181 | |||
| 182 | _escapes = { 'b': '\b', 'n': '\n', 'r': '\r', 't': '\t', '"': '"', '\'': '\'', | ||
| 183 | '\\': '\\', '/': '/', 'f': '\f' } | ||
| 184 | |||
| 185 | _basicstr_re = re.compile(r'[^"\\\000-\037]*') | ||
| 186 | _short_uni_re = re.compile(r'u([0-9a-fA-F]{4})') | ||
| 187 | _long_uni_re = re.compile(r'U([0-9a-fA-F]{8})') | ||
| 188 | _escapes_re = re.compile('[bnrt"\'\\\\/f]') | ||
| 189 | _newline_esc_re = re.compile('\n[ \t\n]*') | ||
| 190 | def _p_basicstr_content(s, content=_basicstr_re): | ||
| 191 | res = [] | ||
| 192 | while True: | ||
| 193 | res.append(s.expect_re(content).group(0)) | ||
| 194 | if not s.consume('\\'): | ||
| 195 | break | ||
| 196 | if s.consume_re(_newline_esc_re): | ||
| 197 | pass | ||
| 198 | elif s.consume_re(_short_uni_re) or s.consume_re(_long_uni_re): | ||
| 199 | res.append(_chr(int(s.last().group(1), 16))) | ||
| 200 | else: | ||
| 201 | s.expect_re(_escapes_re) | ||
| 202 | res.append(_escapes[s.last().group(0)]) | ||
| 203 | return ''.join(res) | ||
| 204 | |||
| 205 | _key_re = re.compile(r'[0-9a-zA-Z-_]+') | ||
| 206 | def _p_key(s): | ||
| 207 | with s: | ||
| 208 | s.expect('"') | ||
| 209 | r = _p_basicstr_content(s, _basicstr_re) | ||
| 210 | s.expect('"') | ||
| 211 | return r | ||
| 212 | if s.consume('\''): | ||
| 213 | if s.consume('\'\''): | ||
| 214 | r = s.expect_re(_litstr_ml_re).group(0) | ||
| 215 | s.expect('\'\'\'') | ||
| 216 | else: | ||
| 217 | r = s.expect_re(_litstr_re).group(0) | ||
| 218 | s.expect('\'') | ||
| 219 | return r | ||
| 220 | return s.expect_re(_key_re).group(0) | ||
| 221 | |||
| 222 | _float_re = re.compile(r'[+-]?(?:0|[1-9](?:_?\d)*)(?:\.\d(?:_?\d)*)?(?:[eE][+-]?(?:\d(?:_?\d)*))?') | ||
| 223 | _datetime_re = re.compile(r'(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.\d+)?(?:Z|([+-]\d{2}):(\d{2}))') | ||
| 224 | |||
| 225 | _basicstr_ml_re = re.compile(r'(?:(?:|"|"")[^"\\\000-\011\013-\037])*') | ||
| 226 | _litstr_re = re.compile(r"[^'\000-\037]*") | ||
| 227 | _litstr_ml_re = re.compile(r"(?:(?:|'|'')(?:[^'\000-\011\013-\037]))*") | ||
| 228 | def _p_value(s): | ||
| 229 | pos = s.pos() | ||
| 230 | |||
| 231 | if s.consume('true'): | ||
| 232 | return 'bool', s.last(), True, pos | ||
| 233 | if s.consume('false'): | ||
| 234 | return 'bool', s.last(), False, pos | ||
| 235 | |||
| 236 | if s.consume('"'): | ||
| 237 | if s.consume('""'): | ||
| 238 | r = _p_basicstr_content(s, _basicstr_ml_re) | ||
| 239 | s.expect('"""') | ||
| 240 | else: | ||
| 241 | r = _p_basicstr_content(s, _basicstr_re) | ||
| 242 | s.expect('"') | ||
| 243 | return 'str', r, r, pos | ||
| 244 | |||
| 245 | if s.consume('\''): | ||
| 246 | if s.consume('\'\''): | ||
| 247 | r = s.expect_re(_litstr_ml_re).group(0) | ||
| 248 | s.expect('\'\'\'') | ||
| 249 | else: | ||
| 250 | r = s.expect_re(_litstr_re).group(0) | ||
| 251 | s.expect('\'') | ||
| 252 | return 'str', r, r, pos | ||
| 253 | |||
| 254 | if s.consume_re(_datetime_re): | ||
| 255 | m = s.last() | ||
| 256 | s0 = m.group(0) | ||
| 257 | r = map(int, m.groups()[:6]) | ||
| 258 | if m.group(7): | ||
| 259 | micro = float(m.group(7)) | ||
| 260 | else: | ||
| 261 | micro = 0 | ||
| 262 | |||
| 263 | if m.group(8): | ||
| 264 | g = int(m.group(8), 10) * 60 + int(m.group(9), 10) | ||
| 265 | tz = _TimeZone(datetime.timedelta(0, g * 60)) | ||
| 266 | else: | ||
| 267 | tz = _TimeZone(datetime.timedelta(0, 0)) | ||
| 268 | |||
| 269 | y, m, d, H, M, S = r | ||
| 270 | dt = datetime.datetime(y, m, d, H, M, S, int(micro * 1000000), tz) | ||
| 271 | return 'datetime', s0, dt, pos | ||
| 272 | |||
| 273 | if s.consume_re(_float_re): | ||
| 274 | m = s.last().group(0) | ||
| 275 | r = m.replace('_','') | ||
| 276 | if '.' in m or 'e' in m or 'E' in m: | ||
| 277 | return 'float', m, float(r), pos | ||
| 278 | else: | ||
| 279 | return 'int', m, int(r, 10), pos | ||
| 280 | |||
| 281 | if s.consume('['): | ||
| 282 | items = [] | ||
| 283 | with s: | ||
| 284 | while True: | ||
| 285 | _p_ews(s) | ||
| 286 | items.append(_p_value(s)) | ||
| 287 | s.commit() | ||
| 288 | _p_ews(s) | ||
| 289 | s.expect(',') | ||
| 290 | s.commit() | ||
| 291 | _p_ews(s) | ||
| 292 | s.expect(']') | ||
| 293 | return 'array', None, items, pos | ||
| 294 | |||
| 295 | if s.consume('{'): | ||
| 296 | _p_ws(s) | ||
| 297 | items = {} | ||
| 298 | if not s.consume('}'): | ||
| 299 | k = _p_key(s) | ||
| 300 | _p_ws(s) | ||
| 301 | s.expect('=') | ||
| 302 | _p_ws(s) | ||
| 303 | items[k] = _p_value(s) | ||
| 304 | _p_ws(s) | ||
| 305 | while s.consume(','): | ||
| 306 | _p_ws(s) | ||
| 307 | k = _p_key(s) | ||
| 308 | _p_ws(s) | ||
| 309 | s.expect('=') | ||
| 310 | _p_ws(s) | ||
| 311 | items[k] = _p_value(s) | ||
| 312 | _p_ws(s) | ||
| 313 | s.expect('}') | ||
| 314 | return 'table', None, items, pos | ||
| 315 | |||
| 316 | s.fail() | ||
| 317 | |||
| 318 | def _p_stmt(s): | ||
| 319 | pos = s.pos() | ||
| 320 | if s.consume( '['): | ||
| 321 | is_array = s.consume('[') | ||
| 322 | _p_ws(s) | ||
| 323 | keys = [_p_key(s)] | ||
| 324 | _p_ws(s) | ||
| 325 | while s.consume('.'): | ||
| 326 | _p_ws(s) | ||
| 327 | keys.append(_p_key(s)) | ||
| 328 | _p_ws(s) | ||
| 329 | s.expect(']') | ||
| 330 | if is_array: | ||
| 331 | s.expect(']') | ||
| 332 | return 'table_array' if is_array else 'table', keys, pos | ||
| 333 | |||
| 334 | key = _p_key(s) | ||
| 335 | _p_ws(s) | ||
| 336 | s.expect('=') | ||
| 337 | _p_ws(s) | ||
| 338 | value = _p_value(s) | ||
| 339 | return 'kv', (key, value), pos | ||
| 340 | |||
| 341 | _stmtsep_re = re.compile(r'(?:[ \t]*(?:#[^\n]*)?\n)+[ \t]*') | ||
| 342 | def _p_toml(s): | ||
| 343 | stmts = [] | ||
| 344 | _p_ews(s) | ||
| 345 | with s: | ||
| 346 | stmts.append(_p_stmt(s)) | ||
| 347 | while True: | ||
| 348 | s.commit() | ||
| 349 | s.expect_re(_stmtsep_re) | ||
| 350 | stmts.append(_p_stmt(s)) | ||
| 351 | _p_ews(s) | ||
| 352 | s.expect_eof() | ||
| 353 | return stmts | ||
| 354 | |||
| 355 | class _TimeZone(datetime.tzinfo): | ||
| 356 | def __init__(self, offset): | ||
| 357 | self._offset = offset | ||
| 358 | |||
| 359 | def utcoffset(self, dt): | ||
| 360 | return self._offset | ||
| 361 | |||
| 362 | def dst(self, dt): | ||
| 363 | return None | ||
| 364 | |||
| 365 | def tzname(self, dt): | ||
| 366 | m = self._offset.total_seconds() // 60 | ||
| 367 | if m < 0: | ||
| 368 | res = '-' | ||
| 369 | m = -m | ||
| 370 | else: | ||
| 371 | res = '+' | ||
| 372 | h = m // 60 | ||
| 373 | m = m - h * 60 | ||
| 374 | return '{}{:.02}{:.02}'.format(res, h, m) | ||
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/writer.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/writer.py new file mode 100644 index 0000000..19a8c6e --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/writer.py | |||
| @@ -0,0 +1,127 @@ | |||
| 1 | from __future__ import unicode_literals | ||
| 2 | import io, datetime, math, sys | ||
| 3 | |||
| 4 | if sys.version_info[0] == 3: | ||
| 5 | long = int | ||
| 6 | unicode = str | ||
| 7 | |||
| 8 | |||
| 9 | def dumps(obj, sort_keys=False): | ||
| 10 | fout = io.StringIO() | ||
| 11 | dump(obj, fout, sort_keys=sort_keys) | ||
| 12 | return fout.getvalue() | ||
| 13 | |||
| 14 | |||
| 15 | _escapes = {'\n': 'n', '\r': 'r', '\\': '\\', '\t': 't', '\b': 'b', '\f': 'f', '"': '"'} | ||
| 16 | |||
| 17 | |||
| 18 | def _escape_string(s): | ||
| 19 | res = [] | ||
| 20 | start = 0 | ||
| 21 | |||
| 22 | def flush(): | ||
| 23 | if start != i: | ||
| 24 | res.append(s[start:i]) | ||
| 25 | return i + 1 | ||
| 26 | |||
| 27 | i = 0 | ||
| 28 | while i < len(s): | ||
| 29 | c = s[i] | ||
| 30 | if c in '"\\\n\r\t\b\f': | ||
| 31 | start = flush() | ||
| 32 | res.append('\\' + _escapes[c]) | ||
| 33 | elif ord(c) < 0x20: | ||
| 34 | start = flush() | ||
| 35 | res.append('\\u%04x' % ord(c)) | ||
| 36 | i += 1 | ||
| 37 | |||
| 38 | flush() | ||
| 39 | return '"' + ''.join(res) + '"' | ||
| 40 | |||
| 41 | |||
| 42 | def _escape_id(s): | ||
| 43 | if any(not c.isalnum() and c not in '-_' for c in s): | ||
| 44 | return _escape_string(s) | ||
| 45 | return s | ||
| 46 | |||
| 47 | |||
| 48 | def _format_list(v): | ||
| 49 | return '[{0}]'.format(', '.join(_format_value(obj) for obj in v)) | ||
| 50 | |||
| 51 | # Formula from: | ||
| 52 | # https://docs.python.org/2/library/datetime.html#datetime.timedelta.total_seconds | ||
| 53 | # Once support for py26 is dropped, this can be replaced by td.total_seconds() | ||
| 54 | def _total_seconds(td): | ||
| 55 | return ((td.microseconds | ||
| 56 | + (td.seconds + td.days * 24 * 3600) * 10**6) / 10.0**6) | ||
| 57 | |||
| 58 | def _format_value(v): | ||
| 59 | if isinstance(v, bool): | ||
| 60 | return 'true' if v else 'false' | ||
| 61 | if isinstance(v, int) or isinstance(v, long): | ||
| 62 | return unicode(v) | ||
| 63 | if isinstance(v, float): | ||
| 64 | if math.isnan(v) or math.isinf(v): | ||
| 65 | raise ValueError("{0} is not a valid TOML value".format(v)) | ||
| 66 | else: | ||
| 67 | return repr(v) | ||
| 68 | elif isinstance(v, unicode) or isinstance(v, bytes): | ||
| 69 | return _escape_string(v) | ||
| 70 | elif isinstance(v, datetime.datetime): | ||
| 71 | offs = v.utcoffset() | ||
| 72 | offs = _total_seconds(offs) // 60 if offs is not None else 0 | ||
| 73 | |||
| 74 | if offs == 0: | ||
| 75 | suffix = 'Z' | ||
| 76 | else: | ||
| 77 | if offs > 0: | ||
| 78 | suffix = '+' | ||
| 79 | else: | ||
| 80 | suffix = '-' | ||
| 81 | offs = -offs | ||
| 82 | suffix = '{0}{1:.02}{2:.02}'.format(suffix, offs // 60, offs % 60) | ||
| 83 | |||
| 84 | if v.microsecond: | ||
| 85 | return v.strftime('%Y-%m-%dT%H:%M:%S.%f') + suffix | ||
| 86 | else: | ||
| 87 | return v.strftime('%Y-%m-%dT%H:%M:%S') + suffix | ||
| 88 | elif isinstance(v, list): | ||
| 89 | return _format_list(v) | ||
| 90 | else: | ||
| 91 | raise RuntimeError(v) | ||
| 92 | |||
| 93 | |||
| 94 | def dump(obj, fout, sort_keys=False): | ||
| 95 | tables = [((), obj, False)] | ||
| 96 | |||
| 97 | while tables: | ||
| 98 | name, table, is_array = tables.pop() | ||
| 99 | if name: | ||
| 100 | section_name = '.'.join(_escape_id(c) for c in name) | ||
| 101 | if is_array: | ||
| 102 | fout.write('[[{0}]]\n'.format(section_name)) | ||
| 103 | else: | ||
| 104 | fout.write('[{0}]\n'.format(section_name)) | ||
| 105 | |||
| 106 | table_keys = sorted(table.keys()) if sort_keys else table.keys() | ||
| 107 | new_tables = [] | ||
| 108 | has_kv = False | ||
| 109 | for k in table_keys: | ||
| 110 | v = table[k] | ||
| 111 | if isinstance(v, dict): | ||
| 112 | new_tables.append((name + (k,), v, False)) | ||
| 113 | elif isinstance(v, list) and v and all(isinstance(o, dict) for o in v): | ||
| 114 | new_tables.extend((name + (k,), d, True) for d in v) | ||
| 115 | elif v is None: | ||
| 116 | # based on mojombo's comment: https://github.com/toml-lang/toml/issues/146#issuecomment-25019344 | ||
| 117 | fout.write( | ||
| 118 | '#{} = null # To use: uncomment and replace null with value\n'.format(_escape_id(k))) | ||
| 119 | has_kv = True | ||
| 120 | else: | ||
| 121 | fout.write('{0} = {1}\n'.format(_escape_id(k), _format_value(v))) | ||
| 122 | has_kv = True | ||
| 123 | |||
| 124 | tables.extend(reversed(new_tables)) | ||
| 125 | |||
| 126 | if (name or has_kv) and tables: | ||
| 127 | fout.write('\n') | ||
