Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/simplejson-4.1.1-py3.11-linux-x86_64.egg/simplejson/scanner.py: 18%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

66 statements  

1"""JSON token scanner 

2""" 

3import re 

4from .errors import JSONDecodeError 

5 

6def _import_c_make_scanner(): 

7 try: 

8 from ._speedups import make_scanner 

9 return make_scanner 

10 except ImportError: 

11 return None 

12c_make_scanner = _import_c_make_scanner() 

13 

14__all__ = ['make_scanner', 'JSONDecodeError'] 

15 

16NUMBER_RE = re.compile( 

17 r'(-?(?:0|[1-9][0-9]*))(\.[0-9]+)?([eE][-+]?[0-9]+)?', 

18 (re.VERBOSE | re.MULTILINE | re.DOTALL)) 

19 

20 

21def py_make_scanner(context): 

22 parse_object = context.parse_object 

23 parse_array = context.parse_array 

24 parse_string = context.parse_string 

25 match_number = NUMBER_RE.match 

26 encoding = context.encoding 

27 strict = context.strict 

28 parse_float = context.parse_float 

29 parse_int = context.parse_int 

30 parse_constant = context.parse_constant 

31 object_hook = context.object_hook 

32 object_pairs_hook = context.object_pairs_hook 

33 array_hook = context.array_hook 

34 memo = context.memo 

35 

36 def _scan_once(string, idx): 

37 errmsg = 'Expecting value' 

38 try: 

39 nextchar = string[idx] 

40 except IndexError: 

41 raise JSONDecodeError(errmsg, string, idx) 

42 

43 if nextchar == '"': 

44 return parse_string(string, idx + 1, encoding, strict) 

45 elif nextchar == '{': 

46 return parse_object((string, idx + 1), encoding, strict, 

47 _scan_once, object_hook, object_pairs_hook, memo) 

48 elif nextchar == '[': 

49 return parse_array((string, idx + 1), _scan_once, array_hook) 

50 elif nextchar == 'n' and string[idx:idx + 4] == 'null': 

51 return None, idx + 4 

52 elif nextchar == 't' and string[idx:idx + 4] == 'true': 

53 return True, idx + 4 

54 elif nextchar == 'f' and string[idx:idx + 5] == 'false': 

55 return False, idx + 5 

56 

57 m = match_number(string, idx) 

58 if m is not None: 

59 integer, frac, exp = m.groups() 

60 if frac or exp: 

61 res = parse_float(integer + (frac or '') + (exp or '')) 

62 else: 

63 res = parse_int(integer) 

64 return res, m.end() 

65 elif parse_constant and nextchar == 'N' and string[idx:idx + 3] == 'NaN': 

66 return parse_constant('NaN'), idx + 3 

67 elif parse_constant and nextchar == 'I' and string[idx:idx + 8] == 'Infinity': 

68 return parse_constant('Infinity'), idx + 8 

69 elif parse_constant and nextchar == '-' and string[idx:idx + 9] == '-Infinity': 

70 return parse_constant('-Infinity'), idx + 9 

71 else: 

72 raise JSONDecodeError(errmsg, string, idx) 

73 

74 def scan_once(string, idx): 

75 if idx < 0: 

76 # Ensure the same behavior as the C speedup, otherwise 

77 # this would work for *some* negative string indices due 

78 # to the behavior of __getitem__ for strings. #98 

79 raise JSONDecodeError('Expecting value', string, idx) 

80 try: 

81 return _scan_once(string, idx) 

82 finally: 

83 memo.clear() 

84 

85 return scan_once 

86 

87make_scanner = c_make_scanner or py_make_scanner