GraphvizPlugin: fixed handling of default parameters (#3542).
Besides, this supersedes the fixes for #3073 and #3605.
diff -r d2dd756a7d04 graphviz/graphviz.py
--- a/graphviz/graphviz.py Fri Sep 26 13:13:55 2008 +0200
+++ b/graphviz/graphviz.py Fri Sep 26 15:22:54 2008 +0200
@@ -17,6 +17,7 @@
from StringIO import StringIO
+import locale
import sha
import os
import sys
@@ -187,14 +188,7 @@
buf.write('
Graphviz macro processor error: requested format (%s) not valid.
' % self.out_format)
return buf.getvalue()
- if type(content) == type(u''):
- content = content.encode(self.encoding)
- sha_text = self.processor.encode(self.encoding) + \
- self.processor_options.encode(self.encoding) + content
-
- else:
- sha_text = self.processor + self.processor_options + content
-
+ sha_text = self.processor + unicode(self.processor_options) + content
sha_key = sha.new(sha_text).hexdigest()
img_name = '%s.%s.%s' % (sha_key, self.processor, self.out_format) # cache: hash..
img_path = os.path.join(self.cache_dir, img_name)
@@ -216,7 +210,8 @@
# Antialias PNGs with rsvg, if requested
if self.out_format == 'png' and self.png_anti_alias == True:
# 1. SVG output
- cmd = [proc_cmd, self.processor_options, '-Tsvg', '-o%s.svg' % img_path]
+ cmd = [proc_cmd] + self.processor_options + \
+ ['-Tsvg', '-o%s.svg' % img_path]
#self.log.debug('render_macro: svg output - running command %s' % cmd)
out, err = self.launch(cmd, content)
if len(out) or len(err):
@@ -232,7 +227,8 @@
return self.show_err(msg).getvalue()
else: # Render other image formats
- cmd = [proc_cmd, self.processor_options, '-T%s' % self.out_format, '-o%s' % img_path]
+ cmd = [proc_cmd] + self.processor_options + \
+ ['-T%s' % self.out_format, '-o%s' % img_path]
#self.log.debug('render_macro: render other image formats - running command %s' % cmd)
out, err = self.launch(cmd, content)
if len(out) or len(err):
@@ -244,7 +240,8 @@
# Create the map if not in cache
if not os.path.exists(map_path):
- cmd = [proc_cmd, self.processor_options, '-Tcmap', '-o%s' % map_path]
+ cmd = [proc_cmd] + self.processor_options + \
+ ['-Tcmap', '-o%s' % map_path]
#self.log.debug('render_macro: create map if not in cache - running command %s' % cmd)
out, err = self.launch(cmd, content)
if len(out) or len(err):
@@ -295,13 +292,8 @@
def expand_wiki_links(self, content):
- """Expand TracLinks that follow all URL= patterns.
- The `content` input is a `str` encoding using `sel.fencoding` and
- the result should have the same encoding.
- """
- u_content = unicode(content, self.encoding)
- u_content = re.sub(r'URL="(.*?)"', self._expand_wiki_links, u_content)
- return u_content.encode(self.encoding)
+ """Expand TracLinks that follow all URL= patterns."""
+ return re.sub(r'URL="(.*?)"', self._expand_wiki_links, content)
def _expand_wiki_links(self, match):
wiki_url = match.groups()[0] # TracLink ([1], source:file/, ...)
@@ -402,19 +394,17 @@
#self.log.debug('self.rsvg_path: %s' % self.rsvg_path)
# get default graph/node/edge attributes
- self.processor_options = ''
- default_attributes = [ o for o in self.config.options('graphviz') if o[0].startswith('default_') ]
- if default_attributes:
- graph_attributes = [ o for o in default_attributes if o[0].startswith('default_graph_') ]
- node_attributes = [ o for o in default_attributes if o[0].startswith('default_node_') ]
- edge_attributes = [ o for o in default_attributes if o[0].startswith('default_edge_') ]
- if graph_attributes:
- self.processor_options += " ".join([ "-G" + o[0].replace('default_graph_', '') + "=" + o[1] for o in graph_attributes]) + " "
- if node_attributes:
- self.processor_options += " ".join([ "-N" + o[0].replace('default_node_', '') + "=" + o[1] for o in node_attributes]) + " "
- if edge_attributes:
- self.processor_options += " ".join([ "-E" + o[0].replace('default_edge_', '') + "=" + o[1] for o in edge_attributes])
-
+ self.processor_options = []
+ defaults = [opt for opt in self.config.options('graphviz')
+ if opt[0].startswith('default_')]
+ for name, value in defaults:
+ for prefix, optkey in [
+ ('default_graph_', '-G'),
+ ('default_node_', '-N'),
+ ('default_edge_', '-E')]:
+ if name.startswith(prefix):
+ self.processor_options.append("%s%s=%s" %
+ (optkey, name.replace(prefix,''), value))
# check if we should run the cache manager
self.cache_manager = self.boolean(self.config.get('graphviz', 'cache_manager', False))
@@ -444,13 +434,23 @@
def launch(self, cmd, input):
"""Launch a process (cmd), and returns exitcode, stdout + stderr"""
- p = subprocess.Popen([arg for arg in cmd if arg],
+ # Note: subprocess.Popen doesn't support unicode options arguments
+ # (http://bugs.python.org/issue1759845) so we have to encode them.
+ # We use the same encoding as the one sys.argv is supposed to have, see
+ # http://mail.python.org/pipermail/python-list/2006-October/410404.html
+ cmdline_encoding = locale.getpreferredencoding()
+ encoded_cmd = []
+ for arg in cmd:
+ if isinstance(arg, unicode):
+ arg = arg.encode(cmdline_encoding, 'replace')
+ encoded_cmd.append(arg)
+ p = subprocess.Popen(encoded_cmd,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
if input:
- p.stdin.write(input)
+ p.stdin.write(input.encode(self.encoding))
p.stdin.close()
out = p.stdout.read()
err = p.stderr.read()