diff options
Diffstat (limited to 'chromium/third_party/pyjson5/src/json5')
-rw-r--r-- | chromium/third_party/pyjson5/src/json5/__init__.py | 2 | ||||
-rw-r--r-- | chromium/third_party/pyjson5/src/json5/arg_parser.py | 7 | ||||
-rw-r--r-- | chromium/third_party/pyjson5/src/json5/host.py | 12 | ||||
-rw-r--r-- | chromium/third_party/pyjson5/src/json5/json5.g | 2 | ||||
-rw-r--r-- | chromium/third_party/pyjson5/src/json5/lib.py | 450 | ||||
-rw-r--r-- | chromium/third_party/pyjson5/src/json5/parser.py | 111 | ||||
-rw-r--r-- | chromium/third_party/pyjson5/src/json5/tool.py | 70 | ||||
-rw-r--r-- | chromium/third_party/pyjson5/src/json5/version.py | 2 |
8 files changed, 522 insertions, 134 deletions
diff --git a/chromium/third_party/pyjson5/src/json5/__init__.py b/chromium/third_party/pyjson5/src/json5/__init__.py index 0e8f774dbc8..5af52fc943f 100644 --- a/chromium/third_party/pyjson5/src/json5/__init__.py +++ b/chromium/third_party/pyjson5/src/json5/__init__.py @@ -14,7 +14,6 @@ """A pure Python implementation of the JSON5 configuration language.""" -from . import tool from .lib import load, loads, dump, dumps from .version import VERSION @@ -25,5 +24,4 @@ __all__ = [ 'dumps', 'load', 'loads', - 'tool', ] diff --git a/chromium/third_party/pyjson5/src/json5/arg_parser.py b/chromium/third_party/pyjson5/src/json5/arg_parser.py index 3f45428d044..5853f49394f 100644 --- a/chromium/third_party/pyjson5/src/json5/arg_parser.py +++ b/chromium/third_party/pyjson5/src/json5/arg_parser.py @@ -22,12 +22,15 @@ class _Bailout(Exception): class ArgumentParser(argparse.ArgumentParser): SUPPRESS = argparse.SUPPRESS - def __init__(self, host, **kwargs): + def __init__(self, host, prog, desc, **kwargs): + kwargs['prog'] = prog + kwargs['description'] = desc + kwargs['formatter_class'] = argparse.RawDescriptionHelpFormatter super(ArgumentParser, self).__init__(**kwargs) self._host = host self.exit_status = None self.add_argument('-V', '--version', action='store_true', - help='Print the version and exit.') + help='print the version and exit') def parse_args(self, args=None, namespace=None): try: diff --git a/chromium/third_party/pyjson5/src/json5/host.py b/chromium/third_party/pyjson5/src/json5/host.py index b9935319e36..a347fd5831b 100644 --- a/chromium/third_party/pyjson5/src/json5/host.py +++ b/chromium/third_party/pyjson5/src/json5/host.py @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import fileinput import os import shutil import sys @@ -20,7 +19,7 @@ import tempfile if sys.version_info[0] < 3: - # pylint: disable=redefined-builtin + # pylint: disable=redefined-builtin, invalid-name str = unicode @@ -33,11 +32,6 @@ class Host(object): def chdir(self, *comps): return os.chdir(self.join(*comps)) - def fileinput(self, files=None): - if not files: - return self.stdin.readlines() - return fileinput.input(files) - def getcwd(self): return os.getcwd() @@ -55,6 +49,10 @@ class Host(object): def rmtree(self, path): shutil.rmtree(path, ignore_errors=True) + def read_text_file(self, path): + with open(path, 'rb') as fp: + return fp.read().decode('utf8') + def write_text_file(self, path, contents): with open(path, 'wb') as f: f.write(contents.encode('utf8')) diff --git a/chromium/third_party/pyjson5/src/json5/json5.g b/chromium/third_party/pyjson5/src/json5/json5.g index e4ed3652bb2..1bbb7980d70 100644 --- a/chromium/third_party/pyjson5/src/json5/json5.g +++ b/chromium/third_party/pyjson5/src/json5/json5.g @@ -52,6 +52,8 @@ esc_char = 'b' -> '\u0008' | squote -> '\u0027' | dquote -> '\u0022' | bslash -> '\u005C' + | ~('x'|'u'|digit|eol) anything:c -> c + | '0' ~digit -> '\u0000' | hex_esc:c -> c | unicode_esc:c -> c diff --git a/chromium/third_party/pyjson5/src/json5/lib.py b/chromium/third_party/pyjson5/src/json5/lib.py index 4252dc6a84c..5b2b0ae2620 100644 --- a/chromium/third_party/pyjson5/src/json5/lib.py +++ b/chromium/third_party/pyjson5/src/json5/lib.py @@ -12,34 +12,55 @@ # See the License for the specific language governing permissions and # limitations under the License. +import math import re -import json import sys +import unicodedata from .parser import Parser if sys.version_info[0] < 3: - # pylint: disable=redefined-builtin - str = unicode + str = unicode # pylint: disable=redefined-builtin, invalid-name +else: + long = int # pylint: disable=redefined-builtin, invalid-name def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None, - parse_int=None, parse_constant=None, object_pairs_hook=None): + parse_int=None, parse_constant=None, object_pairs_hook=None, + allow_duplicate_keys=True): """Deserialize ``fp`` (a ``.read()``-supporting file-like object - containing a JSON document) to a Python object.""" + containing a JSON document) to a Python object. + + Supports almost the same arguments as ``json.load()`` except that: + - the `cls` keyword is ignored. + - an extra `allow_duplicate_keys` parameter supports checking for + duplicate keys in a object; by default, this is True for + compatibility with ``json.load()``, but if set to False and + the object contains duplicate keys, a ValueError will be raised. + """ s = fp.read() return loads(s, encoding=encoding, cls=cls, object_hook=object_hook, parse_float=parse_float, parse_int=parse_int, parse_constant=parse_constant, - object_pairs_hook=object_pairs_hook) + object_pairs_hook=object_pairs_hook, + allow_duplicate_keys=allow_duplicate_keys) def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, - parse_int=None, parse_constant=None, object_pairs_hook=None): + parse_int=None, parse_constant=None, object_pairs_hook=None, + allow_duplicate_keys=True): """Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a - JSON5 document) to a Python object.""" + JSON5 document) to a Python object. + + Supports the same arguments as ``json.load()`` except that: + - the `cls` keyword is ignored. + - an extra `allow_duplicate_keys` parameter supports checking for + duplicate keys in a object; by default, this is True for + compatibility with ``json.load()``, but if set to False and + the object contains duplicate keys, a ValueError will be raised. + """ assert cls is None, 'Custom decoders are not supported' @@ -54,7 +75,7 @@ def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, if not s: raise ValueError('Empty strings are not legal JSON5') parser = Parser(s, '<string>') - ast, err, newpos = parser.parse() + ast, err, _ = parser.parse() if err: raise ValueError(err) @@ -66,7 +87,11 @@ def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, elif object_hook: dictify = lambda pairs: object_hook(dict(pairs)) else: - dictify = dict + dictify = lambda pairs: dict(pairs) # pylint: disable=unnecessary-lambda + + if not allow_duplicate_keys: + _orig_dictify = dictify + dictify = lambda pairs: _reject_duplicate_keys(pairs, _orig_dictify) parse_float = parse_float or float parse_int = parse_int or int @@ -75,6 +100,14 @@ def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, return _walk_ast(ast, dictify, parse_float, parse_int, parse_constant) +def _reject_duplicate_keys(pairs, dictify): + keys = set() + for key, _ in pairs: + if key in keys: + raise ValueError('Duplicate key "%s" found in object', key) + keys.add(key) + return dictify(pairs) + def _walk_ast(el, dictify, parse_float, parse_int, parse_constant): if el == 'None': return None @@ -107,53 +140,370 @@ def _walk_ast(el, dictify, parse_float, parse_int, parse_constant): raise Exception('unknown el: ' + el) # pragma: no cover -_notletter = re.compile('\W') +def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True, + allow_nan=True, cls=None, indent=None, separators=None, + default=None, sort_keys=False, + quote_keys=False, trailing_commas=True, + allow_duplicate_keys=True, + **kwargs): + """Serialize ``obj`` to a JSON5-formatted stream to ``fp`` (a ``.write()``- + supporting file-like object). + + Supports the same arguments as ``json.dumps()``, except that: + + - The ``cls`` keyword is not supported. + - The ``encoding`` keyword is ignored; Unicode strings are always written. + - By default, object keys that are legal identifiers are not quoted; + if you pass quote_keys=True, they will be. + - By default, if lists and objects span multiple lines of output (i.e., + when ``indent`` >=0), the last item will have a trailing comma + after it. If you pass ``trailing_commas=False, it will not. + - If you use a number, a boolean, or None as a key value in a dict, + it will be converted to the corresponding json string value, e.g. + "1", "true", or "null". By default, dump() will match the `json` + modules behavior and produce ill-formed JSON if you mix keys of + different types that have the same converted value, e.g.: + {1: "foo", "1": "bar"} produces '{"1": "foo", "1": "bar"}', an + object with duplicated keys. If you pass allow_duplicate_keys=False, + an exception will be raised instead. + + Calling ``dumps(obj, fp, quote_keys=True, trailing_commas=False, + allow_duplicate_keys=True)`` + should produce exactly the same output as ``json.dumps(obj, fp).`` + """ + + fp.write(str(dumps(obj=obj, skipkeys=skipkeys, ensure_ascii=ensure_ascii, + check_circular=check_circular, allow_nan=allow_nan, + cls=cls, indent=indent, separators=separators, + default=default, sort_keys=sort_keys, + quote_keys=quote_keys, trailing_commas=trailing_commas, + allow_duplicate_keys=allow_duplicate_keys))) + + +def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, + allow_nan=True, cls=None, indent=None, separators=None, + default=None, sort_keys=False, + quote_keys=False, trailing_commas=True, allow_duplicate_keys=True, + **kwargs): + """Serialize ``obj`` to a JSON5-formatted ``str``. + + Supports the same arguments as ``json.dumps()``, except that: + + - The ``cls`` keyword is not supported. + - The ``encoding`` keyword is ignored; Unicode strings are always returned. + - By default, object keys that are legal identifiers are not quoted; + if you pass quote_keys=True, they will be. + - By default, if lists and objects span multiple lines of output (i.e., + when ``indent`` >=0), the last item will have a trailing comma + after it. If you pass ``trailing_commas=False, it will not. + - If you use a number, a boolean, or None as a key value in a dict, + it will be converted to the corresponding json string value, e.g. + "1", "true", or "null". By default, dump() will match the ``json`` + module's behavior and produce ill-formed JSON if you mix keys of + different types that have the same converted value, e.g.: + {1: "foo", "1": "bar"} produces '{"1": "foo", "1": "bar"}', an + object with duplicated keys. If you pass ``allow_duplicate_keys=False``, + an exception will be raised instead. + + Calling ``dumps(obj, quote_keys=True, trailing_commas=False, + allow_duplicate_keys=True)`` + should produce exactly the same output as ``json.dumps(obj).`` + """ -def _dumpkey(k): - if _notletter.search(k): - return json.dumps(k) + assert kwargs.get('cls', None) is None, 'Custom encoders are not supported' + + if separators is None: + if indent is None: + separators = (u', ', u': ') + else: + separators = (u',', u': ') + + default = default or _raise_type_error + + if check_circular: + seen = set() else: - return str(k) + seen = None + level = 1 + is_key = False -def dumps(obj, compact=False, as_json=False, **kwargs): - """Serialize ``obj`` to a JSON5-formatted ``str``.""" + _, v = _dumps(obj, skipkeys, ensure_ascii, check_circular, + allow_nan, indent, separators, default, sort_keys, + quote_keys, trailing_commas, allow_duplicate_keys, + seen, level, is_key) + return v - if as_json or not compact: - return json.dumps(obj, **kwargs) + +def _dumps(obj, skipkeys, ensure_ascii, check_circular, allow_nan, indent, + separators, default, sort_keys, + quote_keys, trailing_commas, allow_duplicate_keys, + seen, level, is_key): + s = None + if obj is True: + s = u'true' + if obj is False: + s = u'false' + if obj is None: + s = u'null' t = type(obj) - if obj == True: - return u'true' - elif obj == False: - return u'false' - elif obj == None: - return u'null' - elif t == type('') or t == type(u''): - single = "'" in obj - double = '"' in obj - if single and double: - return json.dumps(obj) - elif single: - return '"' + obj + '"' + if t == type('') or t == type(u''): + if (is_key and _is_ident(obj) and not quote_keys + and not _is_reserved_word(obj)): + return True, obj + return True, _dump_str(obj, ensure_ascii) + if t is float: + s = _dump_float(obj,allow_nan) + if t is int: + s = str(obj) + + if is_key: + if s is not None: + return True, '"%s"' % s + if skipkeys: + return False, None + raise TypeError('invalid key %s' % repr(obj)) + + if s is not None: + return True, s + + if indent is not None: + end_str = '' + if trailing_commas: + end_str = ',' + if type(indent) == int: + if indent > 0: + indent_str = '\n' + ' ' * indent * level + end_str += '\n' + ' ' * indent * (level - 1) + else: + indent_str = '\n' + end_str += '\n' else: - return "'" + obj + "'" - elif t is float or t is int: - return str(obj) - elif t is dict: - return u'{' + u','.join([ - _dumpkey(k) + u':' + dumps(v) for k, v in obj.items() - ]) + '}' - elif t is list: - return u'[' + ','.join([dumps(el) for el in obj]) + u']' - else: # pragma: no cover - return u'' - - -def dump(obj, fp, **kwargs): - """Serialize ``obj`` to a JSON5-formatted stream to ``fp`` (a ``.write()``- - supporting file-like object).""" + indent_str = '\n' + indent * level + end_str += '\n' + indent * (level - 1) + else: + indent_str = '' + end_str = '' + + item_sep, kv_sep = separators + item_sep += indent_str + level += 1 + + if seen is not None: + i = id(obj) + if i in seen: + raise ValueError('Circular reference detected.') + else: + seen.add(i) + + # In Python3, we'd check if this was an abc.Mapping or an abc.Sequence. + # For now, just check for the attrs we need to iterate over the object. + if hasattr(t, 'keys') and hasattr(t, '__getitem__'): + s = _dump_dict(obj, skipkeys, ensure_ascii, + check_circular, allow_nan, indent, + separators, default, sort_keys, + quote_keys, trailing_commas, + allow_duplicate_keys, seen, level, + item_sep, kv_sep, indent_str, end_str) + elif hasattr(t, '__getitem__') and hasattr(t, '__iter__'): + s = _dump_array(obj, skipkeys, ensure_ascii, + check_circular, allow_nan, indent, + separators, default, sort_keys, + quote_keys, trailing_commas, + allow_duplicate_keys, seen, level, + item_sep, indent_str, end_str) + else: + s = default(obj) + + if seen is not None: + seen.remove(i) + return False, s + + +def _dump_dict(obj, skipkeys, ensure_ascii, check_circular, allow_nan, + indent, separators, default, sort_keys, + quote_keys, trailing_commas, allow_duplicate_keys, + seen, level, item_sep, kv_sep, indent_str, end_str): + if not obj: + return u'{}' + + if sort_keys: + keys = sorted(obj.keys()) + else: + keys = obj.keys() + + s = u'{' + indent_str + + num_items_added = 0 + new_keys = set() + for key in keys: + valid_key, key_str = _dumps(key, skipkeys, ensure_ascii, check_circular, + allow_nan, indent, separators, default, + sort_keys, + quote_keys, trailing_commas, + allow_duplicate_keys, + seen, level, is_key=True) + if valid_key: + if not allow_duplicate_keys: + if key_str in new_keys: + raise ValueError('duplicate key %s' % repr(key)) + else: + new_keys.add(key_str) + if num_items_added: + s += item_sep + s += key_str + kv_sep + _dumps(obj[key], skipkeys, ensure_ascii, + check_circular, allow_nan, indent, + separators, default, sort_keys, + quote_keys, trailing_commas, + allow_duplicate_keys, + seen, level, is_key=False)[1] + num_items_added += 1 + elif not skipkeys: + raise TypeError('invalid key %s' % repr(key)) + + s += end_str + u'}' + return s + + +def _dump_array(obj, skipkeys, ensure_ascii, check_circular, allow_nan, + indent, separators, default, sort_keys, + quote_keys, trailing_commas, allow_duplicate_keys, + seen, level, item_sep, indent_str, end_str): + if not obj: + return u'[]' + return (u'[' + indent_str + + item_sep.join([_dumps(el, skipkeys, ensure_ascii, check_circular, + allow_nan, indent, separators, default, + sort_keys, quote_keys, trailing_commas, + allow_duplicate_keys, + seen, level, False)[1] for el in obj]) + + end_str + u']') + + +def _dump_float(obj, allow_nan): + if allow_nan: + if math.isnan(obj): + return 'NaN' + if obj == float('inf'): + return 'Infinity' + if obj == float('-inf'): + return '-Infinity' + elif math.isnan(obj) or obj == float('inf') or obj == float('-inf'): + raise ValueError('Out of range float values ' + 'are not JSON compliant') + return str(obj) + + +def _dump_str(obj, ensure_ascii): + ret = ['"'] + for ch in obj: + if ch == '\\': + ret.append('\\\\') + elif ch == '"': + ret.append('\\"') + elif ch == u'\u2028': + ret.append('\\u2028') + elif ch == u'\u2029': + ret.append('\\u2029') + elif ch == '\n': + ret.append('\\n') + elif ch == '\r': + ret.append('\\r') + elif ch == '\b': + ret.append('\\b') + elif ch == '\f': + ret.append('\\f') + elif ch == '\t': + ret.append('\\t') + elif ch == '\v': + ret.append('\\v') + elif ch == '\0': + ret.append('\\0') + elif not ensure_ascii: + ret.append(ch) + else: + o = ord(ch) + if o >= 32 and o < 128: + ret.append(ch) + elif o < 65536: + ret.append('\\u' + '%04x' % o) + else: + val = o - 0x10000 + high = 0xd800 + (val >> 10) + low = 0xdc00 + (val & 0x3ff) + ret.append('\\u%04x\\u%04x' % (high, low)) + return u''.join(ret) + '"' + + +def _is_ident(k): + k = str(k) + if not k or not _is_id_start(k[0]) and k[0] not in (u'$', u'_'): + return False + for ch in k[1:]: + if not _is_id_continue(ch) and ch not in (u'$', u'_'): + return False + return True + + +def _is_id_start(ch): + return unicodedata.category(ch) in ( + 'Lu', 'Ll', 'Li', 'Lt', 'Lm', 'Lo', 'Nl') + + +def _is_id_continue(ch): + return unicodedata.category(ch) in ( + 'Lu', 'Ll', 'Li', 'Lt', 'Lm', 'Lo', 'Nl', 'Nd', 'Mn', 'Mc', 'Pc') + + +_reserved_word_re = None + +def _is_reserved_word(k): + global _reserved_word_re + + if _reserved_word_re is None: + # List taken from section 7.6.1 of ECMA-262. + _reserved_word_re = re.compile('(' + '|'.join([ + 'break', + 'case', + 'catch', + 'class', + 'const', + 'continue', + 'debugger', + 'default', + 'delete', + 'do', + 'else', + 'enum', + 'export', + 'extends', + 'false', + 'finally', + 'for', + 'function', + 'if', + 'import', + 'in', + 'instanceof', + 'new', + 'null', + 'return', + 'super', + 'switch', + 'this', + 'throw', + 'true', + 'try', + 'typeof', + 'var', + 'void', + 'while', + 'with', + ]) + ')$') + return _reserved_word_re.match(k) is not None + - s = dumps(obj, **kwargs) - fp.write(str(s)) +def _raise_type_error(obj): + raise TypeError('%s is not JSON5 serializable' % repr(obj)) diff --git a/chromium/third_party/pyjson5/src/json5/parser.py b/chromium/third_party/pyjson5/src/json5/parser.py index db1bd701e4a..a2a0039c4bf 100644 --- a/chromium/third_party/pyjson5/src/json5/parser.py +++ b/chromium/third_party/pyjson5/src/json5/parser.py @@ -1,10 +1,10 @@ -# pylint: disable=line-too-long +# pylint: disable=line-too-long,unnecessary-lambda import sys if sys.version_info[0] < 3: - # pylint: disable=redefined-builtin + # pylint: disable=redefined-builtin,invalid-name chr = unichr range = xrange str = unicode @@ -100,6 +100,8 @@ class Parser(object): rule() if self.failed: self._rewind(p) + if p < self.errpos: + self.errpos = p break else: vs.append(self.val) @@ -127,12 +129,12 @@ class Parser(object): else: self._fail() - def _str(self, s, l): - p = self.pos - if (p + l <= self.end) and self.msg[p:p + l] == s: - self._succeed(s, self.pos + l) - else: - self._fail() + def _str(self, s): + for ch in s: + self._ch(ch) + if self.failed: + return + self.val = s def _range(self, i, j): p = self.pos @@ -191,7 +193,7 @@ class Parser(object): self._ch('\f') def _ws__c6_(self): - self._ch('\u00a0') + self._ch(u'\xa0') def _ws__c7_(self): self._ch(u'\ufeff') @@ -232,21 +234,21 @@ class Parser(object): self._choose([self._comment__c0_, self._comment__c1_]) def _comment__c0_(self): - self._seq([lambda: self._str('//', 2), + self._seq([lambda: self._str('//'), lambda: self._star(self._comment__c0__s1_p_)]) def _comment__c0__s1_p_(self): self._seq([lambda: self._not(self._eol_), self._anything_]) def _comment__c1_(self): - self._seq([lambda: self._str('/*', 2), self._comment__c1__s1_, - lambda: self._str('*/', 2)]) + self._seq([lambda: self._str('/*'), self._comment__c1__s1_, + lambda: self._str('*/')]) def _comment__c1__s1_(self): self._star(lambda: self._seq([self._comment__c1__s1_p__s0_, self._anything_])) def _comment__c1__s1_p__s0_(self): - self._not(lambda: self._str('*/', 2)) + self._not(lambda: self._str('*/')) def _value_(self): self._choose([self._value__c0_, self._value__c1_, self._value__c2_, @@ -254,14 +256,13 @@ class Parser(object): self._value__c6_]) def _value__c0_(self): - self._seq([lambda: self._str('null', 4), lambda: self._succeed('None')]) + self._seq([lambda: self._str('null'), lambda: self._succeed('None')]) def _value__c1_(self): - self._seq([lambda: self._str('true', 4), lambda: self._succeed('True')]) + self._seq([lambda: self._str('true'), lambda: self._succeed('True')]) def _value__c2_(self): - self._seq([lambda: self._str('false', 5), - lambda: self._succeed('False')]) + self._seq([lambda: self._str('false'), lambda: self._succeed('False')]) def _value__c3_(self): self._push('value__c3') @@ -393,7 +394,8 @@ class Parser(object): self._esc_char__c4_, self._esc_char__c5_, self._esc_char__c6_, self._esc_char__c7_, self._esc_char__c8_, self._esc_char__c9_, - self._esc_char__c10_]) + self._esc_char__c10_, self._esc_char__c11_, + self._esc_char__c12_]) def _esc_char__c0_(self): self._seq([lambda: self._ch('b'), lambda: self._succeed('\b')]) @@ -402,10 +404,20 @@ class Parser(object): self._seq([lambda: self._ch('f'), lambda: self._succeed('\f')]) def _esc_char__c10_(self): - self._push('esc_char__c10') + self._seq([lambda: self._ch('0'), lambda: self._not(self._digit_), + lambda: self._succeed('\x00')]) + + def _esc_char__c11_(self): + self._push('esc_char__c11') + self._seq([lambda: self._bind(self._hex_esc_, 'c'), + lambda: self._succeed(self._get('c'))]) + self._pop('esc_char__c11') + + def _esc_char__c12_(self): + self._push('esc_char__c12') self._seq([lambda: self._bind(self._unicode_esc_, 'c'), lambda: self._succeed(self._get('c'))]) - self._pop('esc_char__c10') + self._pop('esc_char__c12') def _esc_char__c2_(self): self._seq([lambda: self._ch('n'), lambda: self._succeed('\n')]) @@ -430,10 +442,26 @@ class Parser(object): def _esc_char__c9_(self): self._push('esc_char__c9') - self._seq([lambda: self._bind(self._hex_esc_, 'c'), + self._seq([self._esc_char__c9__s0_, + lambda: self._bind(self._anything_, 'c'), lambda: self._succeed(self._get('c'))]) self._pop('esc_char__c9') + def _esc_char__c9__s0_(self): + self._not(lambda: (self._esc_char__c9__s0_n_g_)()) + + def _esc_char__c9__s0_n_g_(self): + self._choose([self._esc_char__c9__s0_n_g__c0_, + self._esc_char__c9__s0_n_g__c1_, + lambda: self._seq([self._digit_]), + lambda: self._seq([self._eol_])]) + + def _esc_char__c9__s0_n_g__c0_(self): + self._seq([lambda: self._ch('x')]) + + def _esc_char__c9__s0_n_g__c1_(self): + self._seq([lambda: self._ch('u')]) + def _hex_esc_(self): self._push('hex_esc') self._seq([lambda: self._ch('x'), lambda: self._bind(self._hex_, 'h1'), @@ -501,22 +529,6 @@ class Parser(object): lambda: self._succeed([self._get('k'), self._get('v')])]) self._pop('member__c1') - def _member_list_(self): - self._push('member_list') - self._seq([lambda: self._bind(self._member_, 'm'), - self._member_list__s1_, self._sp_, self._member_list__s3_, - lambda: self._succeed([self._get('m')] + self._get('ms'))]) - self._pop('member_list') - - def _member_list__s1_(self): - self._bind(lambda: self._star(self._member_list__s1_l_p_), 'ms') - - def _member_list__s1_l_p_(self): - self._seq([self._sp_, lambda: self._ch(','), self._sp_, self._member_]) - - def _member_list__s3_(self): - self._opt(lambda: self._ch(',')) - def _ident_(self): self._push('ident') self._seq([lambda: self._bind(self._id_start_, 'hd'), self._ident__s1_, @@ -734,10 +746,10 @@ class Parser(object): self._opt(lambda: self._ch('+')) def _num_literal__c3_(self): - self._str('Infinity', 8) + self._str('Infinity') def _num_literal__c4_(self): - self._str('NaN', 3) + self._str('NaN') def _dec_literal_(self): self._choose([self._dec_literal__c0_, self._dec_literal__c1_, @@ -815,7 +827,7 @@ class Parser(object): self._pop('hex_literal') def _hex_literal__s0_(self): - self._choose([lambda: self._str('0x', 2), lambda: self._str('0X', 2)]) + self._choose([lambda: self._str('0x'), lambda: self._str('0X')]) def _hex_literal__s1_(self): self._bind(lambda: self._plus(self._hex_), 'hs') @@ -829,25 +841,6 @@ class Parser(object): def _hex__c1_(self): self._range('A', 'F') - def _hex_esc_(self): - self._push('hex_esc') - self._seq([lambda: self._ch('x'), lambda: self._bind(self._hex_, 'h1'), - lambda: self._bind(self._hex_, 'h2'), - lambda: self._succeed(self._xtou(self._get('h1') + self._get('h2')))]) - self._pop('hex_esc') - - def _hex_literal_(self): - self._push('hex_literal') - self._seq([self._hex_literal__s0_, self._hex_literal__s1_, - lambda: self._succeed('0x' + self._join('', self._get('hs')))]) - self._pop('hex_literal') - - def _hex_literal__s0_(self): - self._choose([lambda: self._str('0x', 2), lambda: self._str('0X', 2)]) - - def _hex_literal__s1_(self): - self._bind(lambda: self._plus(self._hex_), 'hs') - def _frac_(self): self._push('frac') self._seq([lambda: self._ch('.'), self._frac__s1_, diff --git a/chromium/third_party/pyjson5/src/json5/tool.py b/chromium/third_party/pyjson5/src/json5/tool.py index ed536582845..3c7d1209ac4 100644 --- a/chromium/third_party/pyjson5/src/json5/tool.py +++ b/chromium/third_party/pyjson5/src/json5/tool.py @@ -12,16 +12,20 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Command-line tool to validate and pretty-print JSON5. +"""A tool to parse and pretty-print JSON5. -Usage:: +Usage: $ echo '{foo:"bar"}' | python -m json5.tool - { foo: "bar" } - $ + { + foo: 'bar', + } + $ echo '{foo:"bar"}' | python -m json5.tool --as-json + { + "foo": "bar" + } """ -import os import sys from . import arg_parser @@ -33,14 +37,35 @@ from .version import VERSION def main(argv=None, host=None): host = host or Host() - parser = arg_parser.ArgumentParser(host, prog='json5') + parser = arg_parser.ArgumentParser(host, prog='json5', desc=__doc__) parser.add_argument('-c', metavar='STR', dest='cmd', - help='inline json5 string') - parser.add_argument('--json', dest='as_json', action='store_const', + help='inline json5 string to read instead of ' + 'reading from a file') + parser.add_argument('--as-json', dest='as_json', action='store_const', const=True, default=False, - help='output as json') - parser.add_argument('files', nargs='*', default=[], - help=parser.SUPPRESS) + help='output as JSON ' + '(same as --quote-keys --no-trailing-commas)') + parser.add_argument('--indent', dest='indent', default=4, + help='amount to indent each line ' + '(default is 4 spaces)') + parser.add_argument('--quote-keys', action='store_true', default=False, + help='quote all object keys') + parser.add_argument('--no-quote-keys', action='store_false', + dest='quote_keys', + help="don't quote object keys that are identifiers" + " (this is the default)") + parser.add_argument('--trailing-commas', action='store_true', + default=True, + help='add commas after the last item in multi-line ' + 'objects and arrays (this is the default)') + parser.add_argument('--no-trailing-commas', dest='trailing_commas', + action='store_false', + help='do not add commas after the last item in ' + 'multi-line lists and objects') + parser.add_argument('file', metavar='FILE', nargs='?', default='-', + help='optional file to read JSON5 document from; if ' + 'not specified or "-", will read from stdin ' + 'instead') args = parser.parse_args(argv) if parser.exit_status is not None: @@ -52,10 +77,29 @@ def main(argv=None, host=None): if args.cmd: inp = args.cmd + elif args.file == '-': + inp = host.stdin.read() else: - inp = ''.join(host.fileinput(args.files)) + inp = host.read_text_file(args.file) - host.print_(lib.dumps(lib.loads(inp), compact=True, as_json=args.as_json)) + if args.indent == 'None': + args.indent = None + else: + try: + args.indent = int(args.indent) + except ValueError: + pass + + if args.as_json: + args.quote_keys = True + args.trailing_commas = False + + obj = lib.loads(inp) + s = lib.dumps(obj, + indent=args.indent, + quote_keys=args.quote_keys, + trailing_commas=args.trailing_commas) + host.print_(s) return 0 diff --git a/chromium/third_party/pyjson5/src/json5/version.py b/chromium/third_party/pyjson5/src/json5/version.py index dce4f08881d..a0cc8a315c7 100644 --- a/chromium/third_party/pyjson5/src/json5/version.py +++ b/chromium/third_party/pyjson5/src/json5/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -VERSION = '0.6.1' +VERSION = '0.9.5' |