Coverage for simplejson/scanner.py: 0%

# Coverage for simplejson/scanner.py : 0%

## 91 statements 0 run 91 missing 0 excluded

Hot-keys on this page

r m x p toggle line displays

j k next/prev highlighted chunk

0 (zero) top of page

1 (one) first highlighted chunk

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | """JSON token scanner """ import re def _import_c_make_scanner(): try: from simplejson._speedups import make_scanner return make_scanner except ImportError: return None c_make_scanner = _import_c_make_scanner() __all__ = ['make_scanner', 'JSONDecodeError'] NUMBER_RE = re.compile( r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?', (re.VERBOSE | re.MULTILINE | re.DOTALL)) class JSONDecodeError(ValueError): """Subclass of ValueError with the following additional properties: msg: The unformatted error message doc: The JSON document being parsed pos: The start index of doc where parsing failed end: The end index of doc where parsing failed (may be None) lineno: The line corresponding to pos colno: The column corresponding to pos endlineno: The line corresponding to end (may be None) endcolno: The column corresponding to end (may be None) """ # Note that this exception is used from _speedups def __init__(self, msg, doc, pos, end=None): ValueError.__init__(self, errmsg(msg, doc, pos, end=end)) self.msg = msg self.doc = doc self.pos = pos self.end = end self.lineno, self.colno = linecol(doc, pos) if end is not None: self.endlineno, self.endcolno = linecol(doc, end) else: self.endlineno, self.endcolno = None, None def __reduce__(self): return self.__class__, (self.msg, self.doc, self.pos, self.end) def linecol(doc, pos): lineno = doc.count('\n', 0, pos) + 1 if lineno == 1: colno = pos + 1 else: colno = pos - doc.rindex('\n', 0, pos) return lineno, colno def errmsg(msg, doc, pos, end=None): lineno, colno = linecol(doc, pos) msg = msg.replace('%r', repr(doc[pos: pos + 1])) if end is None: fmt = '%s: line %d column %d (char %d)' return fmt % (msg, lineno, colno, pos) endlineno, endcolno = linecol(doc, end) fmt = '%s: line %d column %d - line %d column %d (char %d - %d)' return fmt % (msg, lineno, colno, endlineno, endcolno, pos, end) def py_make_scanner(context): parse_object = context.parse_object parse_array = context.parse_array parse_string = context.parse_string match_number = NUMBER_RE.match encoding = context.encoding strict = context.strict parse_float = context.parse_float parse_int = context.parse_int parse_constant = context.parse_constant object_hook = context.object_hook object_pairs_hook = context.object_pairs_hook memo = context.memo def _scan_once(string, idx): errmsg = 'Expecting value' try: nextchar = string[idx] except IndexError: raise JSONDecodeError(errmsg, string, idx) if nextchar == '"': return parse_string(string, idx + 1, encoding, strict) elif nextchar == '{': return parse_object((string, idx + 1), encoding, strict, _scan_once, object_hook, object_pairs_hook, memo) elif nextchar == '[': return parse_array((string, idx + 1), _scan_once) elif nextchar == 'n' and string[idx: idx + 4] == 'null': return None, idx + 4 elif nextchar == 't' and string[idx: idx + 4] == 'true': return True, idx + 4 elif nextchar == 'f' and string[idx: idx + 5] == 'false': return False, idx + 5 m = match_number(string, idx) if m is not None: integer, frac, exp = m.groups() if frac or exp: res = parse_float(integer + (frac or '') + (exp or '')) else: res = parse_int(integer) return res, m.end() elif nextchar == 'N' and string[idx: idx + 3] == 'NaN': return parse_constant('NaN'), idx + 3 elif nextchar == 'I' and string[idx: idx + 8] == 'Infinity': return parse_constant('Infinity'), idx + 8 elif nextchar == '-' and string[idx: idx + 9] == '-Infinity': return parse_constant('-Infinity'), idx + 9 else: raise JSONDecodeError(errmsg, string, idx) def scan_once(string, idx): if idx < 0: # Ensure the same behavior as the C speedup, otherwise # this would work for *some* negative string indices due # to the behavior of __getitem__ for strings. #98 raise JSONDecodeError('Expecting value', string, idx) try: return _scan_once(string, idx) finally: memo.clear() return scan_once make_scanner = c_make_scanner or py_make_scanner