Skip to content

Commit b1f5c43

Browse files
authored
Merge pull request #10793 from anntzer/style3
A hodgepodge of Py3 & style fixes.
2 parents 464df4a + 144ba49 commit b1f5c43

File tree

9 files changed

+59
-121
lines changed

9 files changed

+59
-121
lines changed

examples/user_interfaces/fourier_demo_wx_sgskip.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,7 @@ def createPlots(self):
180180
# This method creates the subplots, waveforms and labels.
181181
# Later, when the waveforms or sliders are dragged, only the
182182
# waveform data will be updated (not here, but below in setKnob).
183-
if not hasattr(self, 'subplot1'):
184-
self.subplot1, self.subplot2 = self.figure.subplots(2)
183+
self.subplot1, self.subplot2 = self.figure.subplots(2)
185184
x1, y1, x2, y2 = self.compute(self.f0.value, self.A.value)
186185
color = (1., 0., 0.)
187186
self.lines += self.subplot1.plot(x1, y1, color=color, linewidth=2)

lib/matplotlib/animation.py

Lines changed: 37 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,21 @@
1515
# * Movies
1616
# * Can blit be enabled for movies?
1717
# * Need to consider event sources to allow clicking through multiple figures
18-
from __future__ import (absolute_import, division, print_function,
19-
unicode_literals)
2018

2119
import six
22-
from six.moves import zip
2320

2421
import abc
22+
import base64
2523
import contextlib
2624
from io import BytesIO
2725
import itertools
2826
import logging
2927
import os
28+
from pathlib import Path
3029
import platform
3130
import subprocess
3231
import sys
33-
import tempfile
32+
from tempfile import TemporaryDirectory
3433
import uuid
3534

3635
import numpy as np
@@ -39,11 +38,6 @@
3938
JS_INCLUDE)
4039
from matplotlib import cbook, rcParams, rcParamsDefault, rc_context
4140

42-
if six.PY2:
43-
from base64 import encodestring as encodebytes
44-
else:
45-
from base64 import encodebytes
46-
4741

4842
_log = logging.getLogger(__name__)
4943

