Author: Ronan Lamy <ronan.l...@gmail.com> Branch: union-side-effects-2 Changeset: r88352:131c9aecb309 Date: 2016-09-03 03:41 +0100 http://bitbucket.org/pypy/pypy/changeset/131c9aecb309/
Log: Expand hypothesis testing of union() until it fails diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py --- a/rpython/annotator/model.py +++ b/rpython/annotator/model.py @@ -673,6 +673,10 @@ s_None = SomeNone() s_Bool = SomeBool() +s_True = SomeBool() +s_True.const = True +s_False = SomeBool() +s_False.const = False s_Int = SomeInteger() s_ImpossibleValue = SomeImpossibleValue() s_Str0 = SomeString(no_nul=True) diff --git a/rpython/annotator/test/test_model.py b/rpython/annotator/test/test_model.py --- a/rpython/annotator/test/test_model.py +++ b/rpython/annotator/test/test_model.py @@ -70,11 +70,11 @@ except TypeError: # if A0 is also a new-style class, e.g. in PyPy class B3(A0, object): pass - assert commonbase(A1,A2) is A0 - assert commonbase(A1,A0) is A0 - assert commonbase(A1,A1) is A1 - assert commonbase(A2,B2) is object - assert commonbase(A2,B3) is A0 + assert commonbase(A1, A2) is A0 + assert commonbase(A1, A0) is A0 + assert commonbase(A1, A1) is A1 + assert commonbase(A2, B2) is object + assert commonbase(A2, B3) is A0 def test_list_union(): listdef1 = ListDef('dummy', SomeInteger(nonneg=True)) @@ -105,20 +105,89 @@ assert f2.contains(f1) assert f1.contains(f2) +def const_float(x): + s = SomeFloat() + s.const = x + return s + def const_int(n): - s = SomeInteger(nonneg=(n>=0)) + s = SomeInteger(nonneg=(n >= 0)) s.const = n return s +def const_str(x): + no_nul = not '\x00' in x + if len(x) == 1: + result = SomeChar(no_nul=no_nul) + else: + result = SomeString(no_nul=no_nul) + result.const = x + return result + +def const_unicode(x): + no_nul = not u'\x00' in x + if len(x) == 1: + result = SomeUnicodeCodePoint(no_nul=no_nul) + else: + result = SomeUnicodeString(no_nul=no_nul) + result.const = x + return result + +def compatible(s1, s2): + try: + union(s1, s2) + except UnionError: + return False + return True + +def compatible_pair(pair_s): + return compatible(*pair_s) + +st_float = st.just(SomeFloat()) | st.builds(const_float, st.floats()) st_int = st.one_of(st.builds(SomeInteger, st.booleans(), st.booleans()), st.builds(const_int, st.integers())) -st_annotation = st_int +st_bool = st.sampled_from([s_Bool, s_True, s_False]) +st_numeric = st.one_of(st_float, st_int, st_bool) +st_str = (st.builds(SomeString, st.booleans(), st.booleans()) + | st.builds(const_str, st.binary())) +st_unicode = (st.builds(SomeUnicodeString, st.booleans(), st.booleans()) + | st.builds(const_unicode, st.text())) +st_simple = st.one_of(st_numeric, st_str, st_unicode, st.just(s_ImpossibleValue), st.just(s_None)) -@given(s=st_annotation) +def valid_unions(st_ann): + """From a strategy generating annotations, create a strategy returning + unions of these annotations.""" + pairs = st.tuples(st_ann, st_ann) + return pairs.filter(compatible_pair).map(lambda t: union(*t)) + + +st_annotation = st.recursive(st_simple, + lambda st_ann: valid_unions(st_ann) | st.builds(SomeTuple, st.lists(st_ann)), + max_leaves=3) + +@given(s=st_numeric) def test_union_unary(s): assert union(s, s) == s assert union(s_ImpossibleValue, s) == s +@given(s1=st_numeric, s2=st_numeric) +def test_commutativity_of_union_compatibility(s1, s2): + assert compatible(s1, s2) == compatible(s2, s1) + +@given(st.tuples(st_annotation, st_annotation).filter(lambda t: compatible(*t))) +def test_union_commutative(t): + s1, s2 = t + s_union = union(s1, s2) + assert union(s2, s1) == s_union + assert s_union.contains(s1) + assert s_union.contains(s2) + +@given(st.tuples(st_annotation, st_annotation, st_annotation).filter( + lambda t: compatible(t[0], t[1]) and compatible(t[1], t[2]) and compatible(t[0], t[2]))) +def test_union_associative(t): + s1, s2, s3 = t + assert union(union(s1, s2), s3) == union(s1, union(s2, s3)) + def compile_function(function, annotation=[]): t = TranslationContext() _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit