From 612d6d0c27cff76bbcda3cf4bdcd4844f10ed95f Mon Sep 17 00:00:00 2001 From: "Adrien F. Vincent" Date: Wed, 15 Nov 2017 22:56:27 -0800 Subject: [PATCH 1/2] add offset-onoffseq pattern to ls validation --- lib/matplotlib/rcsetup.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/rcsetup.py b/lib/matplotlib/rcsetup.py index 2b0833f215c9..4add79be995b 100644 --- a/lib/matplotlib/rcsetup.py +++ b/lib/matplotlib/rcsetup.py @@ -25,7 +25,7 @@ import warnings import re -from matplotlib.cbook import mplDeprecation, deprecated, ls_mapper +from matplotlib.cbook import mplDeprecation, deprecated, ls_mapper, iterable from matplotlib.fontconfig_pattern import parse_fontconfig_pattern from matplotlib.colors import is_color_like @@ -931,13 +931,29 @@ def _validate_linestyle(ls): "sequence nor a valid string.".format(ls)) # Look for an on-off ink sequence (in points) *of even length*. - # Offset is set to None. + # Offset is set to None if not present. try: + offset = None + # Look first for the case (offset, on-off seq). Take also care of the + # historically supported corner-case of an on-off seq like ["1", "2"]. + if (len(ls) == 2 and iterable(ls[1]) and + not isinstance(ls[0], six.string_types)): + # That is likely to be a pattern (offset, on-off seq), so extract + # the offset and continue with the on-off sequence candidate. + if ls[0] is not None: + try: + offset = float(ls[0]) + except ValueError: + raise ValueError( + "a linestyle offset should be None or " + "a numerical value, not {!r}.".format(ls[0])) + offset, ls = ls + if len(ls) % 2 != 0: raise ValueError("the linestyle sequence {!r} is not of even " "length.".format(ls)) - return (None, validate_nseq_float()(ls)) + return (offset, validate_nseq_float()(ls)) except (ValueError, TypeError): # TypeError can be raised inside the instance of validate_nseq_float, From ffd3434891a779c3a43c3edc54352739cb61ad3d Mon Sep 17 00:00:00 2001 From: "Adrien F. Vincent" Date: Wed, 15 Nov 2017 23:26:22 -0800 Subject: [PATCH 2/2] update the relevant test --- lib/matplotlib/tests/test_rcparams.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/tests/test_rcparams.py b/lib/matplotlib/tests/test_rcparams.py index 06650de2b37b..71b8dc48d9a2 100644 --- a/lib/matplotlib/tests/test_rcparams.py +++ b/lib/matplotlib/tests/test_rcparams.py @@ -375,14 +375,18 @@ def generate_validator_testcases(valid): (['1.23', '4.56'], (None, [1.23, 4.56])), ([1.23, 456], (None, [1.23, 456.0])), ([1, 2, 3, 4], (None, [1.0, 2.0, 3.0, 4.0])), + ((-1, [1.23, 456]), (-1, [1.23, 456.0])), + ((None, [1.23, 456]), (None, [1.23, 456.0])), + ((9.87, [1.23, 456]), (9.87, [1.23, 456.0])), + ((np.float128(1), [1.23, 4]), (1.0, [1.23, 4.0])), ), 'fail': (('aardvark', ValueError), # not a valid string ('dotted'.encode('utf-16'), ValueError), # even on PY2 - ((None, [1, 2]), ValueError), # (offset, dashes) != OK - ((0, [1, 2]), ValueError), # idem - ((-1, [1, 2]), ValueError), # idem ([1, 2, 3], ValueError), # sequence with odd length (1.23, ValueError), # not a sequence + (("a", [1, 2]), ValueError), # wrong explicit offset + ((1, [1, 2, 3]), ValueError), # odd length sequence + (([1, 2], 1), ValueError), # inverted offset/onoff ) } # Add some cases of bytes arguments that Python 2 can convert silently: