1 """Implementation of JSONDecoder
3 from __future__
import absolute_import
7 from .compat
import PY3, unichr
8 from .scanner
import make_scanner, JSONDecodeError
13 from ._speedups
import scanstring
23 __all__ = [
'JSONDecoder']
25 FLAGS = re.VERBOSE | re.MULTILINE | re.DOTALL
29 if sys.version_info < (2, 6):
30 _BYTES =
'7FF80000000000007FF0000000000000'.decode(
'hex')
31 nan, inf = struct.unpack(
'>dd', _BYTES)
46 STRINGCHUNK = re.compile(
r'(.*?)(["\\\x00-\x1f])', FLAGS)
48 '"':
u'"',
'\\':
u'\\',
'/':
u'/',
49 'b':
u'\b',
'f':
u'\f',
'n':
u'\n',
'r':
u'\r',
't':
u'\t',
52 DEFAULT_ENCODING =
"utf-8"
56 _b=BACKSLASH, _m=STRINGCHUNK.match, _join=u''.join,
57 _PY3=PY3, _maxunicode=sys.maxunicode):
58 """Scan the string s for a JSON string. End is the index of the
59 character in s after the quote that started the JSON string.
60 Unescapes all valid JSON string escape sequences and raises ValueError
61 on attempt to decode an invalid string. If strict is False then literal
62 control characters are allowed in the string.
64 Returns a tuple of the decoded string and the index of the character in s
65 after the end quote."""
67 encoding = DEFAULT_ENCODING
69 _append = chunks.append
75 "Unterminated string starting at", s, begin)
77 content, terminator = chunk.groups()
80 if not _PY3
and not isinstance(content, unicode):
81 content = unicode(content, encoding)
87 elif terminator !=
'\\':
89 msg =
"Invalid control character %r at"
98 "Unterminated string starting at", s, begin)
104 msg =
"Invalid \\X escape sequence %r"
109 msg =
"Invalid \\uXXXX escape sequence"
110 esc = s[end + 1:end + 5]
112 if len(esc) != 4
or escX ==
'x' or escX ==
'X':
122 if (_maxunicode > 65535
and
123 uni & 0xfc00 == 0xd800
and
124 s[end:end + 2] ==
'\\u'):
125 esc2 = s[end + 2:end + 6]
127 if len(esc2) == 4
and not (escX ==
'x' or escX ==
'X'):
132 if uni2 & 0xfc00 == 0xdc00:
133 uni = 0x10000 + (((uni - 0xd800) << 10) |
139 return _join(chunks), end
143 scanstring = c_scanstring
or py_scanstring
145 WHITESPACE = re.compile(
r'[ \t\n\r]*', FLAGS)
146 WHITESPACE_STR =
' \t\n\r'
149 def JSONObject(state, encoding, strict, scan_once, object_hook,
150 object_pairs_hook, memo=None,
151 _w=WHITESPACE.match, _ws=WHITESPACE_STR):
156 memo_get = memo.setdefault
160 nextchar = s[end:end + 1]
164 end = _w(s, end).end()
165 nextchar = s[end:end + 1]
168 if object_pairs_hook
is not None:
169 result = object_pairs_hook(pairs)
170 return result, end + 1
172 if object_hook
is not None:
173 pairs = object_hook(pairs)
174 return pairs, end + 1
175 elif nextchar !=
'"':
177 "Expecting property name enclosed in double quotes",
181 key, end =
scanstring(s, end, encoding, strict)
182 key = memo_get(key, key)
186 if s[end:end + 1] !=
':':
187 end = _w(s, end).end()
188 if s[end:end + 1] !=
':':
197 end = _w(s, end + 1).end()
201 value, end = scan_once(s, end)
202 pairs.append((key, value))
207 end = _w(s, end + 1).end()
215 elif nextchar !=
',':
224 end = _w(s, end + 1).end()
232 "Expecting property name enclosed in double quotes",
235 if object_pairs_hook
is not None:
236 result = object_pairs_hook(pairs)
239 if object_hook
is not None:
240 pairs = object_hook(pairs)
244 def JSONArray(state, scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR):
247 nextchar = s[end:end + 1]
249 end = _w(s, end + 1).end()
250 nextchar = s[end:end + 1]
253 return values, end + 1
256 _append = values.append
258 value, end = scan_once(s, end)
260 nextchar = s[end:end + 1]
262 end = _w(s, end + 1).end()
263 nextchar = s[end:end + 1]
267 elif nextchar !=
',':
274 end = _w(s, end + 1).end()
282 """Simple JSON <http://json.org> decoder
284 Performs the following translations in decoding by default:
286 +---------------+-------------------+
288 +===============+===================+
290 +---------------+-------------------+
292 +---------------+-------------------+
293 | string | str, unicode |
294 +---------------+-------------------+
295 | number (int) | int, long |
296 +---------------+-------------------+
297 | number (real) | float |
298 +---------------+-------------------+
300 +---------------+-------------------+
302 +---------------+-------------------+
304 +---------------+-------------------+
306 It also understands ``NaN``, ``Infinity``, and ``-Infinity`` as
307 their corresponding ``float`` values, which is outside the JSON spec.
311 def __init__(self, encoding=None, object_hook=None, parse_float=None,
312 parse_int=None, parse_constant=None, strict=True,
313 object_pairs_hook=None):
316 :class:`str` 对象由此实例解码 (``'utf-8'`` by
317 默认)。它在解码 unicode 对象时不起作用。
319 请注意,目前只有作为 ASCII 超集的编码才有效,
320 其他编码的字符串应该作为 unicode 传入。
322 *object_hook*,如果指定,将使用每个的结果调用
323 解码后的 JSON 对象及其返回值将用于代替
324 给定:class:`dict`。这可用于提供自定义
325 反序列化(例如支持 JSON-RPC 类提示)。
327 *object_pairs_hook* 是一个可选函数,将被调用
329 将使用 *object_pairs_hook* 的返回值代替
330 :class:`字典`。此功能可用于实现自定义解码器
332 例如,:func:`collections.OrderedDict` 会记住
333 插入)。如果还定义了 *object_hook*,则 *object_pairs_hook*
336 *parse_float*,如果指定,将使用每个的字符串调用
337 要解码的 JSON 浮点数。默认情况下,这相当于
338 ``浮动(num_str)``。这可用于使用其他数据类型或解析器
339 对于 JSON 浮点数(例如 :class:`decimal.Decimal`)。
341 * parse_int *(如果指定)将使用每个字符串
342 要解码的 JSON int。默认情况下,这相当于
343 ``int(num_str)``。这可用于使用其他数据类型或解析器
344 对于 JSON 整数(例如 :class:`float`)。
346 *parse_constant*,如果指定,将使用以下之一调用
347 以下字符串:“-Infinity”、“Infinity”、“NaN”。这
348 如果无效的JSON数字为,则可用于引发异常
353 ``True`` 表示未转义的控制字符是解析错误,如果
354 ``False`` 那么字符串中将允许使用控制字符
358 encoding = DEFAULT_ENCODING
372 def decode(self, s, _w=WHITESPACE.match, _PY3=PY3):
373 """返回 ``s`` 的 Python 表示(一个 ``str`` 或 ``unicode``
378 if _PY3
and isinstance(s, bytes):
381 end = _w(s, end).end()
386 def raw_decode(self, s, idx=0, _w=WHITESPACE.match, _PY3=PY3):
388 从一个str或unicode解码一个 JSON 文档
390 以 JSON 文档开头)并返回 Python 的 2 元组
394 可选地,``idx`` 可用于指定 ``s`` 中的偏移量
396 这可用于从字符串解码 JSON 文档,该字符串可能
401 if _PY3
and not isinstance(s, str):
402 raise TypeError(
"Input string must be text, not bytes")
408 elif ord0 == 0xef
and s[idx:idx + 3] ==
'\xef\xbb\xbf':
410 return self.
scan_once(s, idx=_w(s, idx).end())