simplejson.py 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786
  1. '''
  2. PyS60 1.4.x compatible simplejson
  3. 2009 Created by Aapo Rista (ispired by Marcelo Barros) from
  4. simplejson 2.0.x with an ugly shell script. (But hey, it works!)
  5. '''
  6. from __future__ import generators
  7. basestring = (unicode, str)
  8. __author__ = 'Bob Ippolito <bob@redivi.com>'
  9. import re
  10. import struct
  11. import sys
  12. try:
  13. from simplejson._speedups import scanstring as c_scanstring
  14. except ImportError:
  15. c_scanstring = None
  16. FLAGS = re.VERBOSE | re.MULTILINE | re.DOTALL
  17. def _floatconstants():
  18. _BYTES = '7FF80000000000007FF0000000000000'.decode('hex')
  19. if sys.byteorder != 'big':
  20. _BYTES = "00008FF70000000000000FF700000000".decode("hex")
  21. nan, inf = struct.unpack('dd', _BYTES)
  22. return nan, inf, -inf
  23. NaN, PosInf, NegInf = _floatconstants()
  24. def linecol(doc, pos):
  25. lineno = doc.count('\n', 0, pos) + 1
  26. if lineno == 1:
  27. colno = pos
  28. else:
  29. colno = pos - doc.rindex('\n', 0, pos)
  30. return lineno, colno
  31. def errmsg(msg, doc, pos, end=None):
  32. # Note that this function is called from _speedups
  33. lineno, colno = linecol(doc, pos)
  34. if end is None:
  35. #fmt = '{0}: line {1} column {2} (char {3})'
  36. #return fmt.format(msg, lineno, colno, pos)
  37. fmt = '%s: line %d column %d (char %d)'
  38. return fmt % (msg, lineno, colno, pos)
  39. endlineno, endcolno = linecol(doc, end)
  40. #fmt = '{0}: line {1} column {2} - line {3} column {4} (char {5} - {6})'
  41. #return fmt.format(msg, lineno, colno, endlineno, endcolno, pos, end)
  42. fmt = '%s: line %d column %d - line %d column %d (char %d - %d)'
  43. return fmt % (msg, lineno, colno, endlineno, endcolno, pos, end)
  44. _CONSTANTS = {
  45. '-Infinity': NegInf,
  46. 'Infinity': PosInf,
  47. 'NaN': NaN,
  48. }
  49. STRINGCHUNK = re.compile(r'(.*?)(["\\\x00-\x1f])', FLAGS)
  50. BACKSLASH = {
  51. '"': u'"', '\\': u'\\', '/': u'/',
  52. 'b': u'\b', 'f': u'\f', 'n': u'\n', 'r': u'\r', 't': u'\t',
  53. }
  54. DEFAULT_ENCODING = "utf-8"
  55. def py_scanstring(s, end, encoding=None, strict=True, _b=BACKSLASH, _m=STRINGCHUNK.match):
  56. if encoding is None:
  57. encoding = DEFAULT_ENCODING
  58. chunks = []
  59. _append = chunks.append
  60. begin = end - 1
  61. while 1:
  62. chunk = _m(s, end)
  63. if chunk is None:
  64. raise ValueError(
  65. errmsg("Unterminated string starting at", s, begin))
  66. end = chunk.end()
  67. content, terminator = chunk.groups()
  68. # Content is contains zero or more unescaped string characters
  69. if content:
  70. if not isinstance(content, unicode):
  71. content = unicode(content, encoding)
  72. _append(content)
  73. # Terminator is the end of string, a literal control character,
  74. # or a backslash denoting that an escape sequence follows
  75. if terminator == '"':
  76. break
  77. elif terminator != '\\':
  78. if strict:
  79. msg = "Invalid control character %r at" % (terminator,)
  80. #msg = "Invalid control character {0!r} at".format(terminator)
  81. raise ValueError(errmsg(msg, s, end))
  82. else:
  83. _append(terminator)
  84. continue
  85. try:
  86. esc = s[end]
  87. except IndexError:
  88. raise ValueError(
  89. errmsg("Unterminated string starting at", s, begin))
  90. # If not a unicode escape sequence, must be in the lookup table
  91. if esc != 'u':
  92. try:
  93. char = _b[esc]
  94. except KeyError:
  95. msg = "Invalid \\escape: " + repr(esc)
  96. raise ValueError(errmsg(msg, s, end))
  97. end += 1
  98. else:
  99. # Unicode escape sequence
  100. esc = s[end + 1:end + 5]
  101. next_end = end + 5
  102. if len(esc) != 4:
  103. msg = "Invalid \\uXXXX escape"
  104. raise ValueError(errmsg(msg, s, end))
  105. uni = int(esc, 16)
  106. # Check for surrogate pair on UCS-4 systems
  107. if 0xd800 <= uni <= 0xdbff and sys.maxunicode > 65535:
  108. msg = "Invalid \\uXXXX\\uXXXX surrogate pair"
  109. if not s[end + 5:end + 7] == '\\u':
  110. raise ValueError(errmsg(msg, s, end))
  111. esc2 = s[end + 7:end + 11]
  112. if len(esc2) != 4:
  113. raise ValueError(errmsg(msg, s, end))
  114. uni2 = int(esc2, 16)
  115. uni = 0x10000 + (((uni - 0xd800) << 10) | (uni2 - 0xdc00))
  116. next_end += 6
  117. char = unichr(uni)
  118. end = next_end
  119. # Append the unescaped character
  120. _append(char)
  121. return u''.join(chunks), end
  122. # Use speedup if available
  123. scanstring = c_scanstring or py_scanstring
  124. WHITESPACE = re.compile(r'[ \t\n\r]*', FLAGS)
  125. WHITESPACE_STR = ' \t\n\r'
  126. def JSONObject((s, end), encoding, strict, scan_once, object_hook, _w=WHITESPACE.match, _ws=WHITESPACE_STR):
  127. pairs = {}
  128. # Use a slice to prevent IndexError from being raised, the following
  129. # check will raise a more specific ValueError if the string is empty
  130. nextchar = s[end:end + 1]
  131. # Normally we expect nextchar == '"'
  132. if nextchar != '"':
  133. if nextchar in _ws:
  134. end = _w(s, end).end()
  135. nextchar = s[end:end + 1]
  136. # Trivial empty object
  137. if nextchar == '}':
  138. return pairs, end + 1
  139. elif nextchar != '"':
  140. raise ValueError(errmsg("Expecting property name", s, end))
  141. end += 1
  142. while True:
  143. key, end = scanstring(s, end, encoding, strict)
  144. # To skip some function call overhead we optimize the fast paths where
  145. # the JSON key separator is ": " or just ":".
  146. if s[end:end + 1] != ':':
  147. end = _w(s, end).end()
  148. if s[end:end + 1] != ':':
  149. raise ValueError(errmsg("Expecting : delimiter", s, end))
  150. end += 1
  151. try:
  152. if s[end] in _ws:
  153. end += 1
  154. if s[end] in _ws:
  155. end = _w(s, end + 1).end()
  156. except IndexError:
  157. pass
  158. try:
  159. value, end = scan_once(s, end)
  160. except StopIteration:
  161. raise ValueError(errmsg("Expecting object", s, end))
  162. pairs[key] = value
  163. try:
  164. nextchar = s[end]
  165. if nextchar in _ws:
  166. end = _w(s, end + 1).end()
  167. nextchar = s[end]
  168. except IndexError:
  169. nextchar = ''
  170. end += 1
  171. if nextchar == '}':
  172. break
  173. elif nextchar != ',':
  174. raise ValueError(errmsg("Expecting , delimiter", s, end - 1))
  175. try:
  176. nextchar = s[end]
  177. if nextchar in _ws:
  178. end += 1
  179. nextchar = s[end]
  180. if nextchar in _ws:
  181. end = _w(s, end + 1).end()
  182. nextchar = s[end]
  183. except IndexError:
  184. nextchar = ''
  185. end += 1
  186. if nextchar != '"':
  187. raise ValueError(errmsg("Expecting property name", s, end - 1))
  188. if object_hook is not None:
  189. pairs = object_hook(pairs)
  190. return pairs, end
  191. def JSONArray((s, end), scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR):
  192. values = []
  193. nextchar = s[end:end + 1]
  194. if nextchar in _ws:
  195. end = _w(s, end + 1).end()
  196. nextchar = s[end:end + 1]
  197. # Look-ahead for trivial empty array
  198. if nextchar == ']':
  199. return values, end + 1
  200. _append = values.append
  201. while True:
  202. try:
  203. value, end = scan_once(s, end)
  204. except StopIteration:
  205. raise ValueError(errmsg("Expecting object", s, end))
  206. _append(value)
  207. nextchar = s[end:end + 1]
  208. if nextchar in _ws:
  209. end = _w(s, end + 1).end()
  210. nextchar = s[end:end + 1]
  211. end += 1
  212. if nextchar == ']':
  213. break
  214. elif nextchar != ',':
  215. raise ValueError(errmsg("Expecting , delimiter", s, end))
  216. try:
  217. if s[end] in _ws:
  218. end += 1
  219. if s[end] in _ws:
  220. end = _w(s, end + 1).end()
  221. except IndexError:
  222. pass
  223. return values, end
  224. class JSONDecoder(object):
  225. def __init__(self, encoding=None, object_hook=None, parse_float=None,
  226. parse_int=None, parse_constant=None, strict=True):
  227. self.encoding = encoding
  228. self.object_hook = object_hook
  229. self.parse_float = parse_float or float
  230. self.parse_int = parse_int or int
  231. self.parse_constant = parse_constant or _CONSTANTS.__getitem__
  232. self.strict = strict
  233. self.parse_object = JSONObject
  234. self.parse_array = JSONArray
  235. self.parse_string = scanstring
  236. self.scan_once = make_scanner(self)
  237. def decode(self, s, _w=WHITESPACE.match):
  238. obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  239. end = _w(s, end).end()
  240. if end != len(s):
  241. raise ValueError(errmsg("Extra data", s, end, len(s)))
  242. return obj
  243. def raw_decode(self, s, idx=0):
  244. try:
  245. obj, end = self.scan_once(s, idx)
  246. except StopIteration:
  247. raise ValueError("No JSON object could be decoded")
  248. return obj, end
  249. try:
  250. from simplejson._speedups import encode_basestring_ascii as c_encode_basestring_ascii
  251. except ImportError:
  252. c_encode_basestring_ascii = None
  253. try:
  254. from simplejson._speedups import make_encoder as c_make_encoder
  255. except ImportError:
  256. c_make_encoder = None
  257. ESCAPE = re.compile(r'[\x00-\x1f\\"\b\f\n\r\t]')
  258. ESCAPE_ASCII = re.compile(r'([\\"]|[^\ -~])')
  259. HAS_UTF8 = re.compile(r'[\x80-\xff]')
  260. ESCAPE_DCT = {
  261. '\\': '\\\\',
  262. '"': '\\"',
  263. '\b': '\\b',
  264. '\f': '\\f',
  265. '\n': '\\n',
  266. '\r': '\\r',
  267. '\t': '\\t',
  268. }
  269. for i in range(0x20):
  270. #ESCAPE_DCT.setdefault(chr(i), '\\u{0:04x}'.format(i))
  271. ESCAPE_DCT.setdefault(chr(i), '\\u%04x' % (i,))
  272. # Assume this produces an infinity on all machines (probably not guaranteed)
  273. INFINITY = float('1e66666')
  274. FLOAT_REPR = repr
  275. def encode_basestring(s):
  276. def replace(match):
  277. return ESCAPE_DCT[match.group(0)]
  278. return '"' + ESCAPE.sub(replace, s) + '"'
  279. def py_encode_basestring_ascii(s):
  280. if isinstance(s, str) and HAS_UTF8.search(s) is not None:
  281. s = s.decode('utf-8')
  282. def replace(match):
  283. s = match.group(0)
  284. try:
  285. return ESCAPE_DCT[s]
  286. except KeyError:
  287. n = ord(s)
  288. if n < 0x10000:
  289. #return '\\u{0:04x}'.format(n)
  290. return '\\u%04x' % (n,)
  291. else:
  292. # surrogate pair
  293. n -= 0x10000
  294. s1 = 0xd800 | ((n >> 10) & 0x3ff)
  295. s2 = 0xdc00 | (n & 0x3ff)
  296. #return '\\u{0:04x}\\u{1:04x}'.format(s1, s2)
  297. return '\\u%04x\\u%04x' % (s1, s2)
  298. return '"' + str(ESCAPE_ASCII.sub(replace, s)) + '"'
  299. encode_basestring_ascii = c_encode_basestring_ascii or py_encode_basestring_ascii
  300. class JSONEncoder(object):
  301. item_separator = ', '
  302. key_separator = ': '
  303. def __init__(self, skipkeys=False, ensure_ascii=True,
  304. check_circular=True, allow_nan=True, sort_keys=False,
  305. indent=None, separators=None, encoding='utf-8', default=None):
  306. self.skipkeys = skipkeys
  307. self.ensure_ascii = ensure_ascii
  308. self.check_circular = check_circular
  309. self.allow_nan = allow_nan
  310. self.sort_keys = sort_keys
  311. self.indent = indent
  312. if separators is not None:
  313. self.item_separator, self.key_separator = separators
  314. if default is not None:
  315. self.default = default
  316. self.encoding = encoding
  317. def default(self, o):
  318. raise TypeError(repr(o) + " is not JSON serializable")
  319. def encode(self, o):
  320. # This is for extremely simple cases and benchmarks.
  321. if isinstance(o, basestring):
  322. if isinstance(o, str):
  323. _encoding = self.encoding
  324. if (_encoding is not None
  325. and not (_encoding == 'utf-8')):
  326. o = o.decode(_encoding)
  327. if self.ensure_ascii:
  328. return encode_basestring_ascii(o)
  329. else:
  330. return encode_basestring(o)
  331. # This doesn't pass the iterator directly to ''.join() because the
  332. # exceptions aren't as detailed. The list call should be roughly
  333. # equivalent to the PySequence_Fast that ''.join() would do.
  334. chunks = self.iterencode(o, _one_shot=True)
  335. if not isinstance(chunks, (list, tuple)):
  336. chunks = list(chunks)
  337. return ''.join(chunks)
  338. def iterencode(self, o, _one_shot=False):
  339. if self.check_circular:
  340. markers = {}
  341. else:
  342. markers = None
  343. if self.ensure_ascii:
  344. _encoder = encode_basestring_ascii
  345. else:
  346. _encoder = encode_basestring
  347. if self.encoding != 'utf-8':
  348. def _encoder(o, _orig_encoder=_encoder, _encoding=self.encoding):
  349. if isinstance(o, str):
  350. o = o.decode(_encoding)
  351. return _orig_encoder(o)
  352. def floatstr(o, allow_nan=self.allow_nan, _repr=FLOAT_REPR, _inf=INFINITY, _neginf=-INFINITY):
  353. # Check for specials. Note that this type of test is processor- and/or
  354. # platform-specific, so do tests which don't depend on the internals.
  355. if o != o:
  356. text = 'NaN'
  357. elif o == _inf:
  358. text = 'Infinity'
  359. elif o == _neginf:
  360. text = '-Infinity'
  361. else:
  362. return _repr(o)
  363. if not allow_nan:
  364. raise ValueError(
  365. "Out of range float values are not JSON compliant: " +
  366. repr(o))
  367. return text
  368. if _one_shot and c_make_encoder is not None and not self.indent and not self.sort_keys:
  369. _iterencode = c_make_encoder(
  370. markers, self.default, _encoder, self.indent,
  371. self.key_separator, self.item_separator, self.sort_keys,
  372. self.skipkeys, self.allow_nan)
  373. else:
  374. _iterencode = _make_iterencode(
  375. markers, self.default, _encoder, self.indent, floatstr,
  376. self.key_separator, self.item_separator, self.sort_keys,
  377. self.skipkeys, _one_shot)
  378. return _iterencode(o, 0)
  379. def _make_iterencode(markers, _default, _encoder, _indent, _floatstr, _key_separator, _item_separator, _sort_keys, _skipkeys, _one_shot,
  380. ## HACK: hand-optimized bytecode; turn globals into locals
  381. False=False,
  382. True=True,
  383. ValueError=ValueError,
  384. basestring=basestring,
  385. dict=dict,
  386. float=float,
  387. id=id,
  388. int=int,
  389. isinstance=isinstance,
  390. list=list,
  391. long=long,
  392. str=str,
  393. tuple=tuple,
  394. ):
  395. def _iterencode_list(lst, _current_indent_level):
  396. if not lst:
  397. yield '[]'
  398. return
  399. if markers is not None:
  400. markerid = id(lst)
  401. if markerid in markers:
  402. raise ValueError("Circular reference detected")
  403. markers[markerid] = lst
  404. buf = '['
  405. if _indent is not None:
  406. _current_indent_level += 1
  407. newline_indent = '\n' + (' ' * (_indent * _current_indent_level))
  408. separator = _item_separator + newline_indent
  409. buf += newline_indent
  410. else:
  411. newline_indent = None
  412. separator = _item_separator
  413. first = True
  414. for value in lst:
  415. if first:
  416. first = False
  417. else:
  418. buf = separator
  419. if isinstance(value, basestring):
  420. yield buf + _encoder(value)
  421. elif value is None:
  422. yield buf + 'null'
  423. elif value is True:
  424. yield buf + 'true'
  425. elif value is False:
  426. yield buf + 'false'
  427. elif isinstance(value, (int, long)):
  428. yield buf + str(value)
  429. elif isinstance(value, float):
  430. yield buf + _floatstr(value)
  431. else:
  432. yield buf
  433. if isinstance(value, (list, tuple)):
  434. chunks = _iterencode_list(value, _current_indent_level)
  435. elif isinstance(value, dict):
  436. chunks = _iterencode_dict(value, _current_indent_level)
  437. else:
  438. chunks = _iterencode(value, _current_indent_level)
  439. for chunk in chunks:
  440. yield chunk
  441. if newline_indent is not None:
  442. _current_indent_level -= 1
  443. yield '\n' + (' ' * (_indent * _current_indent_level))
  444. yield ']'
  445. if markers is not None:
  446. del markers[markerid]
  447. def _iterencode_dict(dct, _current_indent_level):
  448. if not dct:
  449. yield '{}'
  450. return
  451. if markers is not None:
  452. markerid = id(dct)
  453. if markerid in markers:
  454. raise ValueError("Circular reference detected")
  455. markers[markerid] = dct
  456. yield '{'
  457. if _indent is not None:
  458. _current_indent_level += 1
  459. newline_indent = '\n' + (' ' * (_indent * _current_indent_level))
  460. item_separator = _item_separator + newline_indent
  461. yield newline_indent
  462. else:
  463. newline_indent = None
  464. item_separator = _item_separator
  465. first = True
  466. if _sort_keys:
  467. items = dct.items()
  468. items.sort(key=lambda kv: kv[0])
  469. else:
  470. items = dct.iteritems()
  471. for key, value in items:
  472. if isinstance(key, basestring):
  473. pass
  474. # JavaScript is weakly typed for these, so it makes sense to
  475. # also allow them. Many encoders seem to do something like this.
  476. elif isinstance(key, float):
  477. key = _floatstr(key)
  478. elif key is True:
  479. key = 'true'
  480. elif key is False:
  481. key = 'false'
  482. elif key is None:
  483. key = 'null'
  484. elif isinstance(key, (int, long)):
  485. key = str(key)
  486. elif _skipkeys:
  487. continue
  488. else:
  489. raise TypeError("key " + repr(key) + " is not a string")
  490. if first:
  491. first = False
  492. else:
  493. yield item_separator
  494. yield _encoder(key)
  495. yield _key_separator
  496. if isinstance(value, basestring):
  497. yield _encoder(value)
  498. elif value is None:
  499. yield 'null'
  500. elif value is True:
  501. yield 'true'
  502. elif value is False:
  503. yield 'false'
  504. elif isinstance(value, (int, long)):
  505. yield str(value)
  506. elif isinstance(value, float):
  507. yield _floatstr(value)
  508. else:
  509. if isinstance(value, (list, tuple)):
  510. chunks = _iterencode_list(value, _current_indent_level)
  511. elif isinstance(value, dict):
  512. chunks = _iterencode_dict(value, _current_indent_level)
  513. else:
  514. chunks = _iterencode(value, _current_indent_level)
  515. for chunk in chunks:
  516. yield chunk
  517. if newline_indent is not None:
  518. _current_indent_level -= 1
  519. yield '\n' + (' ' * (_indent * _current_indent_level))
  520. yield '}'
  521. if markers is not None:
  522. del markers[markerid]
  523. def _iterencode(o, _current_indent_level):
  524. if isinstance(o, basestring):
  525. yield _encoder(o)
  526. elif o is None:
  527. yield 'null'
  528. elif o is True:
  529. yield 'true'
  530. elif o is False:
  531. yield 'false'
  532. elif isinstance(o, (int, long)):
  533. yield str(o)
  534. elif isinstance(o, float):
  535. yield _floatstr(o)
  536. elif isinstance(o, (list, tuple)):
  537. for chunk in _iterencode_list(o, _current_indent_level):
  538. yield chunk
  539. elif isinstance(o, dict):
  540. for chunk in _iterencode_dict(o, _current_indent_level):
  541. yield chunk
  542. else:
  543. if markers is not None:
  544. markerid = id(o)
  545. if markerid in markers:
  546. raise ValueError("Circular reference detected")
  547. markers[markerid] = o
  548. o = _default(o)
  549. for chunk in _iterencode(o, _current_indent_level):
  550. yield chunk
  551. if markers is not None:
  552. del markers[markerid]
  553. return _iterencode
  554. try:
  555. from simplejson._speedups import make_scanner as c_make_scanner
  556. except ImportError:
  557. c_make_scanner = None
  558. NUMBER_RE = re.compile(
  559. r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?',
  560. (re.VERBOSE | re.MULTILINE | re.DOTALL))
  561. def py_make_scanner(context):
  562. parse_object = context.parse_object
  563. parse_array = context.parse_array
  564. parse_string = context.parse_string
  565. match_number = NUMBER_RE.match
  566. encoding = context.encoding
  567. strict = context.strict
  568. parse_float = context.parse_float
  569. parse_int = context.parse_int
  570. parse_constant = context.parse_constant
  571. object_hook = context.object_hook
  572. def _scan_once(string, idx):
  573. try:
  574. nextchar = string[idx]
  575. except IndexError:
  576. raise StopIteration
  577. if nextchar == '"':
  578. return parse_string(string, idx + 1, encoding, strict)
  579. elif nextchar == '{':
  580. return parse_object((string, idx + 1), encoding, strict, _scan_once, object_hook)
  581. elif nextchar == '[':
  582. return parse_array((string, idx + 1), _scan_once)
  583. elif nextchar == 'n' and string[idx:idx + 4] == 'null':
  584. return None, idx + 4
  585. elif nextchar == 't' and string[idx:idx + 4] == 'true':
  586. return True, idx + 4
  587. elif nextchar == 'f' and string[idx:idx + 5] == 'false':
  588. return False, idx + 5
  589. m = match_number(string, idx)
  590. if m is not None:
  591. integer, frac, exp = m.groups()
  592. if frac or exp:
  593. res = parse_float(integer + (frac or '') + (exp or ''))
  594. else:
  595. res = parse_int(integer)
  596. return res, m.end()
  597. elif nextchar == 'N' and string[idx:idx + 3] == 'NaN':
  598. return parse_constant('NaN'), idx + 3
  599. elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity':
  600. return parse_constant('Infinity'), idx + 8
  601. elif nextchar == '-' and string[idx:idx + 9] == '-Infinity':
  602. return parse_constant('-Infinity'), idx + 9
  603. else:
  604. raise StopIteration
  605. return _scan_once
  606. make_scanner = c_make_scanner or py_make_scanner
  607. __version__ = '2.0.9'
  608. __all__ = [
  609. 'dump', 'dumps', 'load', 'loads',
  610. 'JSONDecoder', 'JSONEncoder',
  611. ]
  612. _default_encoder = JSONEncoder(
  613. skipkeys=False,
  614. ensure_ascii=True,
  615. check_circular=True,
  616. allow_nan=True,
  617. indent=None,
  618. separators=None,
  619. encoding='utf-8',
  620. default=None,
  621. )
  622. def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
  623. allow_nan=True, cls=None, indent=None, separators=None,
  624. encoding='utf-8', default=None, **kw):
  625. # cached encoder
  626. if (not skipkeys and ensure_ascii and
  627. check_circular and allow_nan and
  628. cls is None and indent is None and separators is None and
  629. encoding == 'utf-8' and default is None and not kw):
  630. iterable = _default_encoder.iterencode(obj)
  631. else:
  632. if cls is None:
  633. cls = JSONEncoder
  634. iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii,
  635. check_circular=check_circular, allow_nan=allow_nan, indent=indent,
  636. separators=separators, encoding=encoding,
  637. default=default, **kw).iterencode(obj)
  638. # could accelerate with writelines in some versions of Python, at
  639. # a debuggability cost
  640. for chunk in iterable:
  641. fp.write(chunk)
  642. def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
  643. allow_nan=True, cls=None, indent=None, separators=None,
  644. encoding='utf-8', default=None, **kw):
  645. # cached encoder
  646. if (not skipkeys and ensure_ascii and
  647. check_circular and allow_nan and
  648. cls is None and indent is None and separators is None and
  649. encoding == 'utf-8' and default is None and not kw):
  650. return _default_encoder.encode(obj)
  651. if cls is None:
  652. cls = JSONEncoder
  653. return cls(
  654. skipkeys=skipkeys, ensure_ascii=ensure_ascii,
  655. check_circular=check_circular, allow_nan=allow_nan, indent=indent,
  656. separators=separators, encoding=encoding, default=default,
  657. **kw).encode(obj)
  658. _default_decoder = JSONDecoder(encoding=None, object_hook=None)
  659. def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None,
  660. parse_int=None, parse_constant=None, **kw):
  661. return loads(fp.read(),
  662. encoding=encoding, cls=cls, object_hook=object_hook,
  663. parse_float=parse_float, parse_int=parse_int,
  664. parse_constant=parse_constant, **kw)
  665. def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None,
  666. parse_int=None, parse_constant=None, **kw):
  667. if (cls is None and encoding is None and object_hook is None and
  668. parse_int is None and parse_float is None and
  669. parse_constant is None and not kw):
  670. return _default_decoder.decode(s)
  671. if cls is None:
  672. cls = JSONDecoder
  673. if object_hook is not None:
  674. kw['object_hook'] = object_hook
  675. if parse_float is not None:
  676. kw['parse_float'] = parse_float
  677. if parse_int is not None:
  678. kw['parse_int'] = parse_int
  679. if parse_constant is not None:
  680. kw['parse_constant'] = parse_constant
  681. return cls(encoding=encoding, **kw).decode(s)