@@ -383,8 +377,7 @@ def grab_frame(self, **savefig_kwargs):
383377
dpi=self.dpi, **savefig_kwargs)
384378
except (RuntimeError, IOError) as e:
385379
out, err = self._proc.communicate()
386-
_log.info('MovieWriter -- Error '
387-
'running proc:\n%s\n%s' % (out, err))
380+
_log.info('MovieWriter -- Error running proc:\n%s\n%s', out, err)
388381
raise IOError('Error saving animation to file (cause: {0}) '
389382
'Stdout: {1} StdError: {2}. It may help to re-run '
390383
'with logging level set to '
@@ -537,8 +530,7 @@ def grab_frame(self, **savefig_kwargs):
537530

538531
except RuntimeError:
539532
out, err = self._proc.communicate()
540-
_log.info('MovieWriter -- Error '
541-
'running proc:\n%s\n%s' % (out, err))
533+
_log.info('MovieWriter -- Error running proc:\n%s\n%s', out, err)
542534
raise
543535

544536
def finish(self):
@@ -669,7 +661,7 @@ def _args(self):
669661
# Logging is quieted because subprocess.PIPE has limited buffer size.
670662
# If you have a lot of frames in your animation and set logging to
671663
# DEBUG, you will have a buffer overrun.
672-
if (_log.getEffectiveLevel() > logging.DEBUG):
664+
if _log.getEffectiveLevel() > logging.DEBUG:
673665
args += ['-loglevel', 'quiet']
674666
args += ['-i', 'pipe:'] + self.output_args
675667
return args
@@ -903,7 +895,7 @@ def grab_frame(self, **savefig_kwargs):
903895
f = BytesIO()
904896
self.fig.savefig(f, format=self.frame_format,
905897
dpi=self.dpi, **savefig_kwargs)
906-
imgdata64 = encodebytes(f.getvalue()).decode('ascii')
898+
imgdata64 = base64.encodebytes(f.getvalue()).decode('ascii')
907899
self._total_bytes += len(imgdata64)
908900
if self._total_bytes >= self._bytes_limit:
909901
_log.warning(
@@ -1336,35 +1328,30 @@ def to_html5_video(self, embed_limit=None):
13361328
# Convert from MB to bytes
13371329
embed_limit *= 1024 * 1024
13381330

1339-
# First write the video to a tempfile. Set delete to False
1340-
# so we can re-open to read binary data.
1341-
with tempfile.NamedTemporaryFile(suffix='.m4v',
1342-
delete=False) as f:
1331+
# Can't open a NamedTemporaryFile twice on Windows, so use a
1332+
# TemporaryDirectory instead.
1333+
with TemporaryDirectory() as tmpdir:
1334+
path = Path(tmpdir, "temp.m4v")
13431335
# We create a writer manually so that we can get the
13441336
# appropriate size for the tag
13451337
Writer = writers[rcParams['animation.writer']]
13461338
writer = Writer(codec='h264',
13471339
bitrate=rcParams['animation.bitrate'],
13481340
fps=1000. / self._interval)
1349-
self.save(f.name, writer=writer)
1350-
1351-
# Now open and base64 encode
1352-
with open(f.name, 'rb') as video:
1353-
vid64 = encodebytes(video.read())
1354-
vid_len = len(vid64)
1355-
if vid_len >= embed_limit:
1356-
_log.warning(
1357-
"Animation movie is %s bytes, exceeding the limit of "
1358-
"%s. If you're sure you want a large animation "
1359-
"embedded, set the animation.embed_limit rc parameter "
1360-
"to a larger value (in MB).", vid_len, embed_limit)
1361-
else:
1362-
self._base64_video = vid64.decode('ascii')
1363-
self._video_size = 'width="{}" height="{}"'.format(
1364-
*writer.frame_size)
1365-
1366-
# Now we can remove
1367-
os.remove(f.name)
1341+
self.save(str(path), writer=writer)
1342+
# Now open and base64 encode.
1343+
vid64 = base64.encodebytes(path.read_bytes())
1344+
1345+
if len(vid64) >= embed_limit:
1346+
_log.warning(
1347+
"Animation movie is %s bytes, exceeding the limit of %s. "
1348+
"If you're sure you want a large animation embedded, set "
1349+
"the animation.embed_limit rc parameter to a larger value "
1350+
"(in MB).", vid_len, embed_limit)
1351+
else:
1352+
self._base64_video = vid64.decode('ascii')
1353+
self._video_size = 'width="{}" height="{}"'.format(
1354+
*writer.frame_size)
13681355

13691356
# If we exceeded the size, this attribute won't exist
13701357
if hasattr(self, '_base64_video'):
@@ -1392,25 +1379,18 @@ def to_jshtml(self, fps=None, embed_frames=True, default_mode=None):
13921379
if default_mode is None:
13931380
default_mode = 'loop' if self.repeat else 'once'
13941381

1395-
if hasattr(self, "_html_representation"):
1396-
return self._html_representation
1397-
else:
1398-
# Can't open a second time while opened on windows. So we avoid
1399-
# deleting when closed, and delete manually later.
1400-
with tempfile.NamedTemporaryFile(suffix='.html',
1401-
delete=False) as f:
1402-
self.save(f.name, writer=HTMLWriter(fps=fps,
1403-
embed_frames=embed_frames,
1404-
default_mode=default_mode))
1405-
# Re-open and get content
1406-
with open(f.name) as fobj:
1407-
html = fobj.read()
1408-
1409-
# Now we can delete
1410-
os.remove(f.name)
1411-
1412-
self._html_representation = html
1413-
return html
1382+
if not hasattr(self, "_html_representation"):
1383+
# Can't open a NamedTemporaryFile twice on Windows, so use a
1384+
# TemporaryDirectory instead.
1385+
with TemporaryDirectory() as tmpdir:
1386+
path = Path(tmpdir, "temp.html")
1387+
writer = HTMLWriter(fps=fps,
1388+
embed_frames=embed_frames,
1389+
default_mode=default_mode)
1390+
self.save(str(path), writer=writer)
1391+
self._html_representation = path.read_text()
1392+
1393+
return self._html_representation
14141394

14151395
def _repr_html_(self):
14161396
'''IPython display hook for rendering.'''

lib/matplotlib/axes/_base.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
from __future__ import (absolute_import, division, print_function,
2-
unicode_literals)
3-
41
from collections import OrderedDict
52

63
import six
@@ -836,12 +833,11 @@ def _update_transScale(self):
836833
self.transScale.set(
837834
mtransforms.blended_transform_factory(
838835
self.xaxis.get_transform(), self.yaxis.get_transform()))
839-
if hasattr(self, "lines"):
840-
for line in self.lines:
841-
try:
842-
line._transformed_path.invalidate()
843-
except AttributeError:
844-
pass
836+
for line in getattr(self, "lines", []): # Not set during init.
837+
try:
838+
line._transformed_path.invalidate()
839+
except AttributeError:
840+
pass
845841

846842
def get_position(self, original=False):
847843
"""

lib/matplotlib/backend_bases.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@
3232
The base class for the messaging area.
3333
"""
3434

35-
from __future__ import (absolute_import, division, print_function,
36-
unicode_literals)
37-
3835
import six
3936

4037
from contextlib import contextmanager
@@ -2062,9 +2059,8 @@ def _get_output_canvas(self, fmt):
20622059
If necessary, this function will switch to a registered backend that
20632060
supports the format.
20642061
"""
2065-
method_name = 'print_%s' % fmt
20662062
# Return the current canvas if it supports the requested format.
2067-
if hasattr(self, method_name):
2063+
if hasattr(self, 'print_{}'.format(fmt)):
20682064
return self
20692065
# Return a default canvas for the requested format, if it exists.
20702066
canvas_class = get_registered_canvas_class(fmt)

lib/matplotlib/backends/backend_webagg.py

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
"""
22
Displays Agg images in the browser, with interactivity
33
"""
4-
from __future__ import (absolute_import, division, print_function,
5-
unicode_literals)
64

75
# The WebAgg backend is divided into two modules:
86
#
@@ -13,12 +11,12 @@
1311
# - `backend_webagg.py` contains a concrete implementation of a basic
1412
# application, implemented with tornado.
1513

16-
import six
17-
1814
from contextlib import contextmanager
1915
import errno
16+
from io import BytesIO
2017
import json
2118
import os
19+
from pathlib import Path
2220
import random
2321
import sys
2422
import signal
@@ -63,14 +61,9 @@ class WebAggApplication(tornado.web.Application):
6361

6462
class FavIcon(tornado.web.RequestHandler):
6563
def get(self):
66-
image_path = os.path.join(
67-
os.path.dirname(os.path.dirname(__file__)),
68-
'mpl-data', 'images')
69-
7064
self.set_header('Content-Type', 'image/png')
71-
with open(os.path.join(image_path,
72-
'matplotlib.png'), 'rb') as fd:
73-
self.write(fd.read())
65+
image_path = Path(rcParams["datapath"], "images", "matplotlib.png")
66+
self.write(image_path.read_bytes())
7467

7568
class SingleFigurePage(tornado.web.RequestHandler):
7669
def __init__(self, application, request, **kwargs):
@@ -135,7 +128,7 @@ def get(self, fignum, fmt):
135128

136129
self.set_header('Content-Type', mimetypes.get(fmt, 'binary'))
137130

138-
buff = six.BytesIO()
131+
buff = BytesIO()
139132
manager.canvas.figure.savefig(buff, format=fmt)
140133
self.write(buff.getvalue())
141134

@@ -304,13 +297,9 @@ def ipython_inline_display(figure):
304297
if not webagg_server_thread.is_alive():
305298
webagg_server_thread.start()
306299

307-
with open(os.path.join(
308-
core.FigureManagerWebAgg.get_static_file_path(),
309-
'ipython_inline_figure.html')) as fd:
310-
tpl = fd.read()
311-
312300
fignum = figure.number
313-
301+
tpl = Path(core.FigureManagerWebAgg.get_static_file_path(),
302+
"ipython_inline_figure.html").read_text()
314303
t = tornado.template.Template(tpl)
315304
return t.generate(
316305
prefix=WebAggApplication.url_prefix,

lib/matplotlib/cbook/__init__.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
it imports matplotlib only at runtime.
77
"""
88

9-
from __future__ import absolute_import, division, print_function
10-
119
import six
1210
from six.moves import xrange, zip
1311
import bz2
@@ -470,7 +468,7 @@ def to_filehandle(fname, flag='rU', return_opened=False, encoding=None):
470468
files is automatic, if the filename ends in .gz. *flag* is a
471469
read/write flag for :func:`file`
472470
"""
473-
if hasattr(os, "PathLike") and isinstance(fname, os.PathLike):
471+
if isinstance(fname, getattr(os, "PathLike", ())):
474472
return to_filehandle(
475473
os.fspath(fname),
476474
flag=flag, return_opened=return_opened, encoding=encoding)
@@ -547,8 +545,7 @@ def get_sample_data(fname, asfileobj=True):
547545
path = os.path.join(root, fname)
548546

549547
if asfileobj:
550-
if (os.path.splitext(fname)[-1].lower() in
551-
('.csv', '.xrc', '.txt')):
548+
if os.path.splitext(fname)[-1].lower() in ['.csv', '.xrc', '.txt']:
552549
mode = 'r'
553550
else:
554551
mode = 'rb'

lib/matplotlib/tests/test_artist.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
from __future__ import absolute_import, division, print_function
2-
31
import io
4-
import warnings
52
from itertools import chain
3+
import warnings
64

75
import numpy as np
86

@@ -270,10 +268,7 @@ class TestArtist(martist.Artist):
270268
def set_f(self):
271269
pass
272270

273-
func = TestArtist.set_f
274-
if hasattr(func, '__func__'):
275-
func = func.__func__ # python 2 must write via __func__.__doc__
276-
func.__doc__ = """
271+
TestArtist.set_f.__doc__ = """
277272
Some text.
278273
279274
%s

lib/matplotlib/tests/test_simplification.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
from __future__ import absolute_import, division, print_function
2-
1+
import base64
32
import io
43

54
import numpy as np
@@ -265,15 +264,7 @@ def test_start_with_moveto():
265264
AABHqP//ej8AAD6z//+FPwAANb7//48/AAAsyf//lz8AACPU//+ePwAAGt///6M/AAAR6v//pj8A
266265
AAj1//+nPwAA/////w=="""
267266

268-
import base64
269-
if hasattr(base64, 'encodebytes'):
270-
# Python 3 case
271-
decodebytes = base64.decodebytes
272-
else:
273-
# Python 2 case
274-
decodebytes = base64.decodestring
275-
276-
verts = np.fromstring(decodebytes(data), dtype='<i4')
267+
verts = np.fromstring(base64.decodebytes(data), dtype='<i4')
277268
verts = verts.reshape((len(verts) // 2, 2))
278269
path = Path(verts)
279270
segs = path.iter_segments(transforms.IdentityTransform(),

tools/triage_tests.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,8 @@
2424
R: Reject test. Copy the expected result to the source tree.
2525
"""
2626

27-
from __future__ import unicode_literals
28-
2927
import os
28+
from pathlib import Path
3029
import shutil
3130
import sys
3231

@@ -272,11 +271,7 @@ def same(self, a, b):
272271
"""
273272
Returns True if two files have the same content.
274273
"""
275-
with open(a, 'rb') as fd:
276-
a_content = fd.read()
277-
with open(b, 'rb') as fd:
278-
b_content = fd.read()
279-
return a_content == b_content
274+
return Path(a).read_bytes() == Path(b).read_bytes()
280275

281276
def copy_file(self, a, b):
282277
"""

0 commit comments

Comments
 (0)