this repo has no description
at trunk 128 lines 4.9 kB view raw
1#!/usr/bin/env python3 2# Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 3# WARNING: This is mostly a copy of code from the cpython library. 4# flake8: noqa 5# fmt: off 6# isort:skip_file 7"""Implementation of JSONDecoder 8""" 9import re 10from _json import JSONDecodeError, loads as _loads 11 12from _builtins import _unimplemented 13 14__all__ = ['JSONDecoder', 'JSONDecodeError'] 15 16 17NaN = float('nan') 18PosInf = float('inf') 19NegInf = float('-inf') 20 21_CONSTANTS = { 22 '-Infinity': NegInf, 23 'Infinity': PosInf, 24 'NaN': NaN, 25} 26 27 28class JSONDecoder(object): 29 """Simple JSON <http://json.org> decoder 30 31 Performs the following translations in decoding by default: 32 33 +---------------+-------------------+ 34 | JSON | Python | 35 +===============+===================+ 36 | object | dict | 37 +---------------+-------------------+ 38 | array | list | 39 +---------------+-------------------+ 40 | string | str | 41 +---------------+-------------------+ 42 | number (int) | int | 43 +---------------+-------------------+ 44 | number (real) | float | 45 +---------------+-------------------+ 46 | true | True | 47 +---------------+-------------------+ 48 | false | False | 49 +---------------+-------------------+ 50 | null | None | 51 +---------------+-------------------+ 52 53 It also understands ``NaN``, ``Infinity``, and ``-Infinity`` as 54 their corresponding ``float`` values, which is outside the JSON spec. 55 56 """ 57 58 def __init__(self, *, object_hook=None, parse_float=None, 59 parse_int=None, parse_constant=None, strict=True, 60 object_pairs_hook=None): 61 """``object_hook``, if specified, will be called with the result 62 of every JSON object decoded and its return value will be used in 63 place of the given ``dict``. This can be used to provide custom 64 deserializations (e.g. to support JSON-RPC class hinting). 65 66 ``object_pairs_hook``, if specified will be called with the result of 67 every JSON object decoded with an ordered list of pairs. The return 68 value of ``object_pairs_hook`` will be used instead of the ``dict``. 69 This feature can be used to implement custom decoders. 70 If ``object_hook`` is also defined, the ``object_pairs_hook`` takes 71 priority. 72 73 ``parse_float``, if specified, will be called with the string 74 of every JSON float to be decoded. By default this is equivalent to 75 float(num_str). This can be used to use another datatype or parser 76 for JSON floats (e.g. decimal.Decimal). 77 78 ``parse_int``, if specified, will be called with the string 79 of every JSON int to be decoded. By default this is equivalent to 80 int(num_str). This can be used to use another datatype or parser 81 for JSON integers (e.g. float). 82 83 ``parse_constant``, if specified, will be called with one of the 84 following strings: -Infinity, Infinity, NaN. 85 This can be used to raise an exception if invalid JSON numbers 86 are encountered. 87 88 If ``strict`` is false (true is the default), then control 89 characters will be allowed inside strings. Control characters in 90 this context are those with character codes in the 0-31 range, 91 including ``'\\t'`` (tab), ``'\\n'``, ``'\\r'`` and ``'\\0'``. 92 """ 93 self.object_hook = object_hook 94 self.parse_float = parse_float or float 95 self.parse_int = parse_int or int 96 self.parse_constant = parse_constant or _CONSTANTS.__getitem__ 97 self.strict = strict 98 self.object_pairs_hook = object_pairs_hook 99 100 101 def decode(self, s): 102 """Return the Python representation of ``s`` (a ``str`` instance 103 containing a JSON document). 104 105 """ 106 parse_float = self.parse_float 107 if parse_float is float: 108 parse_float = None 109 parse_int = self.parse_int 110 if parse_int is int: 111 parse_int = None 112 parse_constant = self.parse_constant 113 if parse_constant == _CONSTANTS.__getitem__: 114 parse_constant = None 115 return _loads(s, object_hook=self.object_hook, parse_float=parse_float, 116 parse_int=parse_int, parse_constant=parse_constant, 117 object_pairs_hook=self.object_pairs_hook, strict=self.strict) 118 119 def raw_decode(self, s, idx=0): 120 """Decode a JSON document from ``s`` (a ``str`` beginning with 121 a JSON document) and return a 2-tuple of the Python 122 representation and the index in ``s`` where the document ended. 123 124 This can be used to decode a JSON document from a string that may 125 have extraneous data at the end. 126 127 """ 128 _unimplemented()