Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/graphviz/rendering.py: 58%

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

40 statements  

1"""Save DOT code objects, render with Graphviz ``dot``, and open in viewer.""" 

2 

3import logging 

4import os 

5import pathlib 

6 

7from . import _tools 

8from . import backend 

9from . import saving 

10 

11__all__ = ['Render'] 

12 

13 

14log = logging.getLogger(__name__) 

15 

16 

17class Render(saving.Save, backend.Render, backend.View): 

18 """Write source lines to file and render with Graphviz.""" 

19 

20 @_tools.deprecate_positional_args(supported_number=1, ignore_arg='self') 

21 def render(self, 

22 filename: os.PathLike[str] | str | None = None, 

23 directory: os.PathLike[str] | str | None = None, 

24 view: bool = False, 

25 cleanup: bool = False, 

26 format: str | None = None, 

27 renderer: str | None = None, 

28 formatter: str | None = None, 

29 neato_no_op: bool | int | None = None, 

30 quiet: bool = False, 

31 quiet_view: bool = False, *, 

32 outfile: os.PathLike[str] | str | None = None, 

33 engine: str | None = None, 

34 raise_if_result_exists: bool = False, 

35 overwrite_source: bool = False) -> str: 

36 r"""Save the source to file and render with the Graphviz engine. 

37 

38 Args: 

39 filename: Filename for saving the source 

40 (defaults to ``name`` + ``'.gv'``).s 

41 directory: (Sub)directory for source saving and rendering. 

42 view (bool): Open the rendered result 

43 with the default application. 

44 cleanup (bool): Delete the source file 

45 after successful rendering. 

46 format: The output format used for rendering 

47 (``'pdf'``, ``'png'``, etc.). 

48 renderer: The output renderer used for rendering 

49 (``'cairo'``, ``'gd'``, ...). 

50 formatter: The output formatter used for rendering 

51 (``'cairo'``, ``'gd'``, ...). 

52 neato_no_op: Neato layout engine no-op flag. 

53 quiet (bool): Suppress ``stderr`` output 

54 from the layout subprocess. 

55 quiet_view (bool): Suppress ``stderr`` output 

56 from the viewer process 

57 (implies ``view=True``, ineffective on Windows platform). 

58 outfile: Path for the rendered output file. 

59 engine: Layout engine for rendering 

60 (``'dot'``, ``'neato'``, ...). 

61 raise_if_result_exists: Raise :exc:`graphviz.FileExistsError` 

62 if the result file exists. 

63 overwrite_source: Allow ``dot`` to write to the file it reads from. 

64 Incompatible with ``raise_if_result_exists``. 

65 

66 Returns: 

67 The (possibly relative) path of the rendered file. 

68 

69 Raises: 

70 ValueError: If ``engine``, ``format``, ``renderer``, or ``formatter`` 

71 are unknown. 

72 graphviz.RequiredArgumentError: If ``formatter`` is given 

73 but ``renderer`` is None. 

74 ValueError: If ``outfile`` is the same file as the source file 

75 unless ``overwite_source=True``. 

76 graphviz.ExecutableNotFound: If the Graphviz ``dot`` executable 

77 is not found. 

78 graphviz.CalledProcessError: If the returncode (exit status) 

79 of the rendering ``dot`` subprocess is non-zero. 

80 RuntimeError: If viewer opening is requested but not supported. 

81 

82 Example: 

83 >>> doctest_mark_exe() 

84 >>> import graphviz 

85 >>> dot = graphviz.Graph(name='spam', directory='doctest-output') 

86 >>> dot.render(format='png').replace('\\', '/') 

87 'doctest-output/spam.gv.png' 

88 >>> dot.render(outfile='spam.svg').replace('\\', '/') 

89 'doctest-output/spam.svg' 

90 

91 Note: 

92 The layout command is started from the directory of ``filepath``, 

93 so that references to external files 

94 (e.g. ``[image=images/camelot.png]``) 

95 can be given as paths relative to the DOT source file. 

96 """ 

97 outfile = _tools.promote_pathlike(outfile) 

98 if outfile is not None: 

99 format = self._get_format(outfile, format=format) 

100 if directory is None: 

101 outfile = pathlib.Path(self.directory, outfile) 

102 

103 args, kwargs = self._get_render_parameters(engine=engine, 

104 format=format, 

105 renderer=renderer, 

106 formatter=formatter, 

107 neato_no_op=neato_no_op, 

108 quiet=quiet, 

109 outfile=outfile, 

110 raise_if_result_exists=raise_if_result_exists, 

111 overwrite_source=overwrite_source, 

112 verify=True) 

113 

114 if outfile is not None and filename is None: 

115 filename = self._get_filepath(outfile) 

116 

117 filepath = self.save(filename, directory=directory, skip_existing=None) 

118 

119 args.append(filepath) 

120 

121 rendered = self._render(*args, **kwargs) 

122 

123 if cleanup: 

124 log.debug('delete %r', filepath) 

125 os.remove(filepath) 

126 

127 if quiet_view or view: 

128 self._view(rendered, format=self._format, quiet=quiet_view) 

129 

130 return rendered 

131 

132 def _view(self, filepath: os.PathLike[str] | str, *, 

133 format: str, quiet: bool) -> None: 

134 """Start the right viewer based on file format and platform.""" 

135 methodnames = [ 

136 f'_view_{format}_{backend.viewing.PLATFORM}', 

137 f'_view_{backend.viewing.PLATFORM}', 

138 ] 

139 for name in methodnames: 

140 view_method = getattr(self, name, None) 

141 if view_method is not None: 

142 break 

143 else: 

144 raise RuntimeError(f'{self.__class__!r} has no built-in viewer' 

145 f' support for {format!r}' 

146 f' on {backend.viewing.PLATFORM!r} platform') 

147 view_method(filepath, quiet=quiet) 

148 

149 @_tools.deprecate_positional_args(supported_number=1, ignore_arg='self') 

150 def view(self, 

151 filename: os.PathLike[str] | str | None = None, 

152 directory: os.PathLike[str] | str | None = None, 

153 cleanup: bool = False, 

154 quiet: bool = False, 

155 quiet_view: bool = False) -> str: 

156 """Save the source to file, open the rendered result in a viewer. 

157 

158 Convenience short-cut for running ``.render(view=True)``. 

159 

160 Args: 

161 filename: Filename for saving the source 

162 (defaults to ``name`` + ``'.gv'``). 

163 directory: (Sub)directory for source saving and rendering. 

164 cleanup (bool): Delete the source file after successful rendering. 

165 quiet (bool): Suppress ``stderr`` output from the layout subprocess. 

166 quiet_view (bool): Suppress ``stderr`` output 

167 from the viewer process (ineffective on Windows). 

168 

169 Returns: 

170 The (possibly relative) path of the rendered file. 

171 

172 Raises: 

173 graphviz.ExecutableNotFound: If the Graphviz executable 

174 is not found. 

175 graphviz.CalledProcessError: If the exit status is non-zero. 

176 RuntimeError: If opening the viewer is not supported. 

177 

178 Short-cut method for calling :meth:`.render` with ``view=True``. 

179 

180 Note: 

181 There is no option to wait for the application to close, 

182 and no way to retrieve the application's exit status. 

183 """ 

184 return self.render(filename=filename, directory=directory, view=True, 

185 cleanup=cleanup, quiet=quiet, quiet_view=quiet_view)