mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-29 03:04:38 +08:00
* Sync Python 3.15 core library tests and repr type errors Synchronize ten selected library paths from CPython 3.15.0 at d220409a13b77de7a6c30abe16ea90db01528edc using the canonical updater, retaining existing RustPython adapters and failure markers. Match generic __repr__ invalid-result errors to the qualified type-name format required by the canonical ExceptionGroup regression, preserving string results and exceptions raised by the implementation. Implementation, source review, and validation were AI-assisted. The model version identifier is unavailable; automated checks are not human verification. Bounded validation covers 43 passes and one canonical skip, not the full repository suites. Assisted-by: OpenAI Codex:model version unavailable * Preserve original escape decoder consumed length after callbacks Keep the original input length as consumed after successful unicode-escape and raw-unicode-escape decoding, including error-handler input replacement. Only report the current cursor when a non-final decode stops on incomplete input, matching CPython's codec wrappers and incomplete exits. Fix the canonical Unicode escape mutation regression that failed CI on Linux, macOS and Windows. Preserve all Lib tests and existing assertions. Bounded Linux validation: 55 passes and one canonical skip, CLI build and strict common/VM Clippy passed. Full repository suites were not run. Implementation, source review, and validation were AI-assisted. The model version identifier is unavailable; automated checks are not human verification. Assisted-by: OpenAI Codex:model version unavailable --------- Co-authored-by: youknowdot <336763669+youknowdot@users.noreply.github.com>
157 lines
5.0 KiB
Python
Vendored
157 lines
5.0 KiB
Python
Vendored
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):
|
|
scanstring = self.json.decoder.scanstring
|
|
self.assertEqual(
|
|
scanstring('"z\U0001d120x"', 1, True),
|
|
('z\U0001d120x', 5))
|
|
|
|
self.assertEqual(
|
|
scanstring('"\\u007b"', 1, True),
|
|
('{', 8))
|
|
|
|
self.assertEqual(
|
|
scanstring('"A JSON payload should be an object or array, not a string."', 1, True),
|
|
('A JSON payload should be an object or array, not a string.', 60))
|
|
|
|
self.assertEqual(
|
|
scanstring('["Unclosed array"', 2, True),
|
|
('Unclosed array', 17))
|
|
|
|
self.assertEqual(
|
|
scanstring('["extra comma",]', 2, True),
|
|
('extra comma', 14))
|
|
|
|
self.assertEqual(
|
|
scanstring('["double extra comma",,]', 2, True),
|
|
('double extra comma', 21))
|
|
|
|
self.assertEqual(
|
|
scanstring('["Comma after the close"],', 2, True),
|
|
('Comma after the close', 24))
|
|
|
|
self.assertEqual(
|
|
scanstring('["Extra close"]]', 2, True),
|
|
('Extra close', 14))
|
|
|
|
self.assertEqual(
|
|
scanstring('{"Extra comma": true,}', 2, True),
|
|
('Extra comma', 14))
|
|
|
|
self.assertEqual(
|
|
scanstring('{"Extra value after close": true} "misplaced quoted value"', 2, True),
|
|
('Extra value after close', 26))
|
|
|
|
self.assertEqual(
|
|
scanstring('{"Illegal expression": 1 + 2}', 2, True),
|
|
('Illegal expression', 21))
|
|
|
|
self.assertEqual(
|
|
scanstring('{"Illegal invocation": alert()}', 2, True),
|
|
('Illegal invocation', 21))
|
|
|
|
self.assertEqual(
|
|
scanstring('{"Numbers cannot have leading zeroes": 013}', 2, True),
|
|
('Numbers cannot have leading zeroes', 37))
|
|
|
|
self.assertEqual(
|
|
scanstring('{"Numbers cannot be hex": 0x14}', 2, True),
|
|
('Numbers cannot be hex', 24))
|
|
|
|
self.assertEqual(
|
|
scanstring('[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]', 21, True),
|
|
('Too deep', 30))
|
|
|
|
self.assertEqual(
|
|
scanstring('{"Missing colon" null}', 2, True),
|
|
('Missing colon', 16))
|
|
|
|
self.assertEqual(
|
|
scanstring('{"Double colon":: null}', 2, True),
|
|
('Double colon', 15))
|
|
|
|
self.assertEqual(
|
|
scanstring('{"Comma instead of colon", null}', 2, True),
|
|
('Comma instead of colon', 25))
|
|
|
|
self.assertEqual(
|
|
scanstring('["Colon instead of comma": false]', 2, True),
|
|
('Colon instead of comma', 25))
|
|
|
|
self.assertEqual(
|
|
scanstring('["Bad value", truth]', 2, True),
|
|
('Bad value', 12))
|
|
|
|
def test_surrogates(self):
|
|
scanstring = self.json.decoder.scanstring
|
|
def assertScan(given, expect):
|
|
self.assertEqual(scanstring(given, 1, True),
|
|
(expect, len(given)))
|
|
|
|
assertScan('"z\\ud834\\u0079x"', 'z\ud834yx')
|
|
assertScan('"z\\ud834\\udd20x"', 'z\U0001d120x')
|
|
assertScan('"z\\ud834\\ud834\\udd20x"', 'z\ud834\U0001d120x')
|
|
assertScan('"z\\ud834x"', 'z\ud834x')
|
|
assertScan('"z\\ud834\udd20x12345"', 'z\ud834\udd20x12345')
|
|
assertScan('"z\\udd20x"', 'z\udd20x')
|
|
assertScan('"z\ud834\udd20x"', 'z\ud834\udd20x')
|
|
assertScan('"z\ud834\\udd20x"', 'z\ud834\udd20x')
|
|
assertScan('"z\ud834x"', 'z\ud834x')
|
|
|
|
def test_bad_escapes(self):
|
|
scanstring = self.json.decoder.scanstring
|
|
bad_escapes = [
|
|
'"\\"',
|
|
'"\\x"',
|
|
'"\\u"',
|
|
'"\\u0"',
|
|
'"\\u01"',
|
|
'"\\u012"',
|
|
'"\\uz012"',
|
|
'"\\u0z12"',
|
|
'"\\u01z2"',
|
|
'"\\u012z"',
|
|
'"\\u0x12"',
|
|
'"\\u0X12"',
|
|
'"\\u{0}"'.format("\uff10" * 4),
|
|
'"\\u 123"',
|
|
'"\\u-123"',
|
|
'"\\u+123"',
|
|
'"\\u1_23"',
|
|
'"\\ud834\\"',
|
|
'"\\ud834\\u"',
|
|
'"\\ud834\\ud"',
|
|
'"\\ud834\\udd"',
|
|
'"\\ud834\\udd2"',
|
|
'"\\ud834\\uzdd2"',
|
|
'"\\ud834\\udzd2"',
|
|
'"\\ud834\\uddz2"',
|
|
'"\\ud834\\udd2z"',
|
|
'"\\ud834\\u0x20"',
|
|
'"\\ud834\\u0X20"',
|
|
'"\\ud834\\u{0}"'.format("\uff10" * 4),
|
|
'"\\ud834\\u 123"',
|
|
'"\\ud834\\u-123"',
|
|
'"\\ud834\\u+123"',
|
|
'"\\ud834\\u1_23"',
|
|
# Truncated or non-hex \uXXXX escape at end of input.
|
|
'"\\u004',
|
|
'"\\uXYZW',
|
|
]
|
|
for s in bad_escapes:
|
|
with self.assertRaises(self.JSONDecodeError, msg=s):
|
|
scanstring(s, 1, True)
|
|
|
|
def test_overflow(self):
|
|
with self.assertRaises(OverflowError):
|
|
self.json.decoder.scanstring("xxx", sys.maxsize+1)
|
|
|
|
|
|
class TestPyScanstring(TestScanstring, PyTest): pass
|
|
class TestCScanstring(TestScanstring, CTest): pass
|