@@ -282,6 +282,9 @@ def wrapper():
282
282
283
283
_ExecInfo = namedtuple ("_ExecInfo" , "executable version" )
284
284
285
+ class ExecutableUnavailableError (FileNotFoundError ):
286
+ """Error raised when an executable that Matplotlib optionally depends on can't be found."""
287
+ pass
285
288
286
289
@functools .lru_cache ()
287
290
def _get_executable_info (name ):
@@ -307,7 +310,7 @@ def _get_executable_info(name):
307
310
308
311
Raises
309
312
------
310
- FileNotFoundError
313
+ ExecutableUnavailableError
311
314
If the executable is not found or older than the oldest version
312
315
supported by Matplotlib.
313
316
ValueError
@@ -319,25 +322,27 @@ def impl(args, regex, min_ver=None, ignore_exit_code=False):
319
322
# Search for a regex match in the output; if the match succeeds, the
320
323
# first group of the match is the version.
321
324
# 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 .
323
326
try :
324
327
output = subprocess .check_output (
325
328
args , stderr = subprocess .STDOUT , universal_newlines = True )
326
329
except subprocess .CalledProcessError as _cpe :
327
330
if ignore_exit_code :
328
331
output = _cpe .output
329
332
else :
330
- raise _cpe
333
+ raise ExecutableUnavailableError (str (_cpe )) from _cpe
334
+ except FileNotFoundError as _fnf :
335
+ raise ExecutableUnavailableError (str (_fnf )) from _fnf
331
336
match = re .search (regex , output )
332
337
if match :
333
338
version = LooseVersion (match .group (1 ))
334
339
if min_ver is not None and version < min_ver :
335
- raise FileNotFoundError (
340
+ raise ExecutableUnavailableError (
336
341
f"You have { args [0 ]} version { version } but the minimum "
337
342
f"version supported by Matplotlib is { min_ver } ." )
338
343
return _ExecInfo (args [0 ], version )
339
344
else :
340
- raise FileNotFoundError (
345
+ raise ExecutableUnavailableError (
341
346
f"Failed to determine the version of { args [0 ]} from "
342
347
f"{ ' ' .join (args )} , which output { output } " )
343
348
@@ -350,9 +355,9 @@ def impl(args, regex, min_ver=None, ignore_exit_code=False):
350
355
for e in execs :
351
356
try :
352
357
return impl ([e , "--version" ], "(.*)" , "9" )
353
- except FileNotFoundError :
358
+ except ExecutableUnavailableError :
354
359
pass
355
- raise FileNotFoundError ("Failed to find a Ghostscript installation" )
360
+ raise ExecutableUnavailableError ("Failed to find a Ghostscript installation" )
356
361
elif name == "inkscape" :
357
362
return impl (["inkscape" , "-V" ], "^Inkscape ([^ ]*)" )
358
363
elif name == "magick" :
@@ -380,7 +385,7 @@ def impl(args, regex, min_ver=None, ignore_exit_code=False):
380
385
else :
381
386
path = "convert"
382
387
if path is None :
383
- raise FileNotFoundError (
388
+ raise ExecutableUnavailableError (
384
389
"Failed to find an ImageMagick installation" )
385
390
<
8000
span class=pl-k>return impl ([path , "--version" ], r"^Version: ImageMagick (\S*)" )
386
391
elif name == "pdftops" :
@@ -389,7 +394,7 @@ def impl(args, regex, min_ver=None, ignore_exit_code=False):
389
394
if info and not ("3.0" <= info .version
390
395
# poppler version numbers.
391
396
or "0.9" <= info .version <= "1.0" ):
392
- raise FileNotFoundError (
397
+ raise ExecutableUnavailableError (
393
398
f"You have pdftops version { info .version } but the minimum "
394
399
f"version supported by Matplotlib is 3.0." )
395
400
return info
@@ -478,14 +483,14 @@ def checkdep_ps_distiller(s):
478
483
return False
479
484
try :
480
485
_get_executable_info ("gs" )
481
- except FileNotFoundError :
486
+ except ExecutableUnavailableError :
482
487
_log .warning (
483
488
"Setting rcParams['ps.usedistiller'] requires ghostscript." )
484
489
return False
485
490
if s == "xpdf" :
486
491
try :
487
492
_get_executable_info ("pdftops" )
488
- except FileNotFoundError :
493
+ except ExecutableUnavailableError :
489
494
_log .warning (
490
495
"Setting rcParams['ps.usedistiller'] to 'xpdf' requires xpdf." )
491
496
return False
@@ -500,12 +505,12 @@ def checkdep_usetex(s):
500
505
return False
501
506
try :
502
507
_get_executable_info ("dvipng" )
503
- except FileNotFoundError :
508
+ except ExecutableUnavailableError :
504
509
_log .warning ("usetex mode requires dvipng." )
505
510
return False
506
511
try :
507
512
_get_executable_info ("gs" )
508
- except FileNotFoundError :
513
+ except ExecutableUnavailableError :
509
514
_log .warning ("usetex mode requires ghostscript." )
510
515
return False
511
516
return True
0 commit comments