summaryrefslogtreecommitdiff
path: root/chromium/third_party/pyjson5
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
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')
-rw-r--r--chromium/third_party/pyjson5/OWNERS1
-rw-r--r--chromium/third_party/pyjson5/README.chromium6
-rw-r--r--chromium/third_party/pyjson5/src/MANIFEST.in2
-rw-r--r--chromium/third_party/pyjson5/src/README.md156
-rw-r--r--chromium/third_party/pyjson5/src/benchmarks/chromium.linux.json8
-rw-r--r--chromium/third_party/pyjson5/src/benchmarks/mb_config.json2
-rwxr-xr-xchromium/third_party/pyjson5/src/benchmarks/run.py60
-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
-rw-r--r--chromium/third_party/pyjson5/src/pylintrc267
-rwxr-xr-xchromium/third_party/pyjson5/src/run47
-rw-r--r--chromium/third_party/pyjson5/src/setup.cfg3
-rw-r--r--chromium/third_party/pyjson5/src/setup.py18
19 files changed, 784 insertions, 442 deletions
diff --git a/chromium/third_party/pyjson5/OWNERS b/chromium/third_party/pyjson5/OWNERS
index 92ba00f2111..1bbcd92197b 100644
--- a/chromium/third_party/pyjson5/OWNERS
+++ b/chromium/third_party/pyjson5/OWNERS
@@ -1,3 +1,4 @@
aboxhall@chromium.org
dpranke@chromium.org
+dpranke@google.com
# COMPONENT: Tools
diff --git a/chromium/third_party/pyjson5/README.chromium b/chromium/third_party/pyjson5/README.chromium
index 0a0fdca9e39..b08afb9a65a 100644
--- a/chromium/third_party/pyjson5/README.chromium
+++ b/chromium/third_party/pyjson5/README.chromium
@@ -1,9 +1,9 @@
Name: pyjson5
Short Name: pyjson5
URL: https://github.com/dpranke/pyjson5
-Version: 0.6.1
-Date: May 22, 2018
-Revision: c88ac1f
+Version: 0.9.5
+Date: May 26 2020
+Revision: 9335da8
License: Apache 2.0
License File: src/LICENSE
Security Critical: No
diff --git a/chromium/third_party/pyjson5/src/MANIFEST.in b/chromium/third_party/pyjson5/src/MANIFEST.in
new file mode 100644
index 00000000000..7d43f806355
--- /dev/null
+++ b/chromium/third_party/pyjson5/src/MANIFEST.in
@@ -0,0 +1,2 @@
+include *.md
+include LICENSE
diff --git a/chromium/third_party/pyjson5/src/README.md b/chromium/third_party/pyjson5/src/README.md
new file mode 100644
index 00000000000..bf7aabd5417
--- /dev/null
+++ b/chromium/third_party/pyjson5/src/README.md
@@ -0,0 +1,156 @@
+# pyjson5
+
+A Python implementation of the JSON5 data format.
+
+[JSON5](https://json5.org) extends the
+[JSON](http://www.json.org) data interchange format to make it
+slightly more usable as a configuration language:
+
+* JavaScript-style comments (both single and multi-line) are legal.
+
+* Object keys may be unquoted if they are legal ECMAScript identifiers
+
+* Objects and arrays may end with trailing commas.
+
+* Strings can be single-quoted, and multi-line string literals are allowed.
+
+There are a few other more minor extensions to JSON; see the above page for
+the full details.
+
+This project implements a reader and writer implementation for Python;
+where possible, it mirrors the
+[standard Python JSON API](https://docs.python.org/library/json.html)
+package for ease of use.
+
+There is one notable difference from the JSON api: the `load()` and
+`loads()` methods support optionally checking for (and rejecting) duplicate
+object keys; pass `allow_duplicate_keys=False` to do so (duplicates are
+allowed by default).
+
+This is an early release. It has been reasonably well-tested, but it is
+**SLOW**. It can be 1000-6000x slower than the C-optimized JSON module,
+and is 200x slower (or more) than the pure Python JSON module.
+
+## Known issues
+
+* Did I mention that it is **SLOW**?
+
+* The implementation follows Python3's `json` implementation where
+ possible. This means that the `encoding` method to `dump()` is
+ ignored, and unicode strings are always returned.
+
+* The `cls` keyword argument that `json.load()`/`json.loads()` accepts
+ to specify a custom subclass of ``JSONDecoder`` is not and will not be
+ supported, because this implementation uses a completely different
+ approach to parsing strings and doesn't have anything like the
+ `JSONDecoder` class.
+
+* The `cls` keyword argument that `json.dump()`/`json.dumps()` accepts
+ is also not supported, for consistency with `json5.load()`. The `default`
+ keyword *is* supported, though, and might be able to serve as a
+ workaround.
+
+## Running the tests
+To run the tests, setup a venv and install the required dependencies with
+`pip install -e '.[dev]'`, then run the tests with `python setup.py test`.
+
+
+## Version History / Release Notes
+
+* v0.9.5 (2020-05-26)
+ * Miscellaneous non-source cleanups in the repo, including setting
+ up GitHub Actions for a CI system. No changes to the library from
+ v0.9.4, other than updating the version.
+
+* v0.9.4 (2020-03-26)
+ * [GitHub pull #38](https://github.com/dpranke/pyjson5/pull/38)
+ Fix from fredrik@fornwall.net for dumps() crashing when passed
+ an empty string as a key in an object.
+
+* v0.9.3 (2020-03-17)
+ * [GitHub pull #35](https://github.com/dpranke/pyjson5/pull/35)
+ Fix from pastelmind@ for dump() not passing the right args to dumps().
+ * Fix from p.skouzos@novafutur.com to remove the tests directory from
+ the setup call, making the package a bit smaller.
+
+* v0.9.2 (2020-03-02)
+ * [GitHub pull #34](https://github.com/dpranke/pyjson5/pull/34)
+ Fix from roosephu@ for a badly formatted nested list.
+
+* v0.9.1 (2020-02-09)
+ * [GitHub issue #33](https://github.com/dpranke/pyjson5/issues/33):
+ Fix stray trailing comma when dumping an object with an invalid key.
+
+* v0.9.0 (2020-01-30)
+ * [GitHub issue #29](https://github.com/dpranke/pyjson5/issues/29):
+ Fix an issue where objects keys that started with a reserved
+ word were incorrectly quoted.
+ * [GitHub issue #30](https://github.com/dpranke/pyjson5/issues/30):
+ Fix an issue where dumps() incorrectly thought a data structure
+ was cyclic in some cases.
+ * [GitHub issue #32](https://github.com/dpranke/pyjson5/issues/32):
+ Allow for non-string keys in dicts passed to ``dump()``/``dumps()``.
+ Add an ``allow_duplicate_keys=False`` to prevent possible
+ ill-formed JSON that might result.
+
+* v0.8.5 (2019-07-04)
+ * [GitHub issue #25](https://github.com/dpranke/pyjson5/issues/25):
+ Add LICENSE and README.md to the dist.
+ * [GitHub issue #26](https://github.com/dpranke/pyjson5/issues/26):
+ Fix printing of empty arrays and objects with indentation, fix
+ misreporting of the position on parse failures in some cases.
+
+* v0.8.4 (2019-06-11)
+ * Updated the version history, too.
+
+* v0.8.3 (2019-06-11)
+ * Tweaked the README, bumped the version, forgot to update the version
+ history :).
+
+* v0.8.2 (2019-06-11)
+ * Actually bump the version properly, to 0.8.2.
+
+* v0.8.1 (2019-06-11)
+ * Fix bug in setup.py that messed up the description. Unfortunately,
+ I forgot to bump the version for this, so this also identifies as 0.8.0.
+
+* v0.8.0 (2019-06-11)
+ * Add `allow_duplicate_keys=True` as a default argument to
+ `json5.load()`/`json5.loads()`. If you set the key to `False`, duplicate
+ keys in a single dict will be rejected. The default is set to `True`
+ for compatibility with `json.load()`, earlier versions of json5, and
+ because it's simply not clear if people would want duplicate checking
+ enabled by default.
+
+* v0.7 (2019-03-31)
+ * Changes dump()/dumps() to not quote object keys by default if they are
+ legal identifiers. Passing `quote_keys=True` will turn that off
+ and always quote object keys.
+ * Changes dump()/dumps() to insert trailing commas after the last item
+ in an array or an object if the object is printed across multiple lines
+ (i.e., if `indent` is not None). Passing `trailing_commas=False` will
+ turn that off.
+ * The `json5.tool` command line tool now supports the `--indent`,
+ `--[no-]quote-keys`, and `--[no-]trailing-commas` flags to allow
+ for more control over the output, in addition to the existing
+ `--as-json` flag.
+ * The `json5.tool` command line tool no longer supports reading from
+ multiple files, you can now only read from a single file or
+ from standard input.
+ * The implementation no longer relies on the standard `json` module
+ for anything. The output should still match the json module (except
+ as noted above) and discrepancies should be reported as bugs.
+
+* v0.6.2 (2019-03-08)
+ * Fix [GitHub issue #23](https://github.com/dpranke/pyjson5/issues/23) and
+ pass through unrecognized escape sequences.
+
+* v0.6.1 (2018-05-22)
+ * Cleaned up a couple minor nits in the package.
+
+* v0.6.0 (2017-11-28)
+ * First implementation that attempted to implement 100% of the spec.
+
+* v0.5.0 (2017-09-04)
+ * First implementation that supported the full set of kwargs that
+ the `json` module supports.
diff --git a/chromium/third_party/pyjson5/src/benchmarks/chromium.linux.json b/chromium/third_party/pyjson5/src/benchmarks/chromium.linux.json
index 3cb4bef44ae..3ee88cedc13 100644
--- a/chromium/third_party/pyjson5/src/benchmarks/chromium.linux.json
+++ b/chromium/third_party/pyjson5/src/benchmarks/chromium.linux.json
@@ -4133,15 +4133,15 @@
}
},
{
- "isolate_name": "devtools_lint_check",
- "name": "devtools_lint_check",
+ "isolate_name": "devtools_closure_compile",
+ "name": "devtools_closure_compile",
"swarming": {
"can_use_on_swarming_builders": true
}
},
{
- "isolate_name": "devtools_type_check",
- "name": "devtools_type_check",
+ "isolate_name": "devtools_eslint",
+ "name": "devtools_eslint",
"swarming": {
"can_use_on_swarming_builders": true
}
diff --git a/chromium/third_party/pyjson5/src/benchmarks/mb_config.json b/chromium/third_party/pyjson5/src/benchmarks/mb_config.json
index fc3a96a7e20..af93ef0f293 100644
--- a/chromium/third_party/pyjson5/src/benchmarks/mb_config.json
+++ b/chromium/third_party/pyjson5/src/benchmarks/mb_config.json
@@ -1966,7 +1966,7 @@
"gn_args": "internal_gles2_conform_tests=true"
},
"java_coverage": {
- "gn_args": "jacoco_coverage=true"
+ "gn_args": "emma_coverage=true emma_filter=\"org.chromium.*\""
},
"libfuzzer": {
"gn_args": "use_libfuzzer=true"
diff --git a/chromium/third_party/pyjson5/src/benchmarks/run.py b/chromium/third_party/pyjson5/src/benchmarks/run.py
index 572755816c2..63eb2965dd1 100755
--- a/chromium/third_party/pyjson5/src/benchmarks/run.py
+++ b/chromium/third_party/pyjson5/src/benchmarks/run.py
@@ -22,11 +22,12 @@ import sys
import time
THIS_DIR = os.path.abspath(os.path.dirname(__file__))
-REPO_DIR = os.path.dirname(THIS_DIR)
+REPO_DIR = os.path.dirname(THIS_DIR)
if not REPO_DIR in sys.path:
sys.path.insert(0, REPO_DIR)
-import json5
+import json5 # pylint: disable=wrong-import-position
+
ALL_BENCHMARKS = (
'ios-simulator.json',
@@ -35,7 +36,9 @@ ALL_BENCHMARKS = (
'chromium.perf.json',
)
-DEFAULT_ITERATIONS = 1
+
+DEFAULT_ITERATIONS = 3
+
def main():
parser = argparse.ArgumentParser()
@@ -54,18 +57,21 @@ def main():
# json.decoder.c_scanstring = py_scanstring
- def py_maker(*_args, **_kwargs):
- decoder = json.JSONDecoder()
- decoder.scan_once = json.scanner.py_make_scanner(decoder)
- decoder.parse_string = json.decoder.py_scanstring
- json.decoder.scanstring = decoder.parse_string
- return decoder
+ def py_maker(*args, **kwargs):
+ del args
+ del kwargs
+ decoder = json.JSONDecoder()
+ decoder.scan_once = json.scanner.py_make_scanner(decoder)
+ decoder.parse_string = json.decoder.py_scanstring
+ json.decoder.scanstring = decoder.parse_string
+ return decoder
maker = py_maker if args.pure else json.JSONDecoder
all_times = []
for i, c in enumerate(file_contents):
- times = []
+ json_time = 0.0
+ json5_time = 0.0
for _ in range(args.num_iterations):
start = time.time()
json_obj = json.loads(c, cls=maker)
@@ -73,16 +79,30 @@ def main():
json5_obj = json5.loads(c)
end = time.time()
- json_time = mid - start
- json5_time = end - mid
- times.append((json_time, json5_time))
- assert(json5_obj == json_obj)
- all_times.append(times)
-
- for i, times in enumerate(all_times):
- avg = sum((json5_time / json_time)
- for json_time, json5_time in times) / args.num_iterations
- print("%-20s: %5.1f" % (args.benchmarks[i], avg))
+ json_time += mid - start
+ json5_time += end - mid
+ assert json5_obj == json_obj
+ all_times.append((json_time, json5_time))
+
+ for i, (json_time, json5_time) in enumerate(all_times):
+ fname = os.path.basename(args.benchmarks[i])
+ if json5_time and json_time:
+ if json5_time > json_time:
+ avg = json5_time / json_time
+ print("%-20s: JSON was %5.1fx faster (%.6fs to %.6fs)" % (
+ fname, avg, json_time, json5_time))
+ else:
+ avg = json_time / json5_time
+ print("%-20s: JSON5 was %5.1fx faster (%.6fs to %.6fs)" % (
+ fname, avg, json5_time, json_time))
+ elif json5_time:
+ print("%-20s: JSON5 took %.6f secs, JSON was too fast to measure" %
+ (fname, json5_time))
+ elif json_time:
+ print("%-20s: JSON took %.6f secs, JSON5 was too fast to measure" %
+ (fname, json_time))
+ else:
+ print("%-20s: both were too fast to measure" % (fname,))
return 0
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'
diff --git a/chromium/third_party/pyjson5/src/pylintrc b/chromium/third_party/pyjson5/src/pylintrc
index 4abb6c605d0..03a3a28fb8a 100644
--- a/chromium/third_party/pyjson5/src/pylintrc
+++ b/chromium/third_party/pyjson5/src/pylintrc
@@ -14,261 +14,44 @@
[MASTER]
-# Specify a configuration file.
-#rcfile=
-
-# Python code to execute, usually for sys.path manipulation such as
-# pygtk.require().
-#init-hook=
-
-# Profiled execution.
-profile=no
-
-# Add files or directories to the blacklist. They should be base names, not
-# paths.
-ignore=CVS
-
# Pickle collected data for later comparisons.
persistent=yes
-# List of plugins (as comma separated values of python modules names) to load,
-# usually to register additional checkers.
-load-plugins=
-
-
[MESSAGES CONTROL]
-# Enable the message, report, category or checker with the given id(s). You can
-# either give multiple identifier separated by comma (,) or put this option
-# multiple time.
-#enable=
-
-# Disable the message, report, category or checker with the given id(s). You
-# can either give multiple identifier separated by comma (,) or put this option
-# multiple time (only on the command line, not in the configuration file where
-# it should appear only once).
-# CHANGED:
-# C0111: Missing docstring
-# I0011: Locally disabling WNNNN
-# R0201: Method could be a function
-# R0801: Similar lines
-# W0141: Used builtin function 'map'
-# W0142: Used * or ** magic
-# W0511: TODO
-# W0703: Catch "Exception"
-disable=C0111,I0011,R0201,R0801,W0141,W0142,W0511,W0703
-
+disable=
+ broad-except,
+ global-statement,
+ locally-disabled,
+ missing-docstring,
+ no-self-use,
+ too-many-arguments,
+ too-few-public-methods,
+ too-many-branches,
+ too-many-instance-attributes,
+ too-many-locals,
+ too-many-public-methods,
+ too-many-return-statements,
+ unidiomatic-typecheck,
[REPORTS]
-# Set the output format. Available formats are text, parseable, colorized, msvs
-# (visual studio) and html
-output-format=text
-
-# Include message's id in output
-include-ids=yes
-
-# Put messages in a separate file for each module / package specified on the
-# command line instead of printing them on stdout. Reports (if any) will be
-# written in a file name "pylint_global.[txt|html]".
-files-output=no
-
-# Tells whether to display a full report or only the messages
-# CHANGED:
reports=no
-# Python expression which should return a note less than 10 (10 is the highest
-# note). You have access to the variables errors warning, statement which
-# respectively contain the number of errors / warnings messages and the total
-# number of statements analyzed. This is used by the global evaluation report
-# (RP0004).
-evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
-
-# Add a comment according to your evaluation note. This is used by the global
-# evaluation report (RP0004).
-comment=no
-
-
-[VARIABLES]
-
-# Tells whether we should check for unused import in __init__ files.
-init-import=no
-
-# A regular expression matching the beginning of the name of dummy variables
-# (i.e. not used).
-dummy-variables-rgx=_|dummy
-
-# List of additional names supposed to be defined in builtins. Remember that
-# you should avoid to define new builtins when possible.
-additional-builtins=
-
-
-[TYPECHECK]
-
-# Tells whether missing members accessed in mixin class should be ignored. A
-# mixin class is detected if its name ends with "mixin" (case insensitive).
-ignore-mixin-members=yes
-
-# List of classes names for which member attributes should not be checked
-# (useful for classes with attributes dynamically set).
-ignored-classes=
-
-# When zope mode is activated, add a predefined set of Zope acquired attributes
-# to generated-members.
-zope=no
-
-# List of members which are set dynamically and missed by pylint inference
-# system, and so shouldn't trigger E0201 when accessed. Python regular
-# expressions are accepted.
-generated-members=
-
-
-[MISCELLANEOUS]
-
-# List of note tags to take in consideration, separated by a comma.
-notes=FIXME,XXX,TODO
-
-
-[SIMILARITIES]
-
-# Minimum lines number of a similarity.
-min-similarity-lines=4
-
-# Ignore comments when computing similarities.
-ignore-comments=yes
-
-# Ignore docstrings when computing similarities.
-ignore-docstrings=yes
-
-
-[FORMAT]
-
-# Maximum number of characters on a single line.
-# max-line-length=200
-
-# Maximum number of lines in a module
-# max-module-lines=1000
-
-# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
-# tab).
-# CHANGED:
-indent-string=' '
-
-
[BASIC]
-# Required attributes for module, separated by a comma
-required-attributes=
-
-# List of builtins function names that should not be used, separated by a comma
-bad-functions=map,filter,apply,input
-
-# Regular expression which should only match correct module names
-module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
-
-# Regular expression which should only match correct module level names
-const-rgx=(([a-zA-Z_][a-zA-Z0-9_]*)|(__.*__))$
-
-# Regular expression which should only match correct class names
-class-rgx=[A-Z_][a-zA-Z0-9]+$
+# By default, pylint wants method names to be at most 31 chars long,
+# but we want to allow up to 49 to allow for longer test names.
+method-rgx=[a-zA-Z_][a-zA-Z0-9_]{0,48}$
-# Regular expression which should only match correct function names
-function-rgx=[a-z_][a-z0-9_]{0,40}$
+# By default, pylint only allows UPPER_CASE constants, but we want to
+# allow snake_case as well in some situations.
+const-rgx=[a-zA-Z_][a-zA-Z0-9_]{0,30}$
-# Regular expression which should only match correct method names
-method-rgx=[a-z_][a-z0-9_]{0,48}$
-
-# Regular expression which should only match correct instance attribute names
-attr-rgx=[a-z_][a-z0-9_]{0,30}$
-
-# Regular expression which should only match correct argument names
+# By default, pylint wants all parameter names to be at least two chars long,
+# but we want to allow single-char parameter names as well.
argument-rgx=[a-z_][a-z0-9_]{0,30}$
-# Regular expression which should only match correct variable names
-variable-rgx=[a-zA-Z0-9_]{0,30}$
-
-# Regular expression which should only match correct list comprehension /
-# generator expression variable names
-inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
-
-# Good variable names which should always be accepted, separated by a comma
-good-names=i,j,k,ex,Run,_
-
-# Bad variable names which should always be refused, separated by a comma
-bad-names=foo,bar,baz,toto,tutu,tata
-
-# Regular expression which should only match functions or classes name which do
-# not require a docstring
-no-docstring-rgx=__.*__
-
-
-[DESIGN]
-
-# Maximum number of arguments for function / method
-max-args=8
-
-# Argument names that match this expression will be ignored. Default to name
-# with leading underscore
-ignored-argument-names=_.*
-
-# Maximum number of locals for function / method body
-max-locals=32
-
-# Maximum number of return / yield for function / method body
-max-returns=32
-
-# Maximum number of branch for function / method body
-max-branchs=32
-
-# Maximum number of statements in function / method body
-max-statements=65
-
-# Maximum number of parents for a class (see R0901).
-max-parents=7
-
-# Maximum number of attributes for a class (see R0902).
-max-attributes=16
-
-# Minimum number of public methods for a class (see R0903).
-min-public-methods=0
-
-# Maximum number of public methods for a class (see R0904).
-max-public-methods=100
-
-
-[CLASSES]
-
-# List of interface methods to ignore, separated by a comma. This is used for
-# instance to not check methods defines in Zope's Interface base class.
-ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by
-
-# List of method names used to declare (i.e. assign) instance attributes.
-defining-attr-methods=__init__,__new__,setUp
-
-# List of valid names for the first argument in a class method.
-valid-classmethod-first-arg=cls
-
-
-[IMPORTS]
-
-# Deprecated modules which should not be used, separated by a comma
-deprecated-modules=regsub,string,TERMIOS,Bastion,rexec
-
-# Create a graph of every (i.e. internal and external) dependencies in the
-# given file (report RP0402 must not be disabled)
-import-graph=
-
-# Create a graph of external dependencies in the given file (report RP0402 must
-# not be disabled)
-ext-import-graph=
-
-# Create a graph of internal dependencies in the given file (report RP0402 must
-# not be disabled)
-int-import-graph=
-
-
-[EXCEPTIONS]
-
-# Exceptions that will emit a warning when being caught. Defaults to
-# "Exception"
-overgeneral-exceptions=Exception
+# By default, pylint wants all variable names to be at least two chars long,
+# but we want to allow single-char variable names as well.
+variable-rgx=[a-z_][a-z0-9_]{0,30}$
diff --git a/chromium/third_party/pyjson5/src/run b/chromium/third_party/pyjson5/src/run
index 22fff41b9f7..c28ba07074c 100755
--- a/chromium/third_party/pyjson5/src/run
+++ b/chromium/third_party/pyjson5/src/run
@@ -3,16 +3,11 @@
from __future__ import print_function
import argparse
-import os
import subprocess
import sys
-is_python3 = bool(sys.version_info.major == 3)
-has_python34 = False
verbose = False
-repo_dir = os.path.abspath(os.path.dirname(__file__))
-path_to_cov = os.path.join(repo_dir, 'tools', 'cov.py')
def call(*args, **kwargs):
@@ -25,8 +20,6 @@ def call(*args, **kwargs):
def main(argv):
parser = argparse.ArgumentParser(prog='run')
- parser.add_argument('--no3', action='store_true',
- help='Do not run the tests under Python 3.')
parser.add_argument('-v', '--verbose', action='store_true')
subps = parser.add_subparsers()
@@ -37,16 +30,9 @@ def main(argv):
subp.set_defaults(func=run_clean)
subp = subps.add_parser('coverage',
- help='Run the tests and report code coverage.')
+ help='Run tests and report code coverage.')
subp.set_defaults(func=run_coverage)
- subp = subps.add_parser('develop',
- help='Install a symlinked package locally.')
- subp.set_defaults(func=run_develop)
- subp.add_argument('--system', action='store_true',
- help=('Install to the system site-package dir '
- 'rather than the user\'s (requires root).'))
-
subp = subps.add_parser('format',
help='Reformat the source code.')
subp.set_defaults(func=run_format)
@@ -77,34 +63,31 @@ def main(argv):
global verbose
if args.verbose:
verbose = True
- global has_python34
- if not args.no3:
- try:
- ver = subprocess.check_output(['python3', '--version'])
- has_python34 = ver.split()[1] >= '3.4'
- except:
- pass
args.func(args)
def run_build(args):
+ del args
call([sys.executable, 'setup.py', 'build', '--quiet'])
def run_clean(args):
+ del args
call(['git', 'clean', '-fxd'])
def run_coverage(args):
- call(['typ', '-c', 'json5'])
-
-
-def run_develop(args):
- call([sys.executable, 'setup.py', 'develop'])
+ del args
+ call(['python', '-m', 'coverage', 'run', '-m', 'unittest',
+ 'discover', '-p', '*_test.py'])
+ call(['python3', '-m', 'coverage', 'run', '--append', '-m', 'unittest',
+ 'discover', '-p', '*_test.py'])
+ call([sys.executable, '-m', 'coverage', 'report', '--show-missing'])
def run_format(args):
- call('autopep8 --in-place *.py */*.py */*/*.py', shell=True)
+ del args
+ call('autopep8 --in-place *.py */*.py', shell=True)
def run_help(args):
@@ -122,12 +105,14 @@ def run_install(args):
def run_lint(args):
- call('pylint --rcfile=pylintrc */*.py */*/*.py', shell=True)
- call('pep8 *.py */*.py */*/*.py', shell=True)
+ del args
+ call('pylint --rcfile=pylintrc */*.py', shell=True)
def run_tests(args):
- call(['typ', 'json5'])
+ del args
+ call([sys.executable, '-m', 'unittest', 'discover',
+ '-p', '*_test.py'])
if __name__ == '__main__':
diff --git a/chromium/third_party/pyjson5/src/setup.cfg b/chromium/third_party/pyjson5/src/setup.cfg
index 3c6e79cf31d..8462fbd4a19 100644
--- a/chromium/third_party/pyjson5/src/setup.cfg
+++ b/chromium/third_party/pyjson5/src/setup.cfg
@@ -1,2 +1,5 @@
+[metadata]
+license_files = LICENSE.txt
+
[bdist_wheel]
universal=1
diff --git a/chromium/third_party/pyjson5/src/setup.py b/chromium/third_party/pyjson5/src/setup.py
index d0e23fcc4a5..f63e66c113d 100644
--- a/chromium/third_party/pyjson5/src/setup.py
+++ b/chromium/third_party/pyjson5/src/setup.py
@@ -23,15 +23,13 @@ if here not in sys.path:
import json5
-with open(os.path.join(here, 'README.rst')) as fp:
- readme = fp.read().strip()
+with open(os.path.join(here, 'README.md')) as fp:
+ long_description = fp.read()
-readme_lines = readme.splitlines()
setup(
name='json5',
- packages=find_packages(),
- package_data={'': ['../README.rst']},
+ packages=find_packages(exclude=['tests']),
entry_points={
'console_scripts': [
'pyjson5=json5.tool:main',
@@ -39,11 +37,17 @@ setup(
},
install_requires=[
],
+ extras_require={
+ 'dev': [
+ 'hypothesis'
+ ]
+ },
version=json5.VERSION,
author='Dirk Pranke',
author_email='dpranke@chromium.org',
- description=readme_lines[3],
- long_description=('\n' + '\n'.join(readme_lines)),
+ description=long_description.splitlines()[2],
+ long_description=long_description,
+ long_description_content_type='text/markdown',
url='https://github.com/dpranke/pyjson5',
license='Apache',
classifiers=[