Skip to content

Commit

Permalink
Resolve Iterable type arg
Browse files Browse the repository at this point in the history
  • Loading branch information
Zac-HD committed Oct 24, 2020
1 parent 2b470fc commit db0bde8
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 27 deletions.
4 changes: 4 additions & 0 deletions hypothesis-python/RELEASE.rst
@@ -0,0 +1,4 @@
RELEASE_TYPE: patch

This patch fixes :func:`~hypothesis.strategies.from_type` with
:class:`Iterable[T] <python:typing.Iterable>` (:issue:`2645`).
Expand Up @@ -365,10 +365,10 @@ def _networks(bits):

_global_type_lookup.update(
{
typing.ByteString: st.binary() | st.binary().map(bytearray),
# Reversible is somehow a subclass of Hashable, so we tuplize it.
# See also the discussion at https://bugs.python.org/issue39046
typing.Reversible: st.lists(st.integers()).map(tuple),
# Note: while ByteString notionally also represents the bytearray and
# memoryview types, it is a subclass of Hashable and those types are not.
# We therefore only generate the bytes type.
typing.ByteString: st.binary(),
# TODO: SupportsAbs and SupportsRound should be covariant, ie have functions.
typing.SupportsAbs: st.one_of(
st.booleans(),
Expand Down
43 changes: 24 additions & 19 deletions hypothesis-python/tests/cover/test_lookup.py
Expand Up @@ -90,25 +90,30 @@ def test_typing_Type_Union(ex):
assert ex in (str, list)


class Elem:
pass


@pytest.mark.parametrize(
"typ,coll_type,instance_of",
[
(typing.Set[int], set, int),
(typing.FrozenSet[int], frozenset, int),
(typing.Dict[int, int], dict, int),
(typing.DefaultDict[int, int], collections.defaultdict, int),
(typing.KeysView[int], type({}.keys()), int),
(typing.ValuesView[int], type({}.values()), int),
(typing.List[int], list, int),
(typing.Tuple[int], tuple, int),
(typing.Tuple[int, ...], tuple, int),
(typing.Iterator[int], typing.Iterator, int),
(typing.Sequence[int], typing.Sequence, int),
(typing.Iterable[int], typing.Iterable, int),
(typing.Mapping[int, None], typing.Mapping, int),
(typing.Container[int], typing.Container, int),
(typing.NamedTuple("A_NamedTuple", (("elem", int),)), tuple, int),
(typing.Set[Elem], set, Elem),
(typing.FrozenSet[Elem], frozenset, Elem),
(typing.Dict[Elem, Elem], dict, Elem),
(typing.DefaultDict[Elem, Elem], collections.defaultdict, Elem),
(typing.KeysView[Elem], type({}.keys()), Elem),
(typing.ValuesView[Elem], type({}.values()), Elem),
(typing.List[Elem], list, Elem),
(typing.Tuple[Elem], tuple, Elem),
(typing.Tuple[Elem, ...], tuple, Elem),
(typing.Iterator[Elem], typing.Iterator, Elem),
(typing.Sequence[Elem], typing.Sequence, Elem),
(typing.Iterable[Elem], typing.Iterable, Elem),
(typing.Mapping[Elem, None], typing.Mapping, Elem),
(typing.Container[Elem], typing.Container, Elem),
(typing.NamedTuple("A_NamedTuple", (("elem", Elem),)), tuple, Elem),
],
ids=repr,
)
@given(data=st.data())
def test_specialised_collection_types(data, typ, coll_type, instance_of):
Expand All @@ -119,17 +124,17 @@ def test_specialised_collection_types(data, typ, coll_type, instance_of):
assume(instances) # non-empty collections without calling len(iterator)


@given(from_type(typing.DefaultDict[int, int]).filter(len))
@given(from_type(typing.DefaultDict[Elem, Elem]).filter(len))
def test_defaultdict_values_type(ex):
assert all(isinstance(elem, int) for elem in ex.values())
assert all(isinstance(elem, Elem) for elem in ex.values())


@given(from_type(typing.ItemsView[int, int]).filter(len))
@given(from_type(typing.ItemsView[Elem, Elem]).filter(len))
def test_ItemsView(ex):
# See https://github.com/python/typing/issues/177
assert isinstance(ex, type({}.items()))
assert all(isinstance(elem, tuple) and len(elem) == 2 for elem in ex)
assert all(all(isinstance(e, int) for e in elem) for elem in ex)
assert all(all(isinstance(e, Elem) for e in elem) for elem in ex)


def test_Optional_minimises_to_None():
Expand Down
Expand Up @@ -5,7 +5,7 @@ import test_expected_output
from hypothesis import given, strategies as st


@given(seq=st.one_of(st.binary(), st.binary().map(bytearray), st.lists(st.integers())))
@given(seq=st.one_of(st.binary(), st.lists(st.integers())))
def test_idempotent_timsort(seq):
result = test_expected_output.timsort(seq=seq)
repeat = test_expected_output.timsort(seq=result)
Expand Down
4 changes: 2 additions & 2 deletions hypothesis-python/tests/ghostwriter/test_ghostwriter.py
Expand Up @@ -21,7 +21,7 @@
import unittest.mock
from decimal import Decimal
from types import ModuleType
from typing import Any, List, Sequence, Set
from typing import Any, List, Sequence, Set, Union

import pytest

Expand Down Expand Up @@ -117,7 +117,7 @@ def non_resolvable_arg(x: NotResolvable):


def test_flattens_one_of_repr():
strat = from_type(Sequence[int])
strat = from_type(Union[int, Sequence[int]])
assert repr(strat).count("one_of(") > 1
assert ghostwriter._valid_syntax_repr(strat).count("one_of(") == 1

Expand Down
2 changes: 1 addition & 1 deletion tooling/src/hypothesistooling/__main__.py
Expand Up @@ -376,7 +376,7 @@ def run_tox(task, version):


# Via https://github.com/pyenv/pyenv/tree/master/plugins/python-build/share/python-build
PY36 = "3.6.9"
PY36 = "3.6.12"
PY37 = "3.7.9"
PY38 = "3.8.6"
PY39 = "3.9.0"
Expand Down

0 comments on commit db0bde8

Please sign in to comment.