Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fa7b0aa

Browse files
Support and test cycler integer multiplication, concat, and slicing
1 parent 45b6acd commit fa7b0aa

2 files changed

Lines changed: 32 additions & 7 deletions

File tree

lib/matplotlib/rcsetup.py

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
from matplotlib._enums import JoinStyle, CapStyle
3737

3838
# Don't let the original cycler collide with our validating cycler
39-
from cycler import Cycler, cycler as ccycler
39+
from cycler import Cycler, concat as cconcat, cycler as ccycler
4040

4141

4242
class ValidateInStrings:
@@ -845,13 +845,32 @@ def _eval_cycler_expr(node):
845845
return left * right
846846
raise ValueError(f"Unsupported operator: {type(node.op).__name__}")
847847
if isinstance(node, ast.Call):
848-
if not (isinstance(node.func, ast.Name) and node.func.id == 'cycler'):
849-
raise ValueError("only the 'cycler()' function is allowed")
850-
args = [ast.literal_eval(a) for a in node.args]
848+
if not (isinstance(node.func, ast.Name)
849+
and node.func.id in ('cycler', 'concat')):
850+
raise ValueError(
851+
"only the 'cycler()' and 'concat()' functions are allowed")
852+
func = cycler if node.func.id == 'cycler' else cconcat
853+
args = [_eval_cycler_expr(a) for a in node.args]
851854
kwargs = {kw.arg: ast.literal_eval(kw.value) for kw in node.keywords}
852-
return cycler(*args, **kwargs)
853-
raise ValueError(
854-
f"Unsupported expression in cycler string: {ast.dump(node)}")
855+
return func(*args, **kwargs)
856+
if isinstance(node, ast.Subscript):
857+
value = _eval_cycler_expr(node.value)
858+
sl = node.slice
859+
if isinstance(sl, ast.Slice):
860+
s = slice(
861+
ast.literal_eval(sl.lower) if sl.lower else None,
862+
ast.literal_eval(sl.upper) if sl.upper else None,
863+
ast.literal_eval(sl.step) if sl.step else None,
864+
)
865+
return value[s]
866+
raise ValueError("only slicing is supported, not indexing")
867+
# Allow literal values (int, strings, lists, tuples) as arguments
868+
# to cycler() and concat().
869+
try:
870+
return ast.literal_eval(node)
871+
except (ValueError, TypeError):
872+
raise ValueError(
873+
f"Unsupported expression in cycler string: {ast.dump(node)}")
855874

856875

857876
# A validator dedicated to the named legend loc

lib/matplotlib/tests/test_rcparams.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,12 @@ def generate_validator_testcases(valid):
275275
cycler('linestyle', ['-', '--'])),
276276
(cycler(mew=[2, 5]),
277277
cycler('markeredgewidth', [2, 5])),
278+
("2 * cycler('color', 'rgb')", 2 * cycler('color', 'rgb')),
279+
("cycler('color', 'rgb') * 2", cycler('color', 'rgb') * 2),
280+
("concat(cycler('color', 'rgb'), cycler('color', 'cmk'))",
281+
cycler('color', list('rgbcmk'))),
282+
("cycler('color', 'rgbcmk')[:3]", cycler('color', list('rgb'))),
283+
("cycler('color', 'rgb')[::-1]", cycler('color', list('bgr'))),
278284
),
279285
# validate_cycler() parses an arbitrary string using a safe
280286
# AST-based parser (no eval). These tests verify that only valid

0 commit comments

Comments
 (0)