Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d55b6ed

Browse files
committed
Capture stderr to a file instead.
1 parent bd7865c commit d55b6ed

File tree

1 file changed

+25
-12
lines changed

1 file changed

+25
-12
lines changed

lib/matplotlib/testing/compare.py

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import re
1616
import shutil
1717
import sys
18+
from tempfile import TemporaryFile
1819

1920
import numpy as np
2021

@@ -132,8 +133,8 @@ def convert(old, new):
132133
return convert
133134

134135

135-
# Copied from https://bugs.python.org/issue25567
136-
_find_unsafe_bytes = re.compile(rb'[^\w@%+=:,./-]', re.ASCII).search
136+
# Modified from https://bugs.python.org/issue25567.
137+
_find_unsafe_bytes = re.compile(br'[^a-zA-Z0-9_@%+=:,./-]').search
137138

138139

139140
def _shlex_quote_bytes(b):
@@ -185,10 +186,15 @@ def __call__(self, orig, dest):
185186
env["DISPLAY"] = ""
186187
# Do not load any user options.
187188
env["INKSCAPE_PROFILE_DIR"] = os.devnull
189+
# Old versions of Inkscape (0.48.3.1, used on Travis as of now)
190+
# seem to sometimes deadlock when stderr is redirected to a pipe,
191+
# so we redirect it to a temporary file instead. This is not
192+
# necessary anymore as of Inkscape 0.92.1.
193+
self._stderr = TemporaryFile()
188194
self._proc = subprocess.Popen(
189195
[str("inkscape"), "--without-gui", "--shell"],
190-
env=env, stdin=subprocess.PIPE,
191-
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
196+
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
197+
stderr=self._stderr, env=env)
192198
if not self._read_to_prompt():
193199
raise OSError("Failed to start Inkscape")
194200

@@ -200,16 +206,23 @@ def __call__(self, orig, dest):
200206
def fsencode(s):
201207
return s.encode(sys.getfilesystemencoding())
202208

203-
orig, dest = map(_shlex_quote_bytes, map(fsencode, [orig, dest]))
204-
self._proc.stdin.write(orig + b" --export-png=" + dest + b"\n")
209+
orig_b, dest_b = map(_shlex_quote_bytes, map(fsencode, [orig, dest]))
210+
if b"\n" in orig_b or b"\n" in dest_b:
211+
# Who knows whether the current folder name has a newline, or if
212+
# our encoding is even ASCII compatible... Just fall back on the
213+
# slow solution.
214+
return make_external_conversion_command(lambda old, new: [
215+
str('inkscape'), '-z', old, '--export-png', new])(orig, dest)
216+
self._proc.stdin.write(orig_b + b" --export-png=" + dest_b + b"\n")
205217
self._proc.stdin.flush()
206218
if not self._read_to_prompt():
207-
# I *guess* we should technically decode the stream using
208-
# `getdefaultencoding` *except* for filenames which should be
209-
# decoded using `getfilesystemencoding` but that would be a bit
210-
# overkill.
219+
# Inkscape's output is not localized but gtk's is, so the
220+
# output stream probably has a mixed encoding. Using
221+
# `getfilesystemencoding` should at least get the filenames
222+
# right...
223+
self._stderr.seek(0)
211224
raise ImageComparisonFailure(
212-
self._proc.stderr.read().decode(
225+
self._stderr.read().decode(
213226
sys.getfilesystemencoding(), "replace"))
214227

215228
def __del__(self):
@@ -219,7 +232,7 @@ def __del__(self):
219232
self._proc.wait()
220233
self._proc.stdin.close()
221234
self._proc.stdout.close()
222-
self._proc.stderr.close()
235+
self._stderr.close()
223236

224237

225238
def _update_converter():

0 commit comments

Comments
 (0)