Coverage for /home/tbone/.local/share/hatch/env/virtual/importnb-aVRh-lqt/test.stdlib/lib/python3.9/site-packages/importnb/decoder.py: 93%

1 import ast

2 import builtins

3 import linecache

4 import json

5 import textwrap

6 from functools import partial

7

8

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

10 if quotes in object:

11 quotes = '"""'

12 return quotes + object + "\n" + quotes

13

14

15 from ._json_parser import Lark_StandAlone, Transformer

16

17

18 class Transformer(Transformer):

19 def __init__(

20 self,

21 markdown=quote,

22 code=textwrap.dedent,

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

24 **kwargs,

25 ):

26 super().__init__(**kwargs)

27

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

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

30

31 def string(self, s):

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

33

34 def item(self, s):

35 key = s[0][-1]

36 if key == "cells":

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

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

39 return key, s[-1]

40 elif key == "cell_type":

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

42

43 def array(self, s):

44 if s:

45 return s

46 return []

47

48 def object(self, s):

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

50

51 def render_one(self, kind, lines):

52 s = "".join(lines)

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

54 s += "\n"

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

56

57 def render(self, x):

58 body = []

59 for token in x:

60 t = token.get("cell_type")

61 try:

62 s = token["source"]

63 except KeyError:

64 s = token.get("text")

65 if s:

66 if not isinstance(s, list):

67 s = [s]

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

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

70 lines = self.render_one(t, lines)

71 body.extend(lines.splitlines())

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

73

74

75 class LineCacheNotebookDecoder(Transformer):

76 def __init__(

77 self,

78 markdown=quote,

79 code=textwrap.dedent,

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

81 **kwargs,

82 ):

83 super().__init__(**kwargs)

84

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

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

87

88 def source_from_json_grammar(self, object):

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

90

91 def decode(self, object, filename):

92 s = self.source_from_json_grammar(object)

93 if s:

94 source = s[0]

95 linecache.updatecache(filename)

96 if filename in linecache.cache:

97 linecache.cache[filename] = (

98 linecache.cache[filename][0],

99 linecache.cache[filename][1],

100 source.splitlines(True),

101 filename,

102 )

103 return source

104 return ""