| 
									
										
										
										
											2009-05-02 12:36:44 +00:00
										 |  |  | """JSON token scanner
 | 
					
						
							| 
									
										
										
										
											2008-05-08 14:29:10 +00:00
										 |  |  | """
 | 
					
						
							|  |  |  | import re | 
					
						
							| 
									
										
										
										
											2009-05-02 12:36:44 +00:00
										 |  |  | try: | 
					
						
							|  |  |  |     from _json import make_scanner as c_make_scanner | 
					
						
							| 
									
										
										
										
											2013-07-04 17:43:24 -04:00
										 |  |  | except ImportError: | 
					
						
							| 
									
										
										
										
											2009-05-02 12:36:44 +00:00
										 |  |  |     c_make_scanner = None | 
					
						
							| 
									
										
										
										
											2008-05-08 14:29:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 12:36:44 +00:00
										 |  |  | __all__ = ['make_scanner'] | 
					
						
							| 
									
										
										
										
											2008-05-08 14:29:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 12:36:44 +00:00
										 |  |  | NUMBER_RE = re.compile( | 
					
						
							|  |  |  |     r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?', | 
					
						
							|  |  |  |     (re.VERBOSE | re.MULTILINE | re.DOTALL)) | 
					
						
							| 
									
										
										
										
											2008-05-08 14:29:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 12:36:44 +00:00
										 |  |  | 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 | 
					
						
							|  |  |  |     strict = context.strict | 
					
						
							|  |  |  |     parse_float = context.parse_float | 
					
						
							|  |  |  |     parse_int = context.parse_int | 
					
						
							|  |  |  |     parse_constant = context.parse_constant | 
					
						
							|  |  |  |     object_hook = context.object_hook | 
					
						
							| 
									
										
										
										
											2010-09-04 20:16:53 +00:00
										 |  |  |     object_pairs_hook = context.object_pairs_hook | 
					
						
							|  |  |  |     memo = context.memo | 
					
						
							| 
									
										
										
										
											2008-05-08 14:29:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 12:36:44 +00:00
										 |  |  |     def _scan_once(string, idx): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             nextchar = string[idx] | 
					
						
							|  |  |  |         except IndexError: | 
					
						
							| 
									
										
										
										
											2017-04-05 09:37:24 +03:00
										 |  |  |             raise StopIteration(idx) from None | 
					
						
							| 
									
										
										
										
											2008-05-08 14:29:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 12:36:44 +00:00
										 |  |  |         if nextchar == '"': | 
					
						
							|  |  |  |             return parse_string(string, idx + 1, strict) | 
					
						
							|  |  |  |         elif nextchar == '{': | 
					
						
							|  |  |  |             return parse_object((string, idx + 1), strict, | 
					
						
							| 
									
										
										
										
											2010-09-04 20:16:53 +00:00
										 |  |  |                 _scan_once, object_hook, object_pairs_hook, memo) | 
					
						
							| 
									
										
										
										
											2009-05-02 12:36:44 +00:00
										 |  |  |         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 | 
					
						
							| 
									
										
										
										
											2008-05-08 14:29:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 12:36:44 +00:00
										 |  |  |         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: | 
					
						
							| 
									
										
										
										
											2013-01-03 08:44:15 +02:00
										 |  |  |             raise StopIteration(idx) | 
					
						
							| 
									
										
										
										
											2008-05-08 14:29:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-04 20:16:53 +00:00
										 |  |  |     def scan_once(string, idx): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             return _scan_once(string, idx) | 
					
						
							|  |  |  |         finally: | 
					
						
							|  |  |  |             memo.clear() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-22 14:55:07 +03:00
										 |  |  |     return scan_once | 
					
						
							| 
									
										
										
										
											2008-05-08 14:29:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 12:36:44 +00:00
										 |  |  | make_scanner = c_make_scanner or py_make_scanner |