Skip to content

Commit 1414c28

Browse files
committed
Add PEP 519 support
1 parent 4e46319 commit 1414c28

File tree

5 files changed

+63
-11
lines changed

5 files changed

+63
-11
lines changed

lib/matplotlib/animation.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
import contextlib
3838
import tempfile
3939
import warnings
40-
from matplotlib.cbook import iterable, is_string_like
40+
from matplotlib.cbook import iterable, is_string_like, fspath_no_except
4141
from matplotlib.compat import subprocess
4242
from matplotlib import verbose
4343
from matplotlib import rcParams, rcParamsDefault, rc_context
@@ -281,6 +281,7 @@ def _run(self):
281281
output = sys.stdout
282282
else:
283283
output = subprocess.PIPE
284+
command = [fspath_no_except(cmd) for cmd in command]
284285
verbose.report('MovieWriter.run: running command: %s' %
285286
' '.join(command))
286287
self._proc = subprocess.Popen(command, shell=False,

lib/matplotlib/backends/backend_agg.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030
from matplotlib import verbose, rcParams
3131
from matplotlib.backend_bases import (RendererBase, FigureManagerBase,
3232
FigureCanvasBase)
33-
from matplotlib.cbook import is_string_like, maxdict, restrict_dict
33+
from matplotlib.cbook import (is_string_like, maxdict, restrict_dict,
34+
fspath_no_except, to_filehandle)
3435
from matplotlib.figure import Figure
3536
from matplotlib.font_manager import findfont, get_font
3637
from matplotlib.ft2font import (LOAD_FORCE_AUTOHINT, LOAD_NO_HINTING,
@@ -553,7 +554,10 @@ def print_png(self, filename_or_obj, *args, **kwargs):
553554
close = False
554555

555556
try:
556-
_png.write_png(renderer._renderer, filename_or_obj, self.figure.dpi)
557+
_png.write_png(
558+
renderer._renderer, fspath_no_except(filename_or_obj),
559+
self.figure.dpi
560+
)
557561
finally:
558562
if close:
559563
filename_or_obj.close()
@@ -606,7 +610,8 @@ def print_jpg(self, filename_or_obj, *args, **kwargs):
606610
if 'quality' not in options:
607611
options['quality'] = rcParams['savefig.jpeg_quality']
608612

609-
return background.save(filename_or_obj, format='jpeg', **options)
613+
return background.save(to_filehandle(filename_or_obj), format='jpeg',
614+
**options)
610615
print_jpeg = print_jpg
611616

612617
# add TIFF support
@@ -616,7 +621,7 @@ def print_tif(self, filename_or_obj, *args, **kwargs):
616621
return
617622
image = Image.frombuffer('RGBA', size, buf, 'raw', 'RGBA', 0, 1)
618623
dpi = (self.figure.dpi, self.figure.dpi)
619-
return image.save(filename_or_obj, format='tiff',
624+
return image.save(to_filehandle(filename_or_obj), format='tiff',
620625
dpi=dpi)
621626
print_tiff = print_tif
622627

lib/matplotlib/backends/backend_pdf.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
FigureManagerBase, FigureCanvasBase)
3535
from matplotlib.backends.backend_mixed import MixedModeRenderer
3636
from matplotlib.cbook import (Bunch, is_string_like, get_realpath_and_stat,
37-
is_writable_file_like, maxdict)
37+
is_writable_file_like, maxdict, fspath_no_except)
3838
from matplotlib.figure import Figure
3939
from matplotlib.font_manager import findfont, is_opentype_cff_font, get_font
4040
from matplotlib.afm import AFM
@@ -429,6 +429,7 @@ def __init__(self, filename):
429429
self.passed_in_file_object = False
430430
self.original_file_like = None
431431
self.tell_base = 0
432+
filename = fspath_no_except(filename)
432433
if is_string_like(filename):
433434
fh = open(filename, 'wb')
434435
elif is_writable_file_like(filename):

lib/matplotlib/cbook.py

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,7 @@ def to_filehandle(fname, flag='rU', return_opened=False):
756756
files is automatic, if the filename ends in .gz. *flag* is a
757757
read/write flag for :func:`file`
758758
"""
759+
fname = fspath_no_except(fname)
759760
if is_string_like(fname):
760761
if fname.endswith('.gz'):
761762
# get rid of 'U' in flag for gzipped files.
@@ -815,6 +816,7 @@ def get_sample_data(fname, asfileobj=True):
815816
root = matplotlib.rcParams['examples.directory']
816817
else:
817818
root = os.path.join(matplotlib._get_data_path(), 'sample_data')
819+
fname = fspath_no_except(fname)
818820
path = os.path.join(root, fname)
819821

820822
if asfileobj:
@@ -1019,6 +1021,7 @@ def __init__(self):
10191021
self._cache = {}
10201022

10211023
def __call__(self, path):
1024+
path = fspath_no_except(path)
10221025
result = self._cache.get(path)
10231026
if result is None:
10241027
realpath = os.path.realpath(path)
@@ -1173,7 +1176,7 @@ def listFiles(root, patterns='*', recurse=1, return_folders=0):
11731176
pattern_list = patterns.split(';')
11741177
results = []
11751178

1176-
for dirname, dirs, files in os.walk(root):
1179+
for dirname, dirs, files in os.walk(fspath_no_except(root)):
11771180
# Append to results all relevant files (and perhaps folders)
11781181
for name in files:
11791182
fullname = os.path.normpath(os.path.join(dirname, name))
@@ -1197,10 +1200,10 @@ def get_recursive_filelist(args):
11971200
files = []
11981201

11991202
for arg in args:
1200-
if os.path.isfile(arg):
1203+
if os.path.isfile(fspath_no_except(arg)):
12011204
files.append(arg)
12021205
continue
1203-
if os.path.isdir(arg):
1206+
if os.path.isdir(fspath_no_except(arg)):
12041207
newfiles = listFiles(arg, recurse=1, return_folders=1)
12051208
files.extend(newfiles)
12061209

@@ -1726,6 +1729,7 @@ def simple_linear_interpolation(a, steps):
17261729

17271730

17281731
def recursive_remove(path):
1732+
path = fspath_no_except(path)
17291733
if os.path.isdir(path):
17301734
for fname in (glob.glob(os.path.join(path, '*')) +
17311735
glob.glob(os.path.join(path, '.*'))):
@@ -2666,7 +2670,7 @@ class TimeoutError(RuntimeError):
26662670
pass
26672671

26682672
def __init__(self, path):
2669-
self.path = path
2673+
self.path = fspath_no_except(path)
26702674
self.end = "-" + str(os.getpid())
26712675
self.lock_path = os.path.join(self.path, self.LOCKFN + self.end)
26722676
self.pattern = os.path.join(self.path, self.LOCKFN + '-*')
@@ -2701,3 +2705,44 @@ def __exit__(self, exc_type, exc_value, traceback):
27012705
os.rmdir(path)
27022706
except OSError:
27032707
pass
2708+
2709+
2710+
try:
2711+
from os import fspath
2712+
except ImportError:
2713+
def fspath(path):
2714+
"""
2715+
Return the string representation of the path.
2716+
If str or bytes is passed in, it is returned unchanged.
2717+
This code comes from PEP 519, modified to support earlier versions of
2718+
python.
2719+
2720+
This is required for python < 3.6.
2721+
"""
2722+
if isinstance(path, (six.text_type, six.binary_type)):
2723+
return path
2724+
2725+
# Work from the object's type to match method resolution of other magic
2726+
# methods.
2727+
path_type = type(path)
2728+
try:
2729+
return path_type.__fspath__(path)
2730+
except AttributeError:
2731+
if hasattr(path_type, '__fspath__'):
2732+
raise
2733+
try:
2734+
import pathlib
2735+
except ImportError:
2736+
pass
2737+
else:
2738+
if isinstance(path, pathlib.PurePath):
2739+
return six.text_type(path)
2740+
2741+
raise TypeError("expected str, bytes or os.PathLike object, not "
2742+
+ path_type.__name__)
2743+
2744+
def fspath_no_except(path):
2745+
try:
2746+
return fspath(path)
2747+
except TypeError:
2748+
return path

lib/matplotlib/image.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ def contains(self, mouseevent):
525525
def write_png(self, fname):
526526
"""Write the image to png file with fname"""
527527
im = self.to_rgba(self._A, bytes=True, norm=False)
528-
_png.write_png(im, fname)
528+
_png.write_png(im, cbook.fspath_no_except(fname))
529529

530530
def set_data(self, A):
531531
"""

0 commit comments

Comments
 (0)