From 0a1473eb2a0df10ddb0061fbfa75ac07c6347eb6 Mon Sep 17 00:00:00 2001 From: "Adrien F. Vincent" Date: Mon, 27 Feb 2017 16:16:39 +0100 Subject: [PATCH 1/2] More robust type checking in '_validate_linestyle', on both Py2 and Py3 --- lib/matplotlib/rcsetup.py | 42 +++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/lib/matplotlib/rcsetup.py b/lib/matplotlib/rcsetup.py index 050e8901f98c..33c7d09a42c2 100644 --- a/lib/matplotlib/rcsetup.py +++ b/lib/matplotlib/rcsetup.py @@ -914,24 +914,40 @@ def _validate_linestyle(ls): A validator for all possible line styles, the named ones *and* the on-off ink sequences. """ - # Named line style, like u'--' or u'solid' - if isinstance(ls, six.text_type): - return _validate_named_linestyle(ls) - - # On-off ink (in points) sequence *of even length*. + # Look first for a valid named line style, like '--' or 'solid' + if isinstance(ls, six.string_types): + try: + return _validate_named_linestyle(ls) + except (UnicodeDecodeError, KeyError): + # On Python 2, string-like *ls*, like for example + # 'solid'.encode('utf-16'), may raise a unicode error. + raise ValueError("the linestyle string {!r} is not a valid " + "string.".format(ls)) + + if isinstance(ls, (bytes, bytearray)): + # On Python 2, a string-like *ls* should already have lead to a + # successful return or to raising an exception. On Python 3, we have + # to manually raise an exception in the case of a byte-like *ls*. + # Otherwise, if *ls* is of even-length, it will be passed to the + # instance of validate_nseq_float, which will return an absurd on-off + # ink sequence... + raise ValueError("linestyle {!r} neither looks like an on-off ink " + "sequence nor a valid string.".format(ls)) + + # Look for an on-off ink sequence (in points) *of even length*. # Offset is set to None. try: if len(ls) % 2 != 0: - # Expecting a sequence of even length - raise ValueError + raise ValueError("the linestyle sequence {!r} is not of even " + "length.".format(ls)) + return (None, validate_nseq_float()(ls)) - except (ValueError, TypeError): - # TypeError can be raised by wrong types passed to float() - # (called inside the instance of validate_nseq_float). - pass - raise ValueError("linestyle must be a string or " + - "an even-length sequence of floats.") + except (ValueError, TypeError): + # TypeError can be raised inside the instance of validate_nseq_float, + # by wrong types passed to float(), like NoneType. + raise ValueError("linestyle {!r} is not a valid on-off ink " + "sequence.".format(ls)) # a map from key -> value, converter From ed04d93642f0a7f44a33a8246fc1ce14e934e588 Mon Sep 17 00:00:00 2001 From: "Adrien F. Vincent" Date: Mon, 27 Feb 2017 16:18:03 +0100 Subject: [PATCH 2/2] tests now depend on python version to check cases with bytes args --- lib/matplotlib/tests/test_rcparams.py | 56 +++++++++++++++++---------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/lib/matplotlib/tests/test_rcparams.py b/lib/matplotlib/tests/test_rcparams.py index 4e689f6b9c47..e84a90ee34cf 100644 --- a/lib/matplotlib/tests/test_rcparams.py +++ b/lib/matplotlib/tests/test_rcparams.py @@ -333,29 +333,45 @@ def generate_validator_testcases(valid): ), 'fail': (('aardvark', ValueError), ) - }, - {'validator': _validate_linestyle, # NB: case-insensitive - 'success': (('-', '-'), ('solid', 'solid'), - ('--', '--'), ('dashed', 'dashed'), - ('-.', '-.'), ('dashdot', 'dashdot'), - (':', ':'), ('dotted', 'dotted'), - ('', ''), (' ', ' '), - ('None', 'none'), ('none', 'none'), - ('DoTtEd', 'dotted'), - (['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])), - ), - 'fail': (('aardvark', ValueError), # not a valid string - ((None, [1, 2]), ValueError), # (offset, dashes) is not OK - ((0, [1, 2]), ValueError), # idem - ((-1, [1, 2]), ValueError), # idem - ([1, 2, 3], ValueError), # not a sequence of even length - (1.23, ValueError) # not a sequence - ) } ) + # The behavior of _validate_linestyle depends on the version of Python. + # ASCII-compliant bytes arguments should pass on Python 2 because of the + # automatic conversion between bytes and strings. Python 3 does not + # perform such a conversion, so the same cases should raise an exception. + # + # Common cases: + ls_test = {'validator': _validate_linestyle, + 'success': (('-', '-'), ('solid', 'solid'), + ('--', '--'), ('dashed', 'dashed'), + ('-.', '-.'), ('dashdot', 'dashdot'), + (':', ':'), ('dotted', 'dotted'), + ('', ''), (' ', ' '), + ('None', 'none'), ('none', 'none'), + ('DoTtEd', 'dotted'), # case-insensitive + (['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])), + ), + '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 + ) + } + # Add some cases of bytes arguments that Python 2 can convert silently: + ls_bytes_args = (b'dotted', 'dotted'.encode('ascii')) + if six.PY3: + ls_test['fail'] += tuple((arg, ValueError) for arg in ls_bytes_args) + else: + ls_test['success'] += tuple((arg, 'dotted') for arg in ls_bytes_args) + # Update the validation test sequence. + validation_tests += (ls_test,) + for validator_dict in validation_tests: validator = validator_dict['validator'] if valid: pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy