Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 337fb07

Browse filesBrowse files
committed
Merge pull request #6275 from WeatherGod/fix_cycler_validation
Fix cycler validation
1 parent 819f746 commit 337fb07
Copy full SHA for 337fb07

File tree

Expand file treeCollapse file tree

4 files changed

+46
-15
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+46
-15
lines changed

‎lib/matplotlib/rcsetup.py

Copy file name to clipboardExpand all lines: lib/matplotlib/rcsetup.py
+28-9Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -726,15 +726,7 @@ def cycler(*args, **kwargs):
726726
if not isinstance(args[0], Cycler):
727727
raise TypeError("If only one positional argument given, it must "
728728
" be a Cycler instance.")
729-
730-
c = args[0]
731-
unknowns = c.keys - (set(_prop_validators.keys()) |
732-
set(_prop_aliases.keys()))
733-
if unknowns:
734-
# This is about as much validation I can do
735-
raise TypeError("Unknown artist properties: %s" % unknowns)
736-
else:
737-
return Cycler(c)
729+
return validate_cycler(args[0])
738730
elif len(args) == 2:
739731
pairs = [(args[0], args[1])]
740732
elif len(args) > 2:
@@ -789,6 +781,33 @@ def validate_cycler(s):
789781
else:
790782
raise ValueError("object was not a string or Cycler instance: %s" % s)
791783

784+
unknowns = cycler_inst.keys - (set(_prop_validators) | set(_prop_aliases))
785+
if unknowns:
786+
raise ValueError("Unknown artist properties: %s" % unknowns)
787+
788+
# Not a full validation, but it'll at least normalize property names
789+
# A fuller validation would require v0.10 of cycler.
790+
checker = set()
791+
for prop in cycler_inst.keys:
792+
norm_prop = _prop_aliases.get(prop, prop)
793+
if norm_prop != prop and norm_prop in cycler_inst.keys:
794+
raise ValueError("Cannot specify both '{0}' and alias '{1}'"
795+
" in the same prop_cycle".format(norm_prop, prop))
796+
if norm_prop in checker:
797+
raise ValueError("Another property was already aliased to '{0}'."
798+
" Collision normalizing '{1}'.".format(norm_prop,
799+
prop))
800+
checker.update([norm_prop])
801+
802+
# This is just an extra-careful check, just in case there is some
803+
# edge-case I haven't thought of.
804+
assert len(checker) == len(cycler_inst.keys)
805+
806+
# Now, it should be safe to mutate this cycler
807+
for prop in cycler_inst.keys:
808+
norm_prop = _prop_aliases.get(prop, prop)
809+
cycler_inst.change_key(prop, norm_prop)
810+
792811
return cycler_inst
793812

794813

‎lib/matplotlib/tests/test_cycles.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_cycles.py
+12-5Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def test_colorcycle_basic():
3131
def test_marker_cycle():
3232
fig = plt.figure()
3333
ax = fig.add_subplot(111)
34-
ax.set_prop_cycle(cycler('color', ['r', 'g', 'y']) +
34+
ax.set_prop_cycle(cycler('c', ['r', 'g', 'y']) +
3535
cycler('marker', ['.', '*', 'x']))
3636
xs = np.arange(10)
3737
ys = 0.25 * xs + 2
@@ -47,7 +47,7 @@ def test_marker_cycle():
4747
fig = plt.figure()
4848
ax = fig.add_subplot(111)
4949
# Test keyword arguments, numpy arrays, and generic iterators
50-
ax.set_prop_cycle(color=np.array(['r', 'g', 'y']),
50+
ax.set_prop_cycle(c=np.array(['r', 'g', 'y']),
5151
marker=iter(['.', '*', 'x']))
5252
xs = np.arange(10)
5353
ys = 0.25 * xs + 2
@@ -66,7 +66,7 @@ def test_marker_cycle():
6666
def test_linestylecycle_basic():
6767
fig = plt.figure()
6868
ax = fig.add_subplot(111)
69-
ax.set_prop_cycle(cycler('linestyle', ['-', '--', ':']))
69+
ax.set_prop_cycle(cycler('ls', ['-', '--', ':']))
7070
xs = np.arange(10)
7171
ys = 0.25 * xs + 2
7272
ax.plot(xs, ys, label='solid', lw=4)
@@ -84,7 +84,7 @@ def test_linestylecycle_basic():
8484
def test_fillcycle_basic():
8585
fig = plt.figure()
8686
ax = fig.add_subplot(111)
87-
ax.set_prop_cycle(cycler('color', ['r', 'g', 'y']) +
87+
ax.set_prop_cycle(cycler('c', ['r', 'g', 'y']) +
8888
cycler('hatch', ['xx', 'O', '|-']) +
8989
cycler('linestyle', ['-', '--', ':']))
9090
xs = np.arange(10)
@@ -130,7 +130,7 @@ def test_valid_input_forms():
130130
ax.set_prop_cycle(None)
131131
ax.set_prop_cycle(cycler('linewidth', [1, 2]))
132132
ax.set_prop_cycle('color', 'rgywkbcm')
133-
ax.set_prop_cycle('linewidth', (1, 2))
133+
ax.set_prop_cycle('lw', (1, 2))
134134
ax.set_prop_cycle('linewidth', [1, 2])
135135
ax.set_prop_cycle('linewidth', iter([1, 2]))
136136
ax.set_prop_cycle('linewidth', np.array([1, 2]))
@@ -179,6 +179,13 @@ def test_invalid_input_forms():
179179
'linewidth', {'1': 1, '2': 2})
180180
assert_raises((TypeError, ValueError), ax.set_prop_cycle,
181181
linewidth=1, color='r')
182+
assert_raises((TypeError, ValueError), ax.set_prop_cycle, 'foobar', [1, 2])
183+
assert_raises((TypeError, ValueError), ax.set_prop_cycle,
184+
foobar=[1, 2])
185+
assert_raises((TypeError, ValueError), ax.set_prop_cycle,
186+
cycler(foobar=[1, 2]))
187+
assert_raises(ValueError, ax.set_prop_cycle,
188+
cycler(color='rgb', c='cmy'))
182189

183190

184191
if __name__ == '__main__':

‎lib/matplotlib/tests/test_rcparams.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_rcparams.py
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,10 @@ def test_validators():
322322
("cycler('c', 'rgb') * cycler('linestyle', ['-', '--'])",
323323
(cycler('color', 'rgb') *
324324
cycler('linestyle', ['-', '--']))),
325+
(cycler('ls', ['-', '--']),
326+
cycler('linestyle', ['-', '--'])),
327+
(cycler(mew=[2, 5]),
328+
cycler('markeredgewidth', [2, 5])),
325329
),
326330
# This is *so* incredibly important: validate_cycler() eval's
327331
# an arbitrary string! I think I have it locked down enough,
@@ -343,6 +347,7 @@ def test_validators():
343347
('cycler("waka", [1, 2, 3])', ValueError), # not a property
344348
('cycler(c=[1, 2, 3])', ValueError), # invalid values
345349
("cycler(lw=['a', 'b', 'c'])", ValueError), # invalid values
350+
(cycler('waka', [1, 3, 5]), ValueError), # not a property
346351
)
347352
},
348353
{'validator': validate_hatch,

‎setupext.py

Copy file name to clipboardExpand all lines: setupext.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1323,7 +1323,7 @@ def check(self):
13231323
return "using cycler version %s" % cycler.__version__
13241324

13251325
def get_install_requires(self):
1326-
return ['cycler']
1326+
return ['cycler>=0.9']
13271327

13281328

13291329
class Dateutil(SetupPackage):

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.