@@ -282,6 +282,9 @@ def wrapper():
282282
283283_ExecInfo = namedtuple ("_ExecInfo" , "executable version" )
284284
285+ class ExecutableUnavailableError (FileNotFoundError ):
286+ """Error raised when an executable that Matplotlib optionally depends on can't be found."""
287+ pass
285288
286289@functools .lru_cache ()
287290def _get_executable_info (name ):
@@ -307,7 +310,7 @@ def _get_executable_info(name):
307310
308311 Raises
309312 ------
310- FileNotFoundError
313+ ExecutableUnavailableError
311314 If the executable is not found or older than the oldest version
312315 supported by Matplotlib.
313316 ValueError
@@ -319,25 +322,27 @@ def impl(args, regex, min_ver=None, ignore_exit_code=False):
319322 # Search for a regex match in the output; if the match succeeds, the
320323 # first group of the match is the version.
321324 # Return an _ExecInfo if the executable exists, and has a version of
322- # at least min_ver (if set); else, raise FileNotFoundError .
325+ # at least min_ver (if set); else, raise ExecutableUnavailableError .
323326 try :
324327 output = subprocess .check_output (
325328 args , stderr = subprocess .STDOUT , universal_newlines = True )
326329 except subprocess .CalledProcessError as _cpe :
327330 if ignore_exit_code :
328331 output = _cpe .output
329332 else :
330- raise _cpe
333+ raise ExecutableUnavailableError (str (_cpe )) from _cpe
334+ except FileNotFoundError as _fnf :
335+ raise ExecutableUnavailableError (str (_fnf )) from _fnf
331336 match = re .search (regex , output )
332337 if match :
333338 version = LooseVersion (match .group (1 ))
334339 if min_ver is not None and version < min_ver :
335- raise FileNotFoundError (
340+ raise ExecutableUnavailableError (
336341 f"You have { args [0 ]} version { version } but the minimum "
337342 f"version supported by Matplotlib is { min_ver } ." )
338343 return _ExecInfo (args [0 ], version )
339344 else :
340- raise FileNotFoundError (
345+ raise ExecutableUnavailableError (
341346 f"Failed to determine the version of { args [0 ]} from "
342347 f"{ ' ' .join (args )} , which output { output } " )
343348
@@ -350,9 +355,9 @@ def impl(args, regex, min_ver=None, ignore_exit_code=False):
350355 for e in execs :
351356 try :
352357 return impl ([e , "--version" ], "(.*)" , "9" )
353- except FileNotFoundError :
358+ except ExecutableUnavailableError :
354359 pass
355- raise FileNotFoundError ("Failed to find a Ghostscript installation" )
360+ raise ExecutableUnavailableError ("Failed to find a Ghostscript installation" )
356361 elif name == "inkscape" :
357362 return impl (["inkscape" , "-V" ], "^Inkscape ([^ ]*)" )
358363 elif name == "magick" :
@@ -380,7 +385,7 @@ def impl(args, regex, min_ver=None, ignore_exit_code=False):
380385 else :
381386 path = "convert"
382387 if path is None :
383- raise FileNotFoundError (
388+ raise ExecutableUnavailableError (
384389 "Failed to find an ImageMagick installation" )
385390 return impl ([path , "--version" ], r"^Version: ImageMagick (\S*)" )
386391 elif name == "pdftops" :
@@ -389,7 +394,7 @@ def impl(args, regex, min_ver=None, ignore_exit_code=False):
389394 if info and not ("3.0" <= info .version
390395 # poppler version numbers.
391396 or "0.9" <= info .version <= "1.0" ):
392- raise FileNotFoundError (
397+ raise ExecutableUnavailableError (
393398 f"You have pdftops version { info .version } but the minimum "
394399 f"version supported by Matplotlib is 3.0." )
395400 return info
@@ -478,14 +483,14 @@ def checkdep_ps_distiller(s):
478483 return False
479484 try :
480485 _get_executable_info ("gs" )
481- except FileNotFoundError :
486+ except ExecutableUnavailableError :
482487 _log .warning (
483488 "Setting rcParams['ps.usedistiller'] requires ghostscript." )
484489 return False
485490 if s == "xpdf" :
486491 try :
487492 _get_executable_info ("pdftops" )
488- except FileNotFoundError :
493+ except ExecutableUnavailableError :
489494 _log .warning (
490495 "Setting rcParams['ps.usedistiller'] to 'xpdf' requires xpdf." )
491496 return False
@@ -500,12 +505,12 @@ def checkdep_usetex(s):
500505 return False
501506 try :
502507 _get_executable_info ("dvipng" )
503- except FileNotFoundError :
508+ except ExecutableUnavailableError :
504509 _log .warning ("usetex mode requires dvipng." )
505510 return False
506511 try :
507512 _get_executable_info ("gs" )
508- except FileNotFoundError :
513+ except ExecutableUnavailableError :
509514 _log .warning ("usetex mode requires ghostscript." )
510515 return False
511516 return True
0 commit comments