Coverage for /home/runner/.local/share/hatch/env/virtual/importnb-KA2AwMZG/test.interactive/lib/python3.9/site-packages/importnb/decoder.py: 93%

67 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2022-10-03 22:31 +0000

1import json 

2import linecache 

3import textwrap 

4from functools import partial 

5 

6 

7def quote(object, *, quotes="'''"): 

8 if quotes in object: 

9 quotes = '"""' 

10 return quotes + object + "\n" + quotes 

11 

12 

13from ._json_parser import Lark_StandAlone, Transformer 

14 

15 

16class Transformer(Transformer): 

17 def __init__( 

18 self, 

19 markdown=quote, 

20 code=textwrap.dedent, 

21 raw=partial(textwrap.indent, prefix="# "), 

22 **kwargs, 

23 ): 

24 super().__init__(**kwargs) 

25 

26 for key in ("markdown", "code", "raw"): 

27 setattr(self, "transform_" + key, locals().get(key)) 

28 

29 def string(self, s): 

30 return s[0].line, json.loads(s[0]) 

31 

32 def item(self, s): 

33 key = s[0][-1] 

34 if key == "cells": 

35 return self.render(list(map(dict, s[-1]))) 

36 elif key in {"source", "text"}: 

37 return key, s[-1] 

38 elif key == "cell_type": 

39 return key, s[-1][-1] 

40 

41 def array(self, s): 

42 if s: 

43 return s 

44 return [] 

45 

46 def object(self, s): 

47 return [x for x in s if x is not None] 

48 

49 def render_one(self, kind, lines): 

50 s = "".join(lines) 

51 if not s.endswith(("\n",)): 

52 s += "\n" 

53 return getattr(self, f"transform_{kind}")(s) 

54 

55 def render(self, x): 

56 body = [] 

57 for token in x: 

58 t = token.get("cell_type") 

59 try: 

60 s = token["source"] 

61 except KeyError: 

62 s = token.get("text") 

63 if s: 

64 if not isinstance(s, list): 

65 s = [s] 

66 l, lines = s[0][0], [x[1] for x in s] 

67 body.extend([""] * (l - len(body))) 

68 lines = self.render_one(t, lines) 

69 body.extend(lines.splitlines()) 

70 return "\n".join(body + [""]) 

71 

72 

73class LineCacheNotebookDecoder(Transformer): 

74 def __init__( 

75 self, 

76 markdown=quote, 

77 code=textwrap.dedent, 

78 raw=partial(textwrap.indent, prefix="# "), 

79 **kwargs, 

80 ): 

81 super().__init__(**kwargs) 

82 

83 for key in ("markdown", "code", "raw"): 

84 setattr(self, "transform_" + key, locals().get(key)) 

85 

86 def source_from_json_grammar(self, object): 

87 return Lark_StandAlone(transformer=self).parse(object) 

88 

89 def decode(self, object, filename): 

90 s = self.source_from_json_grammar(object) 

91 if s: 

92 source = s[0] 

93 linecache.updatecache(filename) 

94 if filename in linecache.cache: 

95 linecache.cache[filename] = ( 

96 linecache.cache[filename][0], 

97 linecache.cache[filename][1], 

98 source.splitlines(True), 

99 filename, 

100 ) 

101 return source 

102 return ""