mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 10:44:36 +08:00
Update json from 3.13.5 (#6007)
* Update `json` from 3.13.5 * Update `test_json` from 3.13.5
This commit is contained in:
1 parent
8177525d49
commit
c497061290
19 files changed
+195
-102
No files matched your search
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
r"""JSON (JavaScript Object Notation) <http://json.org> is a subset of
|
||||
r"""JSON (JavaScript Object Notation) <https://json.org> is a subset of
|
||||
JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data
|
||||
interchange format.
|
||||
|
||||
|
||||
Vendored
+13
-6
@@ -41,7 +41,6 @@ class JSONDecodeError(ValueError):
|
||||
pos += col
|
||||
return cls(msg, doc, pos)
|
||||
|
||||
|
||||
# Note that this exception is used from _json
|
||||
def __init__(self, msg, doc, pos):
|
||||
lineno = doc.count('\n', 0, pos) + 1
|
||||
@@ -65,17 +64,18 @@ _CONSTANTS = {
|
||||
}
|
||||
|
||||
|
||||
HEXDIGITS = re.compile(r'[0-9A-Fa-f]{4}', FLAGS)
|
||||
STRINGCHUNK = re.compile(r'(.*?)(["\\\x00-\x1f])', FLAGS)
|
||||
BACKSLASH = {
|
||||
'"': '"', '\\': '\\', '/': '/',
|
||||
'b': '\b', 'f': '\f', 'n': '\n', 'r': '\r', 't': '\t',
|
||||
}
|
||||
|
||||
def _decode_uXXXX(s, pos):
|
||||
esc = s[pos + 1:pos + 5]
|
||||
if len(esc) == 4 and esc[1] not in 'xX':
|
||||
def _decode_uXXXX(s, pos, _m=HEXDIGITS.match):
|
||||
esc = _m(s, pos + 1)
|
||||
if esc is not None:
|
||||
try:
|
||||
return int(esc, 16)
|
||||
return int(esc.group(), 16)
|
||||
except ValueError:
|
||||
pass
|
||||
msg = "Invalid \\uXXXX escape"
|
||||
@@ -215,10 +215,13 @@ def JSONObject(s_and_end, strict, scan_once, object_hook, object_pairs_hook,
|
||||
break
|
||||
elif nextchar != ',':
|
||||
raise JSONDecodeError("Expecting ',' delimiter", s, end - 1)
|
||||
comma_idx = end - 1
|
||||
end = _w(s, end).end()
|
||||
nextchar = s[end:end + 1]
|
||||
end += 1
|
||||
if nextchar != '"':
|
||||
if nextchar == '}':
|
||||
raise JSONDecodeError("Illegal trailing comma before end of object", s, comma_idx)
|
||||
raise JSONDecodeError(
|
||||
"Expecting property name enclosed in double quotes", s, end - 1)
|
||||
if object_pairs_hook is not None:
|
||||
@@ -255,19 +258,23 @@ def JSONArray(s_and_end, scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR):
|
||||
break
|
||||
elif nextchar != ',':
|
||||
raise JSONDecodeError("Expecting ',' delimiter", s, end - 1)
|
||||
comma_idx = end - 1
|
||||
try:
|
||||
if s[end] in _ws:
|
||||
end += 1
|
||||
if s[end] in _ws:
|
||||
end = _w(s, end + 1).end()
|
||||
nextchar = s[end:end + 1]
|
||||
except IndexError:
|
||||
pass
|
||||
if nextchar == ']':
|
||||
raise JSONDecodeError("Illegal trailing comma before end of array", s, comma_idx)
|
||||
|
||||
return values, end
|
||||
|
||||
|
||||
class JSONDecoder(object):
|
||||
"""Simple JSON <http://json.org> decoder
|
||||
"""Simple JSON <https://json.org> decoder
|
||||
|
||||
Performs the following translations in decoding by default:
|
||||
|
||||
|
||||
Vendored
+15
-13
@@ -30,6 +30,7 @@ ESCAPE_DCT = {
|
||||
for i in range(0x20):
|
||||
ESCAPE_DCT.setdefault(chr(i), '\\u{0:04x}'.format(i))
|
||||
#ESCAPE_DCT.setdefault(chr(i), '\\u%04x' % (i,))
|
||||
del i
|
||||
|
||||
INFINITY = float('inf')
|
||||
|
||||
@@ -71,7 +72,7 @@ encode_basestring_ascii = (
|
||||
c_encode_basestring_ascii or py_encode_basestring_ascii)
|
||||
|
||||
class JSONEncoder(object):
|
||||
"""Extensible JSON <http://json.org> encoder for Python data structures.
|
||||
"""Extensible JSON <https://json.org> encoder for Python data structures.
|
||||
|
||||
Supports the following objects and types by default:
|
||||
|
||||
@@ -107,8 +108,8 @@ class JSONEncoder(object):
|
||||
"""Constructor for JSONEncoder, with sensible defaults.
|
||||
|
||||
If skipkeys is false, then it is a TypeError to attempt
|
||||
encoding of keys that are not str, int, float or None. If
|
||||
skipkeys is True, such items are simply skipped.
|
||||
encoding of keys that are not str, int, float, bool or None.
|
||||
If skipkeys is True, such items are simply skipped.
|
||||
|
||||
If ensure_ascii is true, the output is guaranteed to be str
|
||||
objects with all incoming non-ASCII characters escaped. If
|
||||
@@ -173,7 +174,7 @@ class JSONEncoder(object):
|
||||
else:
|
||||
return list(iterable)
|
||||
# Let the base class default method raise the TypeError
|
||||
return JSONEncoder.default(self, o)
|
||||
return super().default(o)
|
||||
|
||||
"""
|
||||
raise TypeError(f'Object of type {o.__class__.__name__} '
|
||||
@@ -243,15 +244,18 @@ class JSONEncoder(object):
|
||||
return text
|
||||
|
||||
|
||||
if (_one_shot and c_make_encoder is not None
|
||||
and self.indent is None):
|
||||
if self.indent is None or isinstance(self.indent, str):
|
||||
indent = self.indent
|
||||
else:
|
||||
indent = ' ' * self.indent
|
||||
if _one_shot and c_make_encoder is not None:
|
||||
_iterencode = c_make_encoder(
|
||||
markers, self.default, _encoder, self.indent,
|
||||
markers, self.default, _encoder, indent,
|
||||
self.key_separator, self.item_separator, self.sort_keys,
|
||||
self.skipkeys, self.allow_nan)
|
||||
else:
|
||||
_iterencode = _make_iterencode(
|
||||
markers, self.default, _encoder, self.indent, floatstr,
|
||||
markers, self.default, _encoder, indent, floatstr,
|
||||
self.key_separator, self.item_separator, self.sort_keys,
|
||||
self.skipkeys, _one_shot)
|
||||
return _iterencode(o, 0)
|
||||
@@ -271,9 +275,6 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
|
||||
_intstr=int.__repr__,
|
||||
):
|
||||
|
||||
if _indent is not None and not isinstance(_indent, str):
|
||||
_indent = ' ' * _indent
|
||||
|
||||
def _iterencode_list(lst, _current_indent_level):
|
||||
if not lst:
|
||||
yield '[]'
|
||||
@@ -344,7 +345,6 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
|
||||
_current_indent_level += 1
|
||||
newline_indent = '\n' + _indent * _current_indent_level
|
||||
item_separator = _item_separator + newline_indent
|
||||
yield newline_indent
|
||||
else:
|
||||
newline_indent = None
|
||||
item_separator = _item_separator
|
||||
@@ -377,6 +377,8 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
|
||||
f'not {key.__class__.__name__}')
|
||||
if first:
|
||||
first = False
|
||||
if newline_indent is not None:
|
||||
yield newline_indent
|
||||
else:
|
||||
yield item_separator
|
||||
yield _encoder(key)
|
||||
@@ -403,7 +405,7 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
|
||||
else:
|
||||
chunks = _iterencode(value, _current_indent_level)
|
||||
yield from chunks
|
||||
if newline_indent is not None:
|
||||
if not first and newline_indent is not None:
|
||||
_current_indent_level -= 1
|
||||
yield '\n' + _indent * _current_indent_level
|
||||
yield '}'
|
||||
|
||||
Vendored
+1
-1
@@ -9,7 +9,7 @@ except ImportError:
|
||||
__all__ = ['make_scanner']
|
||||
|
||||
NUMBER_RE = re.compile(
|
||||
r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?',
|
||||
r'(-?(?:0|[1-9][0-9]*))(\.[0-9]+)?([eE][-+]?[0-9]+)?',
|
||||
(re.VERBOSE | re.MULTILINE | re.DOTALL))
|
||||
|
||||
def py_make_scanner(context):
|
||||
|
||||
Vendored
+19
-15
@@ -13,7 +13,6 @@ Usage::
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def main():
|
||||
@@ -22,11 +21,9 @@ def main():
|
||||
'to validate and pretty-print JSON objects.')
|
||||
parser = argparse.ArgumentParser(prog=prog, description=description)
|
||||
parser.add_argument('infile', nargs='?',
|
||||
type=argparse.FileType(encoding="utf-8"),
|
||||
help='a JSON file to be validated or pretty-printed',
|
||||
default=sys.stdin)
|
||||
default='-')
|
||||
parser.add_argument('outfile', nargs='?',
|
||||
type=Path,
|
||||
help='write the output of infile to outfile',
|
||||
default=None)
|
||||
parser.add_argument('--sort-keys', action='store_true', default=False,
|
||||
@@ -59,23 +56,30 @@ def main():
|
||||
dump_args['indent'] = None
|
||||
dump_args['separators'] = ',', ':'
|
||||
|
||||
with options.infile as infile:
|
||||
try:
|
||||
if options.infile == '-':
|
||||
infile = sys.stdin
|
||||
else:
|
||||
infile = open(options.infile, encoding='utf-8')
|
||||
try:
|
||||
if options.json_lines:
|
||||
objs = (json.loads(line) for line in infile)
|
||||
else:
|
||||
objs = (json.load(infile),)
|
||||
finally:
|
||||
if infile is not sys.stdin:
|
||||
infile.close()
|
||||
|
||||
if options.outfile is None:
|
||||
out = sys.stdout
|
||||
else:
|
||||
out = options.outfile.open('w', encoding='utf-8')
|
||||
with out as outfile:
|
||||
for obj in objs:
|
||||
json.dump(obj, outfile, **dump_args)
|
||||
outfile.write('\n')
|
||||
except ValueError as e:
|
||||
raise SystemExit(e)
|
||||
if options.outfile is None:
|
||||
outfile = sys.stdout
|
||||
else:
|
||||
outfile = open(options.outfile, 'w', encoding='utf-8')
|
||||
with outfile:
|
||||
for obj in objs:
|
||||
json.dump(obj, outfile, **dump_args)
|
||||
outfile.write('\n')
|
||||
except ValueError as e:
|
||||
raise SystemExit(e)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
Vendored
+46
-6
@@ -2,21 +2,50 @@ import decimal
|
||||
from io import StringIO
|
||||
from collections import OrderedDict
|
||||
from test.test_json import PyTest, CTest
|
||||
from test import support
|
||||
|
||||
import unittest
|
||||
import unittest # XXX: RUSTPYTHON; importing to be able to skip tests
|
||||
|
||||
|
||||
class TestDecode:
|
||||
def test_decimal(self):
|
||||
rval = self.loads('1.1', parse_float=decimal.Decimal)
|
||||
self.assertTrue(isinstance(rval, decimal.Decimal))
|
||||
self.assertIsInstance(rval, decimal.Decimal)
|
||||
self.assertEqual(rval, decimal.Decimal('1.1'))
|
||||
|
||||
def test_float(self):
|
||||
rval = self.loads('1', parse_int=float)
|
||||
self.assertTrue(isinstance(rval, float))
|
||||
self.assertIsInstance(rval, float)
|
||||
self.assertEqual(rval, 1.0)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.skip("TODO: RUSTPYTHON; called `Result::unwrap()` on an `Err` value: ParseFloatError { kind: Invalid }")
|
||||
def test_nonascii_digits_rejected(self):
|
||||
# JSON specifies only ascii digits, see gh-125687
|
||||
for num in ["1\uff10", "0.\uff10", "0e\uff10"]:
|
||||
with self.assertRaises(self.JSONDecodeError):
|
||||
self.loads(num)
|
||||
|
||||
def test_bytes(self):
|
||||
self.assertEqual(self.loads(b"1"), 1)
|
||||
|
||||
def test_parse_constant(self):
|
||||
for constant, expected in [
|
||||
("Infinity", "INFINITY"),
|
||||
("-Infinity", "-INFINITY"),
|
||||
("NaN", "NAN"),
|
||||
]:
|
||||
self.assertEqual(
|
||||
self.loads(constant, parse_constant=str.upper), expected
|
||||
)
|
||||
|
||||
def test_constant_invalid_case(self):
|
||||
for constant in [
|
||||
"nan", "NAN", "naN", "infinity", "INFINITY", "inFiniTy"
|
||||
]:
|
||||
with self.assertRaises(self.JSONDecodeError):
|
||||
self.loads(constant)
|
||||
|
||||
def test_empty_objects(self):
|
||||
self.assertEqual(self.loads('{}'), {})
|
||||
self.assertEqual(self.loads('[]'), [])
|
||||
@@ -89,7 +118,8 @@ class TestDecode:
|
||||
self.json.load(StringIO(bom_json))
|
||||
self.assertIn('BOM', str(cm.exception))
|
||||
# make sure that the BOM is not detected in the middle of a string
|
||||
bom_in_str = '"{}"'.format(''.encode('utf-8-sig').decode('utf-8'))
|
||||
bom = ''.encode('utf-8-sig').decode('utf-8')
|
||||
bom_in_str = f'"{bom}"'
|
||||
self.assertEqual(self.loads(bom_in_str), '\ufeff')
|
||||
self.assertEqual(self.json.load(StringIO(bom_in_str)), '\ufeff')
|
||||
|
||||
@@ -97,9 +127,19 @@ class TestDecode:
|
||||
d = self.json.JSONDecoder()
|
||||
self.assertRaises(ValueError, d.raw_decode, 'a'*42, -50000)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_limit_int(self):
|
||||
maxdigits = 5000
|
||||
with support.adjust_int_max_str_digits(maxdigits):
|
||||
self.loads('1' * maxdigits)
|
||||
with self.assertRaises(ValueError):
|
||||
self.loads('1' * (maxdigits + 1))
|
||||
|
||||
|
||||
class TestPyDecode(TestDecode, PyTest): pass
|
||||
# TODO: RUSTPYTHON
|
||||
class TestCDecode(TestDecode, CTest): # pass
|
||||
|
||||
class TestCDecode(TestDecode, CTest):
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_keys_reuse(self):
|
||||
|
||||
Vendored
+11
@@ -1,3 +1,4 @@
|
||||
import collections
|
||||
from test.test_json import PyTest, CTest
|
||||
|
||||
|
||||
@@ -7,6 +8,16 @@ class TestDefault:
|
||||
self.dumps(type, default=repr),
|
||||
self.dumps(repr(type)))
|
||||
|
||||
def test_ordereddict(self):
|
||||
od = collections.OrderedDict(a=1, b=2, c=3, d=4)
|
||||
od.move_to_end('b')
|
||||
self.assertEqual(
|
||||
self.dumps(od),
|
||||
'{"a": 1, "c": 3, "d": 4, "b": 2}')
|
||||
self.assertEqual(
|
||||
self.dumps(od, sort_keys=True),
|
||||
'{"a": 1, "b": 2, "c": 3, "d": 4}')
|
||||
|
||||
|
||||
class TestPyDefault(TestDefault, PyTest): pass
|
||||
class TestCDefault(TestDefault, CTest): pass
|
||||
Vendored
+8
@@ -22,6 +22,14 @@ class TestDump:
|
||||
self.assertIn('valid_key', o)
|
||||
self.assertNotIn(b'invalid_key', o)
|
||||
|
||||
def test_dump_skipkeys_indent_empty(self):
|
||||
v = {b'invalid_key': False}
|
||||
self.assertEqual(self.json.dumps(v, skipkeys=True, indent=4), '{}')
|
||||
|
||||
def test_skipkeys_indent(self):
|
||||
v = {b'invalid_key': False, 'valid_key': True}
|
||||
self.assertEqual(self.json.dumps(v, skipkeys=True, indent=4), '{\n "valid_key": true\n}')
|
||||
|
||||
def test_encode_truefalse(self):
|
||||
self.assertEqual(self.dumps(
|
||||
{True: False, False: True}, sort_keys=True),
|
||||
|
||||
+1
-2
@@ -23,8 +23,7 @@ class TestEncodeBasestringAscii:
|
||||
for input_string, expect in CASES:
|
||||
result = self.json.encoder.encode_basestring_ascii(input_string)
|
||||
self.assertEqual(result, expect,
|
||||
'{0!r} != {1!r} for {2}({3!r})'.format(
|
||||
result, expect, fname, input_string))
|
||||
f'{result!r} != {expect!r} for {fname}({input_string!r})')
|
||||
|
||||
def test_ordered_dict(self):
|
||||
# See issue 6105
|
||||
|
||||
Vendored
+44
-42
@@ -1,75 +1,76 @@
|
||||
import unittest
|
||||
from test.test_json import PyTest, CTest
|
||||
|
||||
import unittest # XXX: RUSTPYTHON; importing to be able to skip tests
|
||||
|
||||
# 2007-10-05
|
||||
JSONDOCS = [
|
||||
# http://json.org/JSON_checker/test/fail1.json
|
||||
# https://json.org/JSON_checker/test/fail1.json
|
||||
'"A JSON payload should be an object or array, not a string."',
|
||||
# http://json.org/JSON_checker/test/fail2.json
|
||||
# https://json.org/JSON_checker/test/fail2.json
|
||||
'["Unclosed array"',
|
||||
# http://json.org/JSON_checker/test/fail3.json
|
||||
# https://json.org/JSON_checker/test/fail3.json
|
||||
'{unquoted_key: "keys must be quoted"}',
|
||||
# http://json.org/JSON_checker/test/fail4.json
|
||||
# https://json.org/JSON_checker/test/fail4.json
|
||||
'["extra comma",]',
|
||||
# http://json.org/JSON_checker/test/fail5.json
|
||||
# https://json.org/JSON_checker/test/fail5.json
|
||||
'["double extra comma",,]',
|
||||
# http://json.org/JSON_checker/test/fail6.json
|
||||
# https://json.org/JSON_checker/test/fail6.json
|
||||
'[ , "<-- missing value"]',
|
||||
# http://json.org/JSON_checker/test/fail7.json
|
||||
# https://json.org/JSON_checker/test/fail7.json
|
||||
'["Comma after the close"],',
|
||||
# http://json.org/JSON_checker/test/fail8.json
|
||||
# https://json.org/JSON_checker/test/fail8.json
|
||||
'["Extra close"]]',
|
||||
# http://json.org/JSON_checker/test/fail9.json
|
||||
# https://json.org/JSON_checker/test/fail9.json
|
||||
'{"Extra comma": true,}',
|
||||
# http://json.org/JSON_checker/test/fail10.json
|
||||
# https://json.org/JSON_checker/test/fail10.json
|
||||
'{"Extra value after close": true} "misplaced quoted value"',
|
||||
# http://json.org/JSON_checker/test/fail11.json
|
||||
# https://json.org/JSON_checker/test/fail11.json
|
||||
'{"Illegal expression": 1 + 2}',
|
||||
# http://json.org/JSON_checker/test/fail12.json
|
||||
# https://json.org/JSON_checker/test/fail12.json
|
||||
'{"Illegal invocation": alert()}',
|
||||
# http://json.org/JSON_checker/test/fail13.json
|
||||
# https://json.org/JSON_checker/test/fail13.json
|
||||
'{"Numbers cannot have leading zeroes": 013}',
|
||||
# http://json.org/JSON_checker/test/fail14.json
|
||||
# https://json.org/JSON_checker/test/fail14.json
|
||||
'{"Numbers cannot be hex": 0x14}',
|
||||
# http://json.org/JSON_checker/test/fail15.json
|
||||
# https://json.org/JSON_checker/test/fail15.json
|
||||
'["Illegal backslash escape: \\x15"]',
|
||||
# http://json.org/JSON_checker/test/fail16.json
|
||||
# https://json.org/JSON_checker/test/fail16.json
|
||||
'[\\naked]',
|
||||
# http://json.org/JSON_checker/test/fail17.json
|
||||
# https://json.org/JSON_checker/test/fail17.json
|
||||
'["Illegal backslash escape: \\017"]',
|
||||
# http://json.org/JSON_checker/test/fail18.json
|
||||
# https://json.org/JSON_checker/test/fail18.json
|
||||
'[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]',
|
||||
# http://json.org/JSON_checker/test/fail19.json
|
||||
# https://json.org/JSON_checker/test/fail19.json
|
||||
'{"Missing colon" null}',
|
||||
# http://json.org/JSON_checker/test/fail20.json
|
||||
# https://json.org/JSON_checker/test/fail20.json
|
||||
'{"Double colon":: null}',
|
||||
# http://json.org/JSON_checker/test/fail21.json
|
||||
# https://json.org/JSON_checker/test/fail21.json
|
||||
'{"Comma instead of colon", null}',
|
||||
# http://json.org/JSON_checker/test/fail22.json
|
||||
# https://json.org/JSON_checker/test/fail22.json
|
||||
'["Colon instead of comma": false]',
|
||||
# http://json.org/JSON_checker/test/fail23.json
|
||||
# https://json.org/JSON_checker/test/fail23.json
|
||||
'["Bad value", truth]',
|
||||
# http://json.org/JSON_checker/test/fail24.json
|
||||
# https://json.org/JSON_checker/test/fail24.json
|
||||
"['single quote']",
|
||||
# http://json.org/JSON_checker/test/fail25.json
|
||||
# https://json.org/JSON_checker/test/fail25.json
|
||||
'["\ttab\tcharacter\tin\tstring\t"]',
|
||||
# http://json.org/JSON_checker/test/fail26.json
|
||||
# https://json.org/JSON_checker/test/fail26.json
|
||||
'["tab\\ character\\ in\\ string\\ "]',
|
||||
# http://json.org/JSON_checker/test/fail27.json
|
||||
# https://json.org/JSON_checker/test/fail27.json
|
||||
'["line\nbreak"]',
|
||||
# http://json.org/JSON_checker/test/fail28.json
|
||||
# https://json.org/JSON_checker/test/fail28.json
|
||||
'["line\\\nbreak"]',
|
||||
# http://json.org/JSON_checker/test/fail29.json
|
||||
# https://json.org/JSON_checker/test/fail29.json
|
||||
'[0e]',
|
||||
# http://json.org/JSON_checker/test/fail30.json
|
||||
# https://json.org/JSON_checker/test/fail30.json
|
||||
'[0e+]',
|
||||
# http://json.org/JSON_checker/test/fail31.json
|
||||
# https://json.org/JSON_checker/test/fail31.json
|
||||
'[0e+-1]',
|
||||
# http://json.org/JSON_checker/test/fail32.json
|
||||
# https://json.org/JSON_checker/test/fail32.json
|
||||
'{"Comma instead if closing brace": true,',
|
||||
# http://json.org/JSON_checker/test/fail33.json
|
||||
# https://json.org/JSON_checker/test/fail33.json
|
||||
'["mismatch"}',
|
||||
# http://code.google.com/p/simplejson/issues/detail?id=3
|
||||
# https://code.google.com/archive/p/simplejson/issues/3
|
||||
'["A\u001FZ control characters in string"]',
|
||||
]
|
||||
|
||||
@@ -90,7 +91,7 @@ class TestFail:
|
||||
except self.JSONDecodeError:
|
||||
pass
|
||||
else:
|
||||
self.fail("Expected failure for fail{0}.json: {1!r}".format(idx, doc))
|
||||
self.fail(f"Expected failure for fail{idx}.json: {doc!r}")
|
||||
|
||||
def test_non_string_keys_dict(self):
|
||||
data = {'a' : 1, (1, 2) : 2}
|
||||
@@ -144,11 +145,11 @@ class TestFail:
|
||||
('{"spam":[}', 'Expecting value', 9),
|
||||
('[42:', "Expecting ',' delimiter", 3),
|
||||
('[42 "spam"', "Expecting ',' delimiter", 4),
|
||||
('[42,]', 'Expecting value', 4),
|
||||
('[42,]', "Illegal trailing comma before end of array", 3),
|
||||
('{"spam":[42}', "Expecting ',' delimiter", 11),
|
||||
('["]', 'Unterminated string starting at', 1),
|
||||
('["spam":', "Expecting ',' delimiter", 7),
|
||||
('["spam",]', 'Expecting value', 8),
|
||||
('["spam",]', "Illegal trailing comma before end of array", 7),
|
||||
('{:', 'Expecting property name enclosed in double quotes', 1),
|
||||
('{,', 'Expecting property name enclosed in double quotes', 1),
|
||||
('{42', 'Expecting property name enclosed in double quotes', 1),
|
||||
@@ -160,7 +161,9 @@ class TestFail:
|
||||
('[{"spam":]', 'Expecting value', 9),
|
||||
('{"spam":42 "ham"', "Expecting ',' delimiter", 11),
|
||||
('[{"spam":42]', "Expecting ',' delimiter", 11),
|
||||
('{"spam":42,}', 'Expecting property name enclosed in double quotes', 11),
|
||||
('{"spam":42,}', "Illegal trailing comma before end of object", 10),
|
||||
('{"spam":42 , }', "Illegal trailing comma before end of object", 11),
|
||||
('[123 , ]', "Illegal trailing comma before end of array", 6),
|
||||
]
|
||||
for data, msg, idx in test_cases:
|
||||
with self.assertRaises(self.JSONDecodeError) as cm:
|
||||
@@ -217,10 +220,9 @@ class TestFail:
|
||||
(line, col, idx))
|
||||
|
||||
class TestPyFail(TestFail, PyTest): pass
|
||||
class TestCFail(TestFail, CTest): pass
|
||||
# TODO: RUSTPYTHON
|
||||
|
||||
class TestCFail(TestFail, CTest):
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_failures(self):
|
||||
super().test_failures()
|
||||
return super().test_failures()
|
||||
Vendored
+2
-1
@@ -26,7 +26,8 @@ class TestFloat:
|
||||
res = self.loads(out)
|
||||
self.assertEqual(len(res), 1)
|
||||
self.assertNotEqual(res[0], res[0])
|
||||
self.assertRaises(ValueError, self.dumps, [val], allow_nan=False)
|
||||
msg = f'Out of range float values are not JSON compliant: {val}'
|
||||
self.assertRaisesRegex(ValueError, msg, self.dumps, [val], allow_nan=False)
|
||||
|
||||
|
||||
class TestPyFloat(TestFloat, PyTest): pass
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
from test.test_json import PyTest, CTest
|
||||
|
||||
|
||||
# from http://json.org/JSON_checker/test/pass1.json
|
||||
# from https://json.org/JSON_checker/test/pass1.json
|
||||
JSON = r'''
|
||||
[
|
||||
"JSON Test Pattern pass1",
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
from test.test_json import PyTest, CTest
|
||||
|
||||
|
||||
# from http://json.org/JSON_checker/test/pass2.json
|
||||
# from https://json.org/JSON_checker/test/pass2.json
|
||||
JSON = r'''
|
||||
[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]
|
||||
'''
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
from test.test_json import PyTest, CTest
|
||||
|
||||
|
||||
# from http://json.org/JSON_checker/test/pass3.json
|
||||
# from https://json.org/JSON_checker/test/pass3.json
|
||||
JSON = r'''
|
||||
{
|
||||
"JSON Test Pattern pass3": {
|
||||
|
||||
Vendored
+4
-3
@@ -79,16 +79,17 @@ class TestRecursion:
|
||||
with support.infinite_recursion():
|
||||
self.loads('[' * 100000 + '1' + ']' * 100000)
|
||||
|
||||
@support.requires_resource('cpu')
|
||||
def test_highly_nested_objects_encoding(self):
|
||||
# See #12051
|
||||
l, d = [], {}
|
||||
for x in range(100000):
|
||||
l, d = [l], {'k':d}
|
||||
with self.assertRaises(RecursionError):
|
||||
with support.infinite_recursion():
|
||||
with support.infinite_recursion(5000):
|
||||
self.dumps(l)
|
||||
with self.assertRaises(RecursionError):
|
||||
with support.infinite_recursion():
|
||||
with support.infinite_recursion(5000):
|
||||
self.dumps(d)
|
||||
|
||||
def test_endless_recursion(self):
|
||||
@@ -99,7 +100,7 @@ class TestRecursion:
|
||||
return [o]
|
||||
|
||||
with self.assertRaises(RecursionError):
|
||||
with support.infinite_recursion():
|
||||
with support.infinite_recursion(1000):
|
||||
EndlessJSONEncoder(check_circular=False).encode(5j)
|
||||
|
||||
|
||||
|
||||
+11
-1
@@ -1,7 +1,7 @@
|
||||
import unittest
|
||||
import sys
|
||||
from test.test_json import PyTest, CTest
|
||||
|
||||
import unittest # XXX: RUSTPYTHON; importing to be able to skip tests
|
||||
|
||||
class TestScanstring:
|
||||
def test_scanstring(self):
|
||||
@@ -117,6 +117,11 @@ class TestScanstring:
|
||||
'"\\u012z"',
|
||||
'"\\u0x12"',
|
||||
'"\\u0X12"',
|
||||
'"\\u{0}"'.format("\uff10" * 4),
|
||||
'"\\u 123"',
|
||||
'"\\u-123"',
|
||||
'"\\u+123"',
|
||||
'"\\u1_23"',
|
||||
'"\\ud834\\"',
|
||||
'"\\ud834\\u"',
|
||||
'"\\ud834\\ud"',
|
||||
@@ -128,6 +133,11 @@ class TestScanstring:
|
||||
'"\\ud834\\udd2z"',
|
||||
'"\\ud834\\u0x20"',
|
||||
'"\\ud834\\u0X20"',
|
||||
'"\\ud834\\u{0}"'.format("\uff10" * 4),
|
||||
'"\\ud834\\u 123"',
|
||||
'"\\ud834\\u-123"',
|
||||
'"\\ud834\\u+123"',
|
||||
'"\\ud834\\u1_23"',
|
||||
]
|
||||
for s in bad_escapes:
|
||||
with self.assertRaises(self.JSONDecodeError, msg=s):
|
||||
|
||||
Vendored
+4
-3
@@ -1,6 +1,7 @@
|
||||
from test.test_json import CTest
|
||||
|
||||
import unittest
|
||||
import unittest # XXX: RUSTPYTHON; importing to be able to skip tests
|
||||
|
||||
|
||||
class BadBool:
|
||||
def __bool__(self):
|
||||
@@ -39,7 +40,7 @@ class TestEncode(CTest):
|
||||
b"\xCD\x7D\x3D\x4E\x12\x4C\xF9\x79\xD7\x52\xBA\x82\xF2\x27\x4A\x7D\xA0\xCA\x75",
|
||||
None)
|
||||
|
||||
# TODO: RUSTPYTHON, TypeError: 'NoneType' object is not callable
|
||||
# TODO: RUSTPYTHON; TypeError: 'NoneType' object is not callable
|
||||
@unittest.expectedFailure
|
||||
def test_bad_str_encoder(self):
|
||||
# Issue #31505: There shouldn't be an assertion failure in case
|
||||
@@ -73,7 +74,7 @@ class TestEncode(CTest):
|
||||
self.json.encoder.c_make_encoder(1, None, None, None, ': ', ', ',
|
||||
False, False, False)
|
||||
|
||||
# TODO: RUSTPYTHON, translate the encoder to Rust
|
||||
# TODO: RUSTPYTHON; ZeroDivisionError not raised by test
|
||||
@unittest.expectedFailure
|
||||
def test_bad_bool_args(self):
|
||||
def test(name):
|
||||
|
||||
Vendored
+1
@@ -10,6 +10,7 @@ from test.support import os_helper
|
||||
from test.support.script_helper import assert_python_ok
|
||||
|
||||
|
||||
@support.requires_subprocess()
|
||||
class TestTool(unittest.TestCase):
|
||||
data = """
|
||||
|
||||
|
||||
Vendored
+11
-5
@@ -1,8 +1,9 @@
|
||||
import unittest
|
||||
import codecs
|
||||
from collections import OrderedDict
|
||||
from test.test_json import PyTest, CTest
|
||||
|
||||
import unittest # XXX: RUSTPYTHON; importing to be able to skip tests
|
||||
|
||||
|
||||
class TestUnicode:
|
||||
# test_encoding1 and test_encoding2 from 2.x are irrelevant (only str
|
||||
@@ -21,12 +22,17 @@ class TestUnicode:
|
||||
def test_encoding5(self):
|
||||
u = '\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}'
|
||||
j = self.dumps(u, ensure_ascii=False)
|
||||
self.assertEqual(j, '"{0}"'.format(u))
|
||||
self.assertEqual(j, f'"{u}"')
|
||||
|
||||
def test_encoding6(self):
|
||||
u = '\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}'
|
||||
j = self.dumps([u], ensure_ascii=False)
|
||||
self.assertEqual(j, '["{0}"]'.format(u))
|
||||
self.assertEqual(j, f'["{u}"]')
|
||||
|
||||
def test_encoding7(self):
|
||||
u = '\N{GREEK SMALL LETTER ALPHA}\N{GREEK CAPITAL LETTER OMEGA}'
|
||||
j = self.dumps(u + "\n", ensure_ascii=False)
|
||||
self.assertEqual(j, f'"{u}\\n"')
|
||||
|
||||
def test_big_unicode_encode(self):
|
||||
u = '\U0001d120'
|
||||
@@ -35,13 +41,13 @@ class TestUnicode:
|
||||
|
||||
def test_big_unicode_decode(self):
|
||||
u = 'z\U0001d120x'
|
||||
self.assertEqual(self.loads('"' + u + '"'), u)
|
||||
self.assertEqual(self.loads(f'"{u}"'), u)
|
||||
self.assertEqual(self.loads('"z\\ud834\\udd20x"'), u)
|
||||
|
||||
def test_unicode_decode(self):
|
||||
for i in range(0, 0xd7ff):
|
||||
u = chr(i)
|
||||
s = '"\\u{0:04x}"'.format(i)
|
||||
s = f'"\\u{i:04x}"'
|
||||
self.assertEqual(self.loads(s), u)
|
||||
|
||||
def test_unicode_preservation(self):
|
||||
|
||||
Reference in new issue
Block a user