summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2010-01-12 09:55:07 +0000
committerGeorg Brandl <georg@python.org>2010-01-12 09:55:07 +0000
commitc8321d3020760fb2ec1c51df8bb91e436096172c (patch)
treedfb66eb2eba0d28430b6b5be2267b1ced07325b4
parent403b01f38b187eb17ec69196aa14e246f9c726da (diff)
downloadsphinx-git-c8321d3020760fb2ec1c51df8bb91e436096172c.tar.gz
#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.
-rw-r--r--CHANGES3
-rw-r--r--sphinx/ext/graphviz.py23
-rw-r--r--sphinx/util/__init__.py1
3 files changed, 21 insertions, 6 deletions
diff --git a/CHANGES b/CHANGES
index c6004c3f0..119950f22 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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.
diff --git a/sphinx/ext/graphviz.py b/sphinx/ext/graphviz.py
index d3e1bd99e..993d48962 100644
--- a/sphinx/ext/graphviz.py
+++ b/sphinx/ext/graphviz.py
@@ -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')
- stdout, stderr = p.communicate(code)
+ 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
diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py
index 0b9a1ace0..5745907f4 100644
--- a/sphinx/util/__init__.py
+++ b/sphinx/util/__init__.py
@@ -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+')