From 7177a656743f0c78cfcb24c435aa7d9939f46114 Mon Sep 17 00:00:00 2001 From: tg Date: Fri, 6 Sep 2019 15:32:50 +0100 Subject: [PATCH 1/3] Improved the check_type and check_valid_size validation functions A couple of minor improvements have been made: - The check_type function now tests for lists of length 1 so the returned mesaging is better. - check_valid_size() now passes the name variable into check_type as this is a required argument. To cover the additional logic within check_type a new test has been added in the test_validation file. --- CONTRIBUTING.rst | 1 + hypothesis-python/RELEASE.rst | 4 ++++ .../src/hypothesis/internal/validation.py | 4 +++- hypothesis-python/tests/cover/test_validation.py | 11 +++++++++++ 4 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 hypothesis-python/RELEASE.rst diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 09af95128d..970d0eb64c 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -269,6 +269,7 @@ their individual contributions. * `Sushobhit `_ (sushobhitsolanki@gmail.com) * `Tariq Khokhar `_ (tariq@khokhar.net) * `Tessa Bradbury `_ +* `Thomas Grainge `_ * `Tim Martin `_ (tim@asymptotic.co.uk) * `Tom McDermott `_ (sponster@gmail.com) * `Tyler Gibbons `_ (tyler.gibbons@flexport.com) diff --git a/hypothesis-python/RELEASE.rst b/hypothesis-python/RELEASE.rst new file mode 100644 index 0000000000..b9f9b977a8 --- /dev/null +++ b/hypothesis-python/RELEASE.rst @@ -0,0 +1,4 @@ +RELEASE_TYPE: patch + +This patch improves the messaging that comes from invalid size arguments +to collection strategies such as :func:`~hypothesis.strategies.lists`. \ No newline at end of file diff --git a/hypothesis-python/src/hypothesis/internal/validation.py b/hypothesis-python/src/hypothesis/internal/validation.py index ab5a9efb56..c5573b24e0 100644 --- a/hypothesis-python/src/hypothesis/internal/validation.py +++ b/hypothesis-python/src/hypothesis/internal/validation.py @@ -31,6 +31,8 @@ def check_type(typ, arg, name=""): if name: name += "=" if not isinstance(arg, typ): + if isinstance(typ, tuple) and len(typ) == 1: + typ = typ[0] if isinstance(typ, tuple): typ_string = "one of %s" % (", ".join(t.__name__ for t in typ)) else: @@ -120,7 +122,7 @@ def check_valid_size(value, name): since="2018-10-11", ) else: - check_type(integer_types, value) + check_type(integer_types, value, name) if value < 0: raise InvalidArgument(u"Invalid size %s=%r < 0" % (name, value)) diff --git a/hypothesis-python/tests/cover/test_validation.py b/hypothesis-python/tests/cover/test_validation.py index 11f5bf8428..44ada18523 100644 --- a/hypothesis-python/tests/cover/test_validation.py +++ b/hypothesis-python/tests/cover/test_validation.py @@ -23,6 +23,7 @@ from hypothesis import find, given from hypothesis.errors import InvalidArgument +from hypothesis.internal.validation import check_type from hypothesis.strategies import ( binary, booleans, @@ -247,3 +248,13 @@ def test(x): with pytest.raises(InvalidArgument): test() + + +def test_check_type_with_tuple_of_length_two(): + # This test covers logic for length-two tuples that is essential on PY2, + # e.g. string_types (str, unicode) which are all length-one on Python 3. + check_type((int, str), 1) + check_type((int, str), "1") + + with pytest.raises(InvalidArgument): + check_type((int, str), 1.0) From 6fd32b04d4e8feed9a80ddd3f6cb3d438d38393c Mon Sep 17 00:00:00 2001 From: Zac-HD Date: Tue, 10 Sep 2019 07:15:13 +1000 Subject: [PATCH 2/3] Update test_validation.py --- hypothesis-python/src/hypothesis/internal/coverage.py | 3 ++- hypothesis-python/tests/cover/test_validation.py | 10 ++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/hypothesis-python/src/hypothesis/internal/coverage.py b/hypothesis-python/src/hypothesis/internal/coverage.py index 922e99d284..a4d27e3829 100644 --- a/hypothesis-python/src/hypothesis/internal/coverage.py +++ b/hypothesis-python/src/hypothesis/internal/coverage.py @@ -50,7 +50,8 @@ def pretty_file_name(f): pass parts = f.split(os.path.sep) - parts = parts[-parts[::-1].index("hypothesis") :] + if "hypothesis" in parts: + parts = parts[-parts[::-1].index("hypothesis") :] result = os.path.sep.join(parts) pretty_file_name_cache[f] = result return result diff --git a/hypothesis-python/tests/cover/test_validation.py b/hypothesis-python/tests/cover/test_validation.py index 44ada18523..02bb83a596 100644 --- a/hypothesis-python/tests/cover/test_validation.py +++ b/hypothesis-python/tests/cover/test_validation.py @@ -253,8 +253,10 @@ def test(x): def test_check_type_with_tuple_of_length_two(): # This test covers logic for length-two tuples that is essential on PY2, # e.g. string_types (str, unicode) which are all length-one on Python 3. - check_type((int, str), 1) - check_type((int, str), "1") + def type_checker(x): + check_type((int, str), x, "x") - with pytest.raises(InvalidArgument): - check_type((int, str), 1.0) + type_checker(1) + type_checker("1") + with pytest.raises(InvalidArgument, match="Expected one of int, str but got "): + type_checker(1.0) From ef05f8f3bbf79006cfd21314872356de18c3decf Mon Sep 17 00:00:00 2001 From: Zac-HD Date: Tue, 10 Sep 2019 07:22:37 +1000 Subject: [PATCH 3/3] More efficient field names --- hypothesis-python/src/hypothesis/extra/numpy.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/hypothesis-python/src/hypothesis/extra/numpy.py b/hypothesis-python/src/hypothesis/extra/numpy.py index e2e4c93d00..ed10eb0218 100644 --- a/hypothesis-python/src/hypothesis/extra/numpy.py +++ b/hypothesis-python/src/hypothesis/extra/numpy.py @@ -26,7 +26,7 @@ from hypothesis import Verbosity from hypothesis._settings import note_deprecation from hypothesis.errors import InvalidArgument -from hypothesis.internal.compat import hrange, integer_types +from hypothesis.internal.compat import PY2, hrange, integer_types from hypothesis.internal.coverage import check_function from hypothesis.internal.reflection import proxies from hypothesis.internal.validation import check_type, check_valid_interval @@ -615,11 +615,15 @@ def array_dtypes( """Return a strategy for generating array (compound) dtypes, with members drawn from the given subtype strategy.""" order_check("size", 0, min_size, max_size) - native_strings = st.from_type(str).filter(bool) # See issue #1798 re: filter! - elements = st.tuples(native_strings, subtype_strategy) + # Field names must be native strings and the empty string is weird; see #1963. + if PY2: + field_names = st.binary(min_size=1) + else: + field_names = st.text(min_size=1) + elements = st.tuples(field_names, subtype_strategy) if allow_subarrays: elements |= st.tuples( - native_strings, subtype_strategy, array_shapes(max_dims=2, max_side=2) + field_names, subtype_strategy, array_shapes(max_dims=2, max_side=2) ) return st.lists( elements=elements,