8000 Add _check_isinstance helper. · matplotlib/matplotlib@63b7515 · GitHub
[go: up one dir, main page]

Skip to content

Commit 63b7515

Browse files
committed
Add _check_isinstance helper.
Does the same as _check_in_list... but for isinstance checks. A large number of checks for Normalize were grouped into `ScalarMappable.set_norm`.
1 parent 0536a66 commit 63b7515

19 files changed

+83
-94
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Exception changes
2+
`````````````````
3+
4+
Various APIs that raised a `ValueError` for incorrectly typed inputs now raise
5+
`TypeError` instead: `backend_bases.GraphicsContextBase.set_clip_path`,
6+
`blocking_input.BlockingInput.__call__`, `cm.register_cmap`, `dviread.DviFont`,
7+
`rcsetup.validate_hatch`, `rcsetup.validate_animation_writer_path`, `spines.Spine`,
8+
many classes in the :mod:`matplotlib.transforms` module and :mod:`matplotlib.tri`
9+
package, and Axes methods that take a ``norm`` parameter.

lib/matplotlib/axes/_axes.py

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4454,9 +4454,6 @@ def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
44544454
collection.update(kwargs)
44554455

44564456
if colors is None:
4457-
if norm is not None and not isinstance(norm, mcolors.Normalize):
4458-
raise ValueError(
4459-
"'norm' must be an instance of 'mcolors.Normalize'")
44604457
collection.set_array(c)
44614458
collection.set_cmap(cmap)
44624459
collection.set_norm(norm)
@@ -4770,11 +4767,6 @@ def hexbin(self, x, y, C=None, gridsize=100, bins=None,
47704767
offset_position="data"
47714768
)
47724769

4773-
# Check for valid norm
4774-
if norm is not None and not isinstance(norm, mcolors.Normalize):
4775-
msg = "'norm' must be an instance of 'mcolors.Normalize'"
4776-
raise ValueError(msg)
4777-
47784770
# Set normalizer if bins is 'log'
47794771
if bins == 'log':
47804772
if norm is not None:
@@ -5590,9 +5582,6 @@ def imshow(self, X, cmap=None, norm=None, aspect=None,
55905582
`~matplotlib.pyplot.imshow` expects RGB images adopting the straight
55915583
(unassociated) alpha representation.
55925584
"""
5593-
if norm is not None and not isinstance(norm, mcolors.Normalize):
5594-
raise ValueError(
5595-
"'norm' must be an instance of 'mcolors.Normalize'")
55965585
if aspect is None:
55975586
aspect = rcParams['image.aspect']
55985587
self.set_aspect(aspect)
@@ -5882,9 +5871,6 @@ def pcolor(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
58825871

58835872
collection.set_alpha(alpha)
58845873
collection.set_array(C)
5885-
if norm is not None and not isinstance(norm, mcolors.Normalize):
5886-
raise ValueError(
5887-
"'norm' must be an instance of 'mcolors.Normalize'")
58885874
collection.set_cmap(cmap)
58895875
collection.set_norm(norm)
58905876
collection.set_clim(vmin, vmax)
@@ -6099,9 +6085,6 @@ def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
60996085
**kwargs)
61006086
collection.set_alpha(alpha)
61016087
collection.set_array(C)
6102-
if norm is not None and not isinstance(norm, mcolors.Normalize):
6103-
raise ValueError(
6104-
"'norm' must be an instance of 'mcolors.Normalize'")
61056088
collection.set_cmap(cmap)
61066089
collection.set_norm(norm)
61076090
collection.set_clim(vmin, vmax)
@@ -6238,11 +6221,7 @@ def pcolorfast(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
62386221
Notes
62396222
-----
62406223
.. [notes section required to get data note injection right]
6241-
62426224
"""
6243-
if norm is not None and not isinstance(norm, mcolors.Normalize):
6244-
raise ValueError(
6245-
"'norm' must be an instance of 'mcolors.Normalize'")
62466225

62476226
C = args[-1]
62486227
nr, nc = np.shape(C)[:2]

lib/matplotlib/axis.py

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1631,9 +1631,7 @@ def set_major_formatter(self, formatter):
16311631
----------
16321632
formatter : ~matplotlib.ticker.Formatter
16331633
"""
1634-
if not isinstance(formatter, mticker.Formatter):
1635-
raise TypeError("formatter argument should be instance of "
1636-
"matplotlib.ticker.Formatter")
1634+
cbook._check_isinstance(mticker.Formatter, formatter=formatter)
16371635
self.isDefault_majfmt = False
16381636
self.major.formatter = formatter
16391637
formatter.set_axis(self)
@@ -1647,9 +1645,7 @@ def set_minor_formatter(self, formatter):
16471645
----------
16481646
formatter : ~matplotlib.ticker.Formatter
16491647
"""
1650-
if not isinstance(formatter, mticker.Formatter):
1651-
raise TypeError("formatter argument should be instance of "
1652-
"matplotlib.ticker.Formatter")
1648+
cbook._check_isinstance(mticker.Formatter, formatter=formatter)
16531649
self.isDefault_minfmt = False
16541650
self.minor.formatter = formatter
16551651
formatter.set_axis(self)
@@ -1663,9 +1659,7 @@ def set_major_locator(self, locator):
16631659
----------
16641660
locator : ~matplotlib.ticker.Locator
16651661
"""
1666-
if not isinstance(locator, mticker.Locator):
1667-
raise TypeError("locator argument should be instance of "
1668-
"matplotlib.ticker.Locator")
1662+
cbook._check_isinstance(mticker.Locator, locator=locator)
16691663
self.isDefault_majloc = False
16701664
self.major.locator = locator
16711665
if self.major.formatter:
@@ -1681,9 +1675,7 @@ def set_minor_locator(self, locator):
16811675
----------
16821676
locator : ~matplotlib.ticker.Locator
16831677
"""
1684-
if not isinstance(locator, mticker.Locator):
1685-
raise TypeError("locator argument should be instance of "
1686-
"matplotlib.ticker.Locator")
1678+
cbook._check_isinstance(mticker.Locator, locator=locator)
16871679
self.isDefault_minloc = False
16881680
self.minor.locator = locator
16891681
if self.minor.formatter:

lib/matplotlib/backend_bases.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -879,13 +879,13 @@ def set_clip_rectangle(self, rectangle):
879879

880880
def set_clip_path(self, path):
881881
"""
882-
Set the clip path and transformation. Path should be a
883-
:class:`~matplotlib.transforms.TransformedPath` instance.
882+
Set the clip path and transformation.
883+
884+
Parameters
885+
----------
886+
path : `~matplotlib.transforms.TransformedPath` or None
884887
"""
885-
if (path is not None
886-
and not isinstance(path, transforms.TransformedPath)):
887-
raise ValueError("Path should be a "
888-
"matplotlib.transforms.TransformedPath instance")
888+
cbook._check_isinstance((transforms.TransformedPath, None), path=path)
889889
self._clippath = path
890890

891891
def set_dashes(self, dash_offset, dash_list):

lib/matplotlib/blocking_input.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import logging
2323
from numbers import Integral
2424

25+
from matplotlib import cbook
2526
import matplotlib.lines as mlines
2627

2728
_log = logging.getLogger(__name__)
@@ -76,8 +77,7 @@ def pop_event(self, index=-1):
7677

7778
def __call__(self, n=1, timeout=30):
7879
"""Blocking call to retrieve *n* events."""
79-
if not isinstance(n, Integral):
80-
raise ValueError("Requires an integer argument")
80+
cbook._check_isinstance(Integral, n=n)
8181
self.n = n
8282
self.events = []
8383

lib/matplotlib/category.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717

1818
import numpy as np
1919

20-
import matplotlib.units as units
21-
import matplotlib.ticker as ticker
20+
from matplotlib import cbook, ticker, units
2221

2322

2423
_log = logging.getLogger(__name__)
@@ -204,8 +203,7 @@ def update(self, data):
204203
convertible = True
205204
for val in OrderedDict.fromkeys(data):
206205
# OrderedDict just iterates over unique values in data.
207-
if not isinstance(val, (str, bytes)):
208-
raise TypeError("{val!r} is not a string".format(val=val))
206+
cbook._check_isinstance((str, bytes), value=val)
209207
if convertible:
210208
# this will only be called so long as convertible is True.
211209
convertible = self._str_is_convertible(val)

lib/matplotlib/cbook/__init__.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2011,6 +2011,40 @@ def _check_and_log_subprocess(command, logger, **kwargs):
20112011
return report
20122012

20132013

2014+
def _check_isinstance(types, ** F438 kwargs):
2015+
"""
2016+
For each *key, value* pair in *kwargs*, check that *value* is an instance
2017+
of one of *types*; if not, raise an appropriate TypeError.
2018+
2019+
As a special case, a ``None`` entry in *types* is treated as NoneType.
2020+
2021+
Examples
2022+
--------
2023+
>>> cbook._check_isinstance((SomeClass, None), arg=arg)
2024+
"""
2025+
if isinstance(types, type) or types is None:
2026+
types = (types,)
2027+
none_allowed = None in types
2028+
types = tuple(tp for tp in types if tp is not None)
2029+
2030+
def type_name(tp):
2031+
return (tp.__qualname__ if tp.__module__ == "builtins"
2032+
else f"{tp.__module__}.{tp.__qualname__}")
2033+
2034+
names = [*map(type_name, types)]
2035+
if none_allowed:
2036+
types = (*types, type(None))
2037+
names.append("None")
2038+
for k, v in kwargs.items():
2039+
if not isinstance(v, types):
2040+
raise TypeError(
2041+
"{!r} must be an instance of {}, not a {}".format(
2042+
k,
2043+
", ".join(names[:-1]) + " or " + names[-1]
2044+
if len(names) > 1 else names[0],
2045+
type_name(type(v))))
2046+
2047+
20142048
def _check_in_list(values, **kwargs):
20152049
"""
20162050
For each *key, value* pair in *kwargs*, check that *value* is in *values*;

lib/matplotlib/cm.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,21 +130,16 @@ def register_cmap(name=None, cmap=None, data=None, lut=None):
130130
In the second case, the three arguments are passed to
131131
the :class:`~matplotlib.colors.LinearSegmentedColormap` initializer,
132132
and the resulting colormap is registered.
133-
134133
"""
134+
cbook._check_isinstance((str, None), name=name)
135135
if name is None:
136136
try:
137137
name = cmap.name
138138
except AttributeError:
139139
raise ValueError("Arguments must include a name or a Colormap")
140-
141-
if not isinstance(name, str):
142-
raise ValueError("Colormap name must be a string")
143-
144140
if isinstance(cmap, colors.Colormap):
145141
cmap_d[name] = cmap
146142
return
147-
148143
# For the remainder, let exceptions propagate.
149144
if lut is None:
150145
lut = mpl.rcParams['image.lut']
@@ -362,6 +357,7 @@ def set_norm(self, norm):
362357
on the colorbar to default.
363358
364359
"""
360+
cbook._check_isinstance((colors.Normalize, None), norm=norm)
365361
if norm is None:
366362
norm = colors.Normalize()
367363
self.norm = norm

lib/matplotlib/dviread.py

Lines changed: 1 addition & 3 deletions
10000
Original file line numberDiff line numberDiff line change
@@ -525,9 +525,7 @@ class DviFont:
525525
__slots__ = ('texname', 'size', 'widths', '_scale', '_vf', '_tfm')
526526

527527
def __init__(self, scale, tfm, texname, vf):
528-
if not isinstance(texname, bytes):
529-
raise ValueError("texname must be a bytestring, got %s"
530-
% type(texname))
528+
cbook._check_isinstance(bytes, texname=texname)
531529
self._scale = scale
532530
self._tfm = tfm
533531
self.texname = texname

lib/matplotlib/figure.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,7 @@ def add(self, key, a):
123123
"""
124124
# All the error checking may be unnecessary; but this method
125125
# is called so seldom that the overhead is negligible.
126-
if not isinstance(a, Axes):
127-
raise ValueError("second argument, {!r}, is not an Axes".format(a))
126+
cbook._check_isinstance(Axes, a=a)
128127
try:
129128
hash(key)
130129
except TypeError:

lib/matplotlib/rcsetup.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -738,10 +738,10 @@ def validate_hatch(s):
738738
Validate a hatch pattern.
739739
A hatch pattern string can have any sequence of the following
740740
characters: ``\ / | - + * . x o O``.
741-
742741
"""
743742
if not isinstance(s, str):
744743
raise ValueError("Hatch pattern must be a string")
744+
cbook._check_isinstance(str, hatch_pattern=s)
745745
unknown = set(s) - {'\\', '/', '|', '-', '+', '*', '.', 'x', 'o', 'O'}
746746
if unknown:
747747
raise ValueError("Unknown hatch symbol(s): %s" % list(unknown))
@@ -955,8 +955,7 @@ def validate_animation_writer_path(p):
955955
# Make sure it's a string and then figure out if the animations
956956
# are already loaded and reset the writers (which will validate
957957
# the path on next call)
958-
if not isinstance(p, str):
959-
raise ValueError("path must be a (unicode) string")
958+
cbook._check_isinstance(str, path=p)
960959
from sys import modules
961960
# set dirty, so that the next call to the registry will re-evaluate
962961
# the state.

lib/matplotlib/spines.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,7 @@ def __init__(self, axes, spine_type, path, **kwargs):
6262
# non-rectangular axes is currently implemented, and this lets
6363
# them pass through the spines machinery without errors.)
6464
self._position = None
65-
if not isinstance(path, matplotlib.path.Path):
66-
raise ValueError(
67-
"'path' must be an instance of 'matplotlib.path.Path'")
65+
cbook._check_isinstance(matplotlib.path.Path, path=path)
6866
self._path = path
6967

7068
# To support drawing both linear and circular spines, this

lib/matplotlib/table.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -360,8 +360,7 @@ def __setitem__(self, position, cell):
360360
"""
361361
Set a custom cell in a given position.
362362
"""
363-
if not isinstance(cell, CustomCell):
364-
raise TypeError('Table only accepts CustomCell')
363+
cbook._check_isinstance(CustomCell, cell=cell)
365364
try:
366365
row, col = position[0], position[1]
367366
except Exception:

lib/matplotlib/transforms.py

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -989,9 +989,7 @@ def __init__(self, bbox, transform, **kwargs):
989989
"""
990990
if not bbox.is_bbox:
991991
raise ValueError("'bbox' is not a bbox")
992-
if not isinstance(transform, Transform):
993-
raise ValueError("'transform' must be an instance of "
994-
"'matplotlib.transform.Transform'")
992+
cbook._check_isinstance(Transform, transform=transform)
995993
if transform.input_dims != 2 or transform.output_dims != 2:
996994
raise ValueError(
997995
"The input and output dimensions of 'transform' must be 2")
@@ -1586,9 +1584,7 @@ def __init__(self, child):
15861584
*child*: A class:`Transform` instance. This child may later
15871585
be replaced with :meth:`set`.
15881586
"""
1589-
if not isinstance(child, Transform):
1590-
raise ValueError("'child' must be an instance of "
1591-
"'matplotlib.transform.Transform'")
1587+
cbook._check_isinstance(Transform, child=child)
15921588
self._init(child)
15931589
self.set_children(child)
15941590

@@ -1864,9 +1860,7 @@ def set(self, other):
18641860
Set this transformation from the frozen copy of another
18651861
:class:`Affine2DBase` object.
18661862
"""
1867-
if not isinstance(other, Affine2DBase):
1868-
raise ValueError("'other' must be an instance of "
1869-
"'matplotlib.transform.Affine2DBase'")
1863+
cbook._check_isinstance(Affine2DBase, other=other)
18701864
self._mtx = other.get_matrix()
18711865
self.invalidate()
18721866

@@ -2655,11 +2649,8 @@ def __init__(self, path, transform):
26552649
path : `~.path.Path`
26562650
transform : `Transform`
26572651
"""
2658-
if not isinstance(transform, Transform):
2659-
raise ValueError("'transform' must be an instance of "
2660-
"'matplotlib.transform.Transform'")
2652+
cbook._check_isinstance(Transform, transform=transform)
26612653
TransformNode.__init__(self)
2662-
26632654
self._path = path
26642655
self._transform = transform
26652656
self.set_children(transform)

lib/matplotlib/tri/trifinder.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import numpy as np
22

3+
from matplotlib import < 17AE span class=pl-s1>cbook
34
from matplotlib.tri import Triangulation
45

56

@@ -16,8 +17,7 @@ class TriFinder:
1617
coordinates of the same shape.
1718
"""
1819
def __init__(self, triangulation):
19-
if not isinstance(triangulation, Triangulation):
20-
raise ValueError('Expected a Triangulation object')
20+
cbook._check_isinstance(Triangulation, triangulation=triangulation)
2121
self._triangulation = triangulation
2222

2323

0 commit comments

Comments
 (0)
0