8000 Remove unnecessary calls to float() before division. by anntzer · Pull Request #10331 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

Remove unnecessary calls to float() before division. #10331

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/api/mathtext_asarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
r'some other string', color='red', fontsize=20, dpi=200)

fig = plt.figure()
fig.figimage(rgba1.astype(float)/255., 100, 100)
fig.figimage(rgba2.astype(float)/255., 100, 300)
fig.figimage(rgba1, 100, 100)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you remove the division by 255?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because we can display uint8 images just as well as float images, and the real point of the example is to show how to get the mathtext as an image array...

fig.figimage(rgba2, 100, 300)

plt.show()
4 changes: 2 additions & 2 deletions examples/color/color_cycle_default.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
colors = prop_cycle.by_key()['color']

lwbase = plt.rcParams['lines.linewidth']
thin = float('%.1f' % (lwbase / 2))
thin = lwbase / 2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By curiosity, was there a purpose to the former "rounding to 0.1" scheme?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably to make the title label look better(?), but I think 0.75 looks just fine too.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough, and I think the same

thick = lwbase * 3

fig, axs = plt.subplots(nrows=2, ncols=2, sharex=True, sharey=True)
Expand All @@ -29,7 +29,7 @@

axs[1, icol].set_facecolor('k')
axs[1, icol].xaxis.set_ticks(np.arange(0, 10, 2))
axs[0, icol].set_title('line widths (pts): %.1f, %.1f' % (lwx, lwy),
axs[0, icol].set_title('line widths (pts): %g, %g' % (lwx, lwy),
fontsize='medium')

for irow in range(2):
Expand Down
2 changes: 1 addition & 1 deletion examples/lines_bars_and_markers/stackplot_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def bump(a):
y = 2 * np.random.random() - .5
z = 10 / (.1 + np.random.random())
for i in range(m):
w = (i / float(m) - y) * z
w = (i / m - y) * z
a[i] += x * np.exp(-w * w)
a = np.zeros((m, n))
for i in range(n):
Expand Down
2 changes: 1 addition & 1 deletion examples/statistics/hist.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
N, bins, patches = axs[0].hist(x, bins=n_bins)

# We'll color code by height, but you could use any scalar
fracs = N.astype(float) / N.max()
fracs = N / N.max()

# we need to normalize the data to 0..1 for the full range of the colormap
norm = colors.Normalize(fracs.min(), fracs.max())
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/axes/_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6490,7 +6490,7 @@ def hist(self, x, bins=None, range=None, density=None, weights=None,
if stacked and density:
db = np.diff(bins)
for m in tops:
m[:] = (m.astype(float) / db) / tops[-1].sum()
m[:] = (m / db) / tops[-1].sum()
if cumulative:
slc = slice(None)
if cbook.is_numlike(cumulative) and cumulative < 0:
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/backends/backend_agg.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def draw_path(self, gc, path, transform, rgbFace=None):

if (nmax > 100 and npts > nmax and path.should_simplify and
rgbFace is None and gc.get_hatch() is None):
nch = np.ceil(npts / float(nmax))
nch = np.ceil(npts / nmax)
chsize = int(np.ceil(npts / nch))
i0 = np.arange(0, npts, chsize)
i1 = np.zeros_like(i0)
Expand Down
4 changes: 2 additions & 2 deletions lib/matplotlib/backends/backend_mixed.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ def stop_rasterizing(self):
# backends support this.
self._renderer.draw_image(
gc,
float(l) / self.dpi * self._figdpi,
(float(height)-b-h) / self.dpi * self._figdpi,
l * self._figdpi / self.dpi,
(height-b-h) * self._figdpi / self.dpi,
image)
self._raster_renderer = None
self._rasterizing = False
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/backends/backend_pdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -1282,7 +1282,7 @@ def writeGouraudTriangles(self):
flat_colors = colors.reshape((shape[0] * shape[1], 4))
points_min = np.min(flat_points, axis=0) - (1 << 8)
points_max = np.max(flat_points, axis=0) + (1 << 8)
factor = float(0xffffffff) / (points_max - points_min)
factor = 0xffffffff / (points_max - points_min)

self.beginStream(
ob.id, None,
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/backends/backend_ps.py
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,7 @@ def draw_gouraud_triangles(self, gc, points, colors, trans):
flat_colors = colors.reshape((shape[0] * shape[1], 4))
points_min = np.min(flat_points, axis=0) - (1 << 12)
points_max = np.max(flat_points, axis=0) + (1 << 12)
factor = np.ceil(float(2 ** 32 - 1) / (points_max - points_min))
factor = np.ceil((2 ** 32 - 1) / (points_max - points_min))

xmin, ymin = points_min
xmax, ymax = points_max
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/backends/backend_wx.py
Original file line number Diff line number Diff line change
Expand Up @@ -1099,7 +1099,7 @@ def _onMouseWheel(self, evt):
delta = evt.GetWheelDelta()
rotation = evt.GetWheelRotation()
rate = evt.GetLinesPerAction()
step = rate * float(rotation) / delta
step = rate * rotation / delta

# Done handling event
evt.Skip()
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -1315,7 +1315,7 @@ def __call__(self, value, clip=None):
for i, b in enumerate(self.boundaries):
iret[xx >= b] = i
if self._interp:
scalefac = float(self.Ncmap - 1) / (self.N - 2)
scalefac = (self.Ncmap - 1) / (self.N - 2)
iret = (iret * scalefac).astype(np.int16)
iret[xx < self.vmin] = -1
iret[xx >= self.vmax] = max_col
Expand Down
4 changes: 2 additions & 2 deletions lib/matplotlib/contour.py
Original file line number Diff line number Diff line change
Expand Up @@ -1563,8 +1563,8 @@ def _initialize_x_y(self, z):
x0, x1, y0, y1 = (0, Nx, 0, Ny)
else:
x0, x1, y0, y1 = self.extent
dx = float(x1 - x0) / Nx
dy = float(y1 - y0) / Ny
dx = (x1 - x0) / Nx
dy = (y1 - y0) / Ny
x = x0 + (np.arange(Nx) + 0.5) * dx
y = y0 + (np.arange(Ny) + 0.5) * dy
if self.origin == 'upper':
Expand Down
26 changes: 12 additions & 14 deletions lib/matplotlib/dates.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,23 +306,21 @@ def _from_ordinalf(x, tz=None):
if tz is None:
tz = _get_rc_timezone()

ix = int(x)
ix, remainder = divmod(x, 1)
ix = int(ix)
if ix < 1:
raise ValueError('cannot convert {} to a date. This '
'often happens if non-datetime values are passed to '
'an axis that expects datetime objects. '
.format(ix))
raise ValueError('Cannot convert {} to a date. This often happens if '
'non-datetime values are passed to an axis that '
'expects datetime objects.'.format(ix))
dt = datetime.datetime.fromordinal(ix).replace(tzinfo=UTC)

remainder = float(x) - ix

# Since the input date `x` float is unable to preserve microsecond
# precision of time representation in non-antique years, the
# resulting datetime is rounded to the nearest multiple of
# `musec_prec`. A value of 20 is appropriate for current dates.
musec_prec = 20
remainder_musec = int(round(remainder * MUSECONDS_PER_DAY /
float(musec_prec)) * musec_prec)
remainder_musec = int(round(remainder * MUSECONDS_PER_DAY / musec_prec)
* musec_prec)

# For people tryi 1241 ng to plot with full microsecond precision, enable
# an early-year workaround
Expand Down Expand Up @@ -1287,10 +1285,10 @@ def get_locator(self, dmin, dmax):
# these similar functions, and it's best to avoid doing our own math
# whenever possible.
numYears = float(delta.years)
numMonths = (numYears * MONTHS_PER_YEAR) + delta.months
numMonths = numYears * MONTHS_PER_YEAR + delta.months
numDays = tdelta.days # Avoids estimates of days/month, days/year
numHours = (numDays * HOURS_PER_DAY) + delta.hours
numMinutes = (numHours * MIN_PER_HOUR) + delta.minutes
numHours = numDays * HOURS_PER_DAY + delta.hours
numMinutes = numHours * MIN_PER_HOUR + delta.minutes
numSeconds = np.floor(tdelta.total_seconds())
numMicroseconds = np.floor(tdelta.total_seconds() * 1e6)

Expand Down Expand Up @@ -1745,14 +1743,14 @@ def seconds(s):
"""
Return seconds as days.
"""
return float(s) / SEC_PER_DAY
return s / SEC_PER_DAY


def minutes(m):
"""
Return minutes as days.
"""
return float(m) / MINUTES_PER_DAY
return m / MINUTES_PER_DAY


def hours(h):
Expand Down
6 changes: 3 additions & 3 deletions lib/matplotlib/figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,7 @@ def figimage(self, X,

if resize:
dpi = self.get_dpi()
figsize = [x / float(dpi) for x in (X.shape[1], X.shape[0])]
figsize = [x / dpi for x in (X.shape[1], X.shape[0])]
self.set_size_inches(figsize, forward=True)

im = FigureImage(self, cmap, norm, xo, yo, origin, **kwargs)
Expand Down Expand Up @@ -2288,9 +2288,9 @@ def figaspect(arg):
# Extract the aspect ratio of the array
if isarray:
nr, nc = arg.shape[:2]
arr_ratio = float(nr) / nc
arr_ratio = nr / nc
else:
arr_ratio = float(arg)
arr_ratio = arg

# Height of user figure defaults
fig_height = rcParams['figure.figsize'][1]
Expand Down
4 changes: 2 additions & 2 deletions lib/matplotlib/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -1453,8 +1453,8 @@ def thumbnail(infile, thumbfile, scale=0.1, interpolation='bilinear',
# need it for the mpl API
dpi = 100

height = float(rows)/dpi*scale
width = float(cols)/dpi*scale
height = rows / dpi * scale
width = cols / dpi * scale

extension = extout.lower()

Expand Down
4 changes: 2 additions & 2 deletions lib/matplotlib/mlab.py
Original file line number Diff line number Diff line change
Expand Up @@ -1667,7 +1667,7 @@ def __init__(self, a, standardize=True):
self.s = s**2

# and now the contribution of the individual components
vars = self.s/float(len(s))
vars = self.s / len(s)
self.fracs = vars/vars.sum()

def project(self, x, minfrac=0.):
Expand Down Expand Up @@ -2172,7 +2172,7 @@ def frange(xini, xfin=None, delta=None, **kw):
# compute # of points, spacing and return final list
try:
npts = kw['npts']
delta = (xfin-xini)/float(npts-endpoint)
delta = (xfin-xini) / (npts-endpoint)
except KeyError:
npts = int(np.round((xfin-xini)/delta)) + endpoint
# round finds the nearest, so the endpoint can be up to
Expand Down
14 changes: 7 additions & 7 deletions lib/matplotlib/patches.py
Original file line number Diff line number Diff line change
Expand Up @@ -1085,7 +1085,7 @@ def _recompute_path(self):
# Partial annulus needs to draw the outer ring
# followed by a reversed and scaled inner ring
v1 = arc.vertices
v2 = arc.vertices[::-1] * float(self.r - self.width) / self.r
v2 = arc.vertices[::-1] * (self.r - self.width) / self.r
v = np.vstack([v1, v2, v1[0, :], (0, 0)])
c = np.hstack([arc.codes, arc.codes, connector, Path.CLOSEPOLY])
c[len(arc.codes)] = connector
Expand Down Expand Up @@ -1179,8 +1179,8 @@ def __init__(self, x, y, dx, dy, width=1.0, **kwargs):
L = np.hypot(dx, dy)

if L != 0:
cx = float(dx) / L
sx = float(dy) / L
cx = dx / L
sx = dy / L
else:
# Account for division by zero
cx, sx = 0, 1
Expand Down Expand Up @@ -1286,12 +1286,12 @@ def __init__(self, x, y, dx, dy, width=0.001, length_includes_head=False,
else:
raise ValueError("Got unknown shape: %s" % shape)
if distance != 0:
cx = float(dx) / distance
sx = float(dy) / distance
cx = dx / distance
sx = dy / distance
else:
#Account for division by zero
# Account for division by zero
cx, sx = 0, 1
M = np.array([[cx, sx], [-sx, cx]])
M = [[cx, sx], [-sx, cx]]
verts = np.dot(coords, M) + (x + dx, y + dy)

Polygon.__init__(self, list(map(tuple, verts)), closed=True, **kwargs)
Expand Down
4 changes: 2 additions & 2 deletions lib/matplotlib/streamplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,8 @@ def __init__(self, grid, mask):
self.grid = grid
self.mask = mask
# Constants for conversion between grid- and mask-coordinates
self.x_grid2mask = float(mask.nx - 1) / grid.nx
self.y_grid2mask = float(mask.ny - 1) / grid.ny
self.x_grid2mask = (mask.nx - 1) / grid.nx
self.y_grid2mask = (mask.ny - 1) / grid.ny

self.x_mask2grid = 1. / self.x_grid2mask
self.y_mask2grid = 1. / self.y_grid2mask
Expand Down
8 changes: 2 additions & 6 deletions lib/matplotlib/testing/compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,12 +367,8 @@ def calculate_rms(expectedImage, actualImage):
raise ImageComparisonFailure(
"Image sizes do not match expected size: {0} "
"actual size {1}".format(expectedImage.shape, actualImage.shape))
num_values = expectedImage.size
abs_diff_image = abs(expectedImage - actualImage)
histogram = np.bincount(abs_diff_image.ravel(), minlength=256)
sum_of_squares = np.sum(histogram * np.arange(len(histogram)) ** 2)
rms = np.sqrt(float(sum_of_squares) / num_values)
return rms
# Convert to float to avoid overflowing finite integer types.
return np.sqrt(((expectedImage - actualImage).astype(float) ** 2).mean())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is seems to be a substantive change to a genuine RMS, from something I don't understand. There must have been a reason for the convoluted original.

Copy link
Contributor Author
@anntzer anntzer Jan 28, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the original either, but the relevant tests (which check for exact return values of this function) are still passing...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ours are, but I suspect this might cause problems for packagers who put in larger tolerances than ours, as I believe some do. Therefore I recommend sticking to the original algorithm for the purposes of this PR. Perhaps add a comment that this is not a simple rms. @mdboom can probably tell us the rationale for the algorithm.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAICT the results should be the same: the old method counted, for each delta, the number of pixels that have this delta value, then computed a RMS based on that histogram.
Again, https://github.com/matplotlib/matplotlib/pull/10335/files shows tests where we check that the reported RMS values are stable to 1e-4.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I am correctly expressing the two algorithms below, then their results are not the same:

In [26]: x = np.zeros(1000, dtype=int); x[0] = 1

In [27]: h = np.bincount(x, minlength=256)

In [28]: np.sqrt(((h * np.arange(len(h)))**2).mean())
0.0625

In [29]: np.sqrt((x**2).mean())
0.031622776601683791

In [30]: x[:10]
array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0])

In [31]: (h * np.arange(len(h)))[:10]
array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0])

In [32]: len(x)
1000

In [33]: len(h)
256

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the previous algorithm was dividing by num_values (so sum() / len(x) in your case, not mean()). this fix shows that the values are indentical.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops... sorry I missed that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I can run the Cartopy test suite without any issue using this PR.



def compare_images(expected, actual, tol, in_decorator=False):
Expand Down
4 changes: 2 additions & 2 deletions lib/matplotlib/testing/jpl_units/Duration.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ def __div__( self, rhs ):
= RETURN VALUE
- Returns the scaled Duration.
"""
return Duration( self._frame, self._seconds / float( rhs ) )
return Duration( self._frame, self._seconds / rhs )

#-----------------------------------------------------------------------
def __rdiv__( self, rhs ):
Expand All @@ -178,7 +178,7 @@ def __rdiv__( self, rhs ):
= RETURN VALUE
- Returns the scaled Duration.
"""
return Duration( self._frame, float( rhs ) / self._seconds )
return Duration( self._frame, rhs / self._seconds )

#-----------------------------------------------------------------------
def __str__( self ):
Expand Down
4 changes: 2 additions & 2 deletions lib/matplotlib/tests/test_collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,8 +453,8 @@ def test_EllipseCollection():
X, Y = np.meshgrid(x, y)
XY = np.vstack((X.ravel(), Y.ravel())).T

ww = X/float(x[-1])
hh = Y/float(y[-1])
ww = X / x[-1]
hh = Y / y[-1]
aa = np.ones_like(ww) * 20 # first axis is 20 degrees CCW from x axis

ec = mcollections.EllipseCollection(ww, hh, aa,
Expand Down
6 changes: 3 additions & 3 deletions lib/matplotlib/tests/test_mlab.py
Original file line number Diff line number Diff line change
Expand Up @@ -2435,7 +2435,7 @@ def test_contiguous_regions():
def test_psd_onesided_norm():
u = np.array([0, 1, 2, 3, 1, 2, 1])
dt = 1.0
Su = np.abs(np.fft.fft(u) * dt)**2 / float(dt * u.size)
Su = np.abs(np.fft.fft(u) * dt)**2 / (dt * u.size)
P, f = mlab.psd(u, NFFT=u.size, Fs=1/dt, window=mlab.window_none,
detrend=mlab.detrend_none, noverlap=0, pad_to=None,
scale_by_freq=None,
Expand All @@ -2445,10 +2445,10 @@ def test_psd_onesided_norm():


def test_psd_oversampling():
"""Test the case len(x) < NFFT for psd(). """
"""Test the case len(x) < NFFT for psd()."""
u = np.array([0, 1, 2, 3, 1, 2, 1])
dt = 1.0
Su = np.abs(np.fft.fft(u) * dt)**2 / float(dt * u.size)
Su = np.abs(np.fft.fft(u) * dt)**2 / (dt * u.size)
P, f = mlab.psd(u, NFFT=u.size*2, Fs=1/dt, window=mlab.window_none,
detrend=mlab.detrend_none, noverlap=0, pad_to=None,
scale_by_freq=None,
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/textpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def get_text_width_height_descent(self, s, prop, ismath):
return w, h, d

fontsize = prop.get_size_in_points()
scale = float(fontsize) / self.FONT_SCALE
scale = fontsize / self.FONT_SCALE

if ismath:
prop = prop.copy()
Expand Down
4 changes: 2 additions & 2 deletions lib/matplotlib/ticker.py
Original file line number Diff line number Diff line change
Expand Up @@ -1573,7 +1573,7 @@ def tick_values(self, vmin, vmax):
"""
if self.nbins is None:
return self.locs
step = max(int(0.99 + len(self.locs) / float(self.nbins)), 1)
step = max(int(np.ceil(len(self.locs) / self.nbins)), 1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this change the results in rare cases? It does look nicer, though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. I think the code really, really looks like it was written by someone who meant ceil but didn't remember that function existed.
  2. For the change to actually matter you need a) to use bins with FixedLocator, which seems to be quite rare in my experience, and b) at least 99 ticks and 100 bins (to fall in the "edge" region), which is also quite rare...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll go along with this one.

ticks = self.locs[::step]
for i in range(1, step):
ticks1 = self.locs[i::step]
Expand Down Expand Up @@ -2323,7 +2323,7 @@ def get_log_range(lo, hi):
total_ticks = (a_range[1] - a_range[0]) + (c_range[1] - c_range[0])
if has_b:
total_ticks += 1
stride = max(np.floor(float(total_ticks) / (self.numticks - 1)), 1)
stride = max(total_ticks // (self.numticks - 1), 1)

decades = []
if has_a:
Expand Down
2 changes: 1 addition & 1 deletion lib/mpl_toolkits/axes_grid1/axes_size.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ def from_any(size, fraction_ref=None):
return Fixed(size)
elif isinstance(size, six.string_types):
if size[-1] == "%":
return Fraction(float(size[:-1])/100., fraction_ref)
return Fraction(float(size[:-1]) / 100, fraction_ref)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason this float remains?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because the purpose here is to convert "3%' to 0.03? :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. Sorry, I didn't pay enough attention to the context.


raise ValueError("Unknown format")

Expand Down
Loading
0