/usr/lib/python2.7/dist-packages/ijson/utils.py is in python-ijson 2.3-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 | # -*- coding:utf-8 -*-
from functools import wraps
def coroutine(func):
'''
Wraps a generator which intended to be used as a pure coroutine by
.send()ing it values. The only thing that the wrapper does is calling
.next() for the first time which is required by Python generator protocol.
'''
@wraps(func)
def wrapper(*args, **kwargs):
g = func(*args, **kwargs)
next(g)
return g
return wrapper
@coroutine
def foreach(coroutine_func):
'''
Dispatches each JSON array item to a handler coroutine. A coroutine is
created anew for each item by calling `coroutine_func` callable. The
resulting coroutine should accept value in the form of tuple of values
generated by rich JSON parser: (prefix, event, value).
First event received by foreach should be a "start_array" event.
'''
g = None
base, event, value = yield
if event != 'start_array':
raise Exception('foreach requires "start_array" as the first event, got %s' % repr((base, event, value)))
START_EVENTS = set(['start_map', 'start_array', 'null', 'boolean', 'number', 'string'])
itemprefix = base + '.item' if base else 'item'
while True:
prefix, event, value = yield
if prefix == itemprefix and event in START_EVENTS:
g = coroutine_func()
if (prefix, event) != (base, 'end_array'):
g.send((prefix, event, value))
@coroutine
def dispatcher(targets):
'''
Dispatches JSON parser events into several handlers depending on event
prefixes.
Accepts a list of tuples (base_prefix, coroutine). A coroutine then
receives all the events with prefixes starting with its base_prefix.
'''
while True:
prefix, event, value = yield
for base, target in targets:
if prefix.startswith(base):
target.send((prefix, event, value))
break
|