summaryrefslogtreecommitdiff
path: root/chromium/third_party/pyjson5/src/json5
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/third_party/pyjson5/src/json5
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-chromium-85-based.tar.gz
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/pyjson5/src/json5')
-rw-r--r--chromium/third_party/pyjson5/src/json5/__init__.py2
-rw-r--r--chromium/third_party/pyjson5/src/json5/arg_parser.py7
-rw-r--r--chromium/third_party/pyjson5/src/json5/host.py12
-rw-r--r--chromium/third_party/pyjson5/src/json5/json5.g2
-rw-r--r--chromium/third_party/pyjson5/src/json5/lib.py450
-rw-r--r--chromium/third_party/pyjson5/src/json5/parser.py111
-rw-r--r--chromium/third_party/pyjson5/src/json5/tool.py70
-rw-r--r--chromium/third_party/pyjson5/src/json5/version.py2
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'