#316: catch "broken pipe" OSErrors when communicating with graphviz; get stdout/stderr anyway. This happens e.g. when dot does not support the selected output format.

This commit is contained in:
Georg Brandl 2010-01-12 09:55:07 +00:00
parent 403b01f38b
commit c8321d3020
3 changed files with 21 additions and 6 deletions

View File

@ -1,6 +1,9 @@
Release 0.6.4 (in development)
==============================
* #316: Catch OSErrors occurring when calling graphviz with
arguments it doesn't understand.
* Restore compatibility with Pygments >= 1.2.
* #295: Fix escaping of hyperref targets in LaTeX output.

View File

@ -22,7 +22,7 @@ except ImportError:
from docutils import nodes
from sphinx.errors import SphinxError
from sphinx.util import ensuredir, ENOENT
from sphinx.util import ensuredir, ENOENT, EPIPE
from sphinx.util.compat import Directive
@ -102,6 +102,10 @@ def render_dot(self, code, options, format, prefix='graphviz'):
ensuredir(path.dirname(outfn))
# graphviz expects UTF-8 by default
if isinstance(code, unicode):
code = code.encode('utf-8')
dot_args = [self.builder.config.graphviz_dot]
dot_args.extend(self.builder.config.graphviz_dot_args)
dot_args.extend(options)
@ -118,10 +122,17 @@ def render_dot(self, code, options, format, prefix='graphviz'):
self.builder.config.graphviz_dot)
self.builder._graphviz_warned_dot = True
return None, None
# graphviz expects UTF-8 by default
if isinstance(code, unicode):
code = code.encode('utf-8')
try:
# Graphviz may close standard input when an error occurs,
# resulting in a broken pipe on communicate()
stdout, stderr = p.communicate(code)
except OSError, err:
if err.errno != EPIPE:
raise
# in this case, read the standard output and standard error streams
# directly, to get the error message(s)
stdout, stderr = p.stdout.read(), p.stderr.read()
p.wait()
if p.returncode != 0:
raise GraphvizError('dot exited with error:\n[stderr]\n%s\n'
'[stdout]\n%s' % (stderr, stdout))
@ -131,7 +142,7 @@ def render_dot(self, code, options, format, prefix='graphviz'):
def render_dot_html(self, node, code, options, prefix='graphviz',
imgcls=None, alt=None):
try:
fname, outfn = render_dot(self, code, options, 'png', prefix)
fname, outfn = render_dot(self, code, options, 'pnf', prefix)
except GraphvizError, exc:
self.builder.warn('dot code %r: ' % code + str(exc))
raise nodes.SkipNode

View File

@ -29,6 +29,7 @@ import sphinx
# Errnos that we need.
EEXIST = getattr(errno, 'EEXIST', 0)
ENOENT = getattr(errno, 'ENOENT', 0)
EPIPE = getattr(errno, 'EPIPE', 0)
# Generally useful regular expressions.
ws_re = re.compile(r'\s+')