Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/ijson/utils.py: 70%

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

37 statements  

1# -*- coding:utf-8 -*- 

2from functools import wraps 

3 

4 

5def coroutine(func): 

6 ''' 

7 Wraps a generator which is intended to be used as a pure coroutine by 

8 .send()ing it values. The only thing that the wrapper does is calling 

9 .next() for the first time which is required by Python generator protocol. 

10 ''' 

11 @wraps(func) 

12 def wrapper(*args, **kwargs): 

13 g = func(*args, **kwargs) 

14 next(g) 

15 return g 

16 return wrapper 

17 

18 

19def chain(sink, *coro_pipeline): 

20 ''' 

21 Chains together a sink and a number of coroutines to form a coroutine 

22 pipeline. The pipeline works by calling send() on the coroutine created with 

23 the information in `coro_pipeline[-1]`, which sends its results to the 

24 coroutine created from `coro_pipeline[-2]`, and so on, until the final 

25 result is sent to `sink`. 

26 ''' 

27 f = sink 

28 for coro_func, coro_args, coro_kwargs in coro_pipeline: 

29 f = coro_func(f, *coro_args, **coro_kwargs) 

30 return f 

31 

32 

33class sendable_list(list): 

34 ''' 

35 A list that mimics a coroutine receiving values. 

36 

37 Coroutine are sent values via their send() method. This class defines such a 

38 method so that values sent into it are appended into the list, which can be 

39 inspected later. As such, this type can be used as an "accumulating sink" in 

40 a pipeline consisting on many coroutines. 

41 ''' 

42 send = list.append 

43 

44 

45def coros2gen(source, *coro_pipeline): 

46 ''' 

47 A utility function that returns a generator yielding values dispatched by a 

48 coroutine pipeline after *it* has received values coming from `source`. 

49 ''' 

50 events = sendable_list() 

51 f = chain(events, *coro_pipeline) 

52 try: 

53 for value in source: 

54 try: 

55 f.send(value) 

56 except Exception as ex: 

57 for event in events: 

58 yield event 

59 if isinstance(ex, StopIteration): 

60 return 

61 raise 

62 for event in events: 

63 yield event 

64 del events[:] 

65 except GeneratorExit: 

66 try: 

67 f.close() 

68 except: 

69 pass