Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/IPython/core/displaypub.py: 37%

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

51 statements  

1"""An interface for publishing rich data to frontends. 

2 

3There are two components of the display system: 

4 

5* Display formatters, which take a Python object and compute the 

6 representation of the object in various formats (text, HTML, SVG, etc.). 

7* The display publisher that is used to send the representation data to the 

8 various frontends. 

9 

10This module defines the logic display publishing. The display publisher uses 

11the ``display_data`` message type that is defined in the IPython messaging 

12spec. 

13""" 

14 

15# Copyright (c) IPython Development Team. 

16# Distributed under the terms of the Modified BSD License. 

17 

18import sys 

19 

20from traitlets.config.configurable import Configurable 

21from traitlets import List 

22 

23# This used to be defined here - it is imported for backwards compatibility 

24from .display_functions import publish_display_data 

25from .history import HistoryOutput 

26 

27import typing as t 

28 

29# ----------------------------------------------------------------------------- 

30# Main payload class 

31# ----------------------------------------------------------------------------- 

32 

33_sentinel = object() 

34 

35 

36class DisplayPublisher(Configurable): 

37 """A traited class that publishes display data to frontends. 

38 

39 Instances of this class are created by the main IPython object and should 

40 be accessed there. 

41 """ 

42 

43 def __init__(self, shell=None, *args, **kwargs): 

44 self.shell = shell 

45 self._is_publishing = False 

46 super().__init__(*args, **kwargs) 

47 

48 def _validate_data(self, data, metadata=None): 

49 """Validate the display data. 

50 

51 Parameters 

52 ---------- 

53 data : dict 

54 The formata data dictionary. 

55 metadata : dict 

56 Any metadata for the data. 

57 """ 

58 

59 if not isinstance(data, dict): 

60 raise TypeError("data must be a dict, got: %r" % data) 

61 if metadata is not None: 

62 if not isinstance(metadata, dict): 

63 raise TypeError("metadata must be a dict, got: %r" % data) 

64 

65 # use * to indicate transient, update are keyword-only 

66 def publish( 

67 self, 

68 data, 

69 metadata=None, 

70 source=_sentinel, 

71 *, 

72 transient=None, 

73 update=False, 

74 **kwargs, 

75 ) -> None: 

76 """Publish data and metadata to all frontends. 

77 

78 See the ``display_data`` message in the messaging documentation for 

79 more details about this message type. 

80 

81 The following MIME types are currently implemented: 

82 

83 * text/plain 

84 * text/html 

85 * text/markdown 

86 * text/latex 

87 * application/json 

88 * application/javascript 

89 * image/png 

90 * image/jpeg 

91 * image/svg+xml 

92 

93 Parameters 

94 ---------- 

95 data : dict 

96 A dictionary having keys that are valid MIME types (like 

97 'text/plain' or 'image/svg+xml') and values that are the data for 

98 that MIME type. The data itself must be a JSON'able data 

99 structure. Minimally all data should have the 'text/plain' data, 

100 which can be displayed by all frontends. If more than the plain 

101 text is given, it is up to the frontend to decide which 

102 representation to use. 

103 metadata : dict 

104 A dictionary for metadata related to the data. This can contain 

105 arbitrary key, value pairs that frontends can use to interpret 

106 the data. Metadata specific to each mime-type can be specified 

107 in the metadata dict with the same mime-type keys as 

108 the data itself. 

109 source : str, deprecated 

110 Unused. 

111 transient : dict, keyword-only 

112 A dictionary for transient data. 

113 Data in this dictionary should not be persisted as part of saving this output. 

114 Examples include 'display_id'. 

115 update : bool, keyword-only, default: False 

116 If True, only update existing outputs with the same display_id, 

117 rather than creating a new output. 

118 """ 

119 

120 if source is not _sentinel: 

121 import warnings 

122 

123 warnings.warn( 

124 "The 'source' parameter is deprecated since IPython 3.0 and will be ignored " 

125 "(this warning is present since 9.0). `source` parameter will be removed in the future.", 

126 DeprecationWarning, 

127 stacklevel=2, 

128 ) 

129 

130 handlers: t.Dict = {} 

131 if self.shell is not None: 

132 handlers = getattr(self.shell, "mime_renderers", {}) 

133 

134 outputs = self.shell.history_manager.outputs 

135 

136 outputs[self.shell.execution_count].append( 

137 HistoryOutput(output_type="display_data", bundle=data) 

138 ) 

139 

140 for mime, handler in handlers.items(): 

141 if mime in data: 

142 handler(data[mime], metadata.get(mime, None)) 

143 return 

144 

145 self._is_publishing = True 

146 if "text/plain" in data: 

147 print(data["text/plain"]) 

148 self._is_publishing = False 

149 

150 @property 

151 def is_publishing(self): 

152 return self._is_publishing 

153 

154 def clear_output(self, wait=False): 

155 """Clear the output of the cell receiving output.""" 

156 print("\033[2K\r", end="") 

157 sys.stdout.flush() 

158 print("\033[2K\r", end="") 

159 sys.stderr.flush() 

160 

161 

162class CapturingDisplayPublisher(DisplayPublisher): 

163 """A DisplayPublisher that stores""" 

164 

165 outputs: List = List() 

166 

167 def publish( 

168 self, data, metadata=None, source=None, *, transient=None, update=False 

169 ): 

170 self.outputs.append( 

171 { 

172 "data": data, 

173 "metadata": metadata, 

174 "transient": transient, 

175 "update": update, 

176 } 

177 ) 

178 

179 def clear_output(self, wait=False): 

180 super(CapturingDisplayPublisher, self).clear_output(wait) 

181 

182 # empty the list, *do not* reassign a new list 

183 self.outputs.clear()