From 98ac4874f84dc83e0b9845ef10b73c1799111a7a Mon Sep 17 00:00:00 2001 From: Ilya Konstantinov Date: Tue, 1 Jun 2021 01:29:02 -0400 Subject: [PATCH] Improve pytest quality of life (#10567) --- mypy/state.py | 6 +- mypy/test/helpers.py | 17 +-- mypy/test/testsubtypes.py | 6 +- mypy/test/testtypes.py | 230 +++++++++++++++++++------------------- mypyc/test/testutil.py | 13 ++- 5 files changed, 132 insertions(+), 140 deletions(-) diff --git a/mypy/state.py b/mypy/state.py index 0351785d5db2..16f5c3ea2985 100644 --- a/mypy/state.py +++ b/mypy/state.py @@ -14,5 +14,7 @@ def strict_optional_set(value: bool) -> Iterator[None]: global strict_optional saved = strict_optional strict_optional = value - yield - strict_optional = saved + try: + yield + finally: + strict_optional = saved diff --git a/mypy/test/helpers.py b/mypy/test/helpers.py index 077c2f369cda..6f4252da9fe4 100644 --- a/mypy/test/helpers.py +++ b/mypy/test/helpers.py @@ -5,7 +5,7 @@ import shutil import contextlib -from typing import List, Iterable, Dict, Tuple, Callable, Any, Optional, Iterator +from typing import List, Iterable, Dict, Tuple, Callable, Any, Iterator from mypy import defaults import mypy.api as api @@ -50,6 +50,7 @@ def assert_string_arrays_equal(expected: List[str], actual: List[str], Display any differences in a human-readable form. """ + __tracebackhide__ = True actual = clean_up(actual) actual = [line.replace("can't", "cannot") for line in actual] @@ -326,18 +327,6 @@ def retry_on_error(func: Callable[[], Any], max_wait: float = 1.0) -> None: raise time.sleep(wait_time) -# TODO: assert_true and assert_false are redundant - use plain assert - - -def assert_true(b: bool, msg: Optional[str] = None) -> None: - if not b: - raise AssertionError(msg) - - -def assert_false(b: bool, msg: Optional[str] = None) -> None: - if b: - raise AssertionError(msg) - def good_repr(obj: object) -> str: if isinstance(obj, str): @@ -352,6 +341,7 @@ def good_repr(obj: object) -> str: def assert_equal(a: object, b: object, fmt: str = '{} != {}') -> None: + __tracebackhide__ = True if a != b: raise AssertionError(fmt.format(good_repr(a), good_repr(b))) @@ -364,6 +354,7 @@ def typename(t: type) -> str: def assert_type(typ: type, value: object) -> None: + __tracebackhide__ = True if type(value) != typ: raise AssertionError('Invalid type {}, expected {}'.format( typename(type(value)), typename(typ))) diff --git a/mypy/test/testsubtypes.py b/mypy/test/testsubtypes.py index 876f3eaf3c74..5776d67a5184 100644 --- a/mypy/test/testsubtypes.py +++ b/mypy/test/testsubtypes.py @@ -1,4 +1,4 @@ -from mypy.test.helpers import Suite, assert_true, skip +from mypy.test.helpers import Suite, skip from mypy.nodes import CONTRAVARIANT, INVARIANT, COVARIANT from mypy.subtypes import is_subtype from mypy.test.typefixture import TypeFixture, InterfaceTypeFixture @@ -188,10 +188,10 @@ def test_type_callable_subtyping(self) -> None: # * generic function types def assert_subtype(self, s: Type, t: Type) -> None: - assert_true(is_subtype(s, t), '{} not subtype of {}'.format(s, t)) + assert is_subtype(s, t), '{} not subtype of {}'.format(s, t) def assert_not_subtype(self, s: Type, t: Type) -> None: - assert_true(not is_subtype(s, t), '{} subtype of {}'.format(s, t)) + assert not is_subtype(s, t), '{} subtype of {}'.format(s, t) def assert_strict_subtype(self, s: Type, t: Type) -> None: self.assert_subtype(s, t) diff --git a/mypy/test/testtypes.py b/mypy/test/testtypes.py index 07c8682f10ea..9eaacd0b5262 100644 --- a/mypy/test/testtypes.py +++ b/mypy/test/testtypes.py @@ -2,7 +2,7 @@ from typing import List, Tuple -from mypy.test.helpers import Suite, assert_equal, assert_true, assert_false, assert_type, skip +from mypy.test.helpers import Suite, assert_equal, assert_type, skip from mypy.erasetype import erase_type from mypy.expandtype import expand_type from mypy.join import join_types, join_simple @@ -225,75 +225,75 @@ def assert_erase(self, orig: Type, result: Type) -> None: def test_is_more_precise(self) -> None: fx = self.fx - assert_true(is_more_precise(fx.b, fx.a)) - assert_true(is_more_precise(fx.b, fx.b)) - assert_true(is_more_precise(fx.b, fx.b)) - assert_true(is_more_precise(fx.b, fx.anyt)) - assert_true(is_more_precise(self.tuple(fx.b, fx.a), - self.tuple(fx.b, fx.a))) - assert_true(is_more_precise(self.tuple(fx.b, fx.b), - self.tuple(fx.b, fx.a))) - - assert_false(is_more_precise(fx.a, fx.b)) - assert_false(is_more_precise(fx.anyt, fx.b)) + assert is_more_precise(fx.b, fx.a) + assert is_more_precise(fx.b, fx.b) + assert is_more_precise(fx.b, fx.b) + assert is_more_precise(fx.b, fx.anyt) + assert is_more_precise(self.tuple(fx.b, fx.a), + self.tuple(fx.b, fx.a)) + assert is_more_precise(self.tuple(fx.b, fx.b), + self.tuple(fx.b, fx.a)) + + assert not is_more_precise(fx.a, fx.b) + assert not is_more_precise(fx.anyt, fx.b) # is_proper_subtype def test_is_proper_subtype(self) -> None: fx = self.fx - assert_true(is_proper_subtype(fx.a, fx.a)) - assert_true(is_proper_subtype(fx.b, fx.a)) - assert_true(is_proper_subtype(fx.b, fx.o)) - assert_true(is_proper_subtype(fx.b, fx.o)) + assert is_proper_subtype(fx.a, fx.a) + assert is_proper_subtype(fx.b, fx.a) + assert is_proper_subtype(fx.b, fx.o) + assert is_proper_subtype(fx.b, fx.o) - assert_false(is_proper_subtype(fx.a, fx.b)) - assert_false(is_proper_subtype(fx.o, fx.b)) + assert not is_proper_subtype(fx.a, fx.b) + assert not is_proper_subtype(fx.o, fx.b) - assert_true(is_proper_subtype(fx.anyt, fx.anyt)) - assert_false(is_proper_subtype(fx.a, fx.anyt)) - assert_false(is_proper_subtype(fx.anyt, fx.a)) + assert is_proper_subtype(fx.anyt, fx.anyt) + assert not is_proper_subtype(fx.a, fx.anyt) + assert not is_proper_subtype(fx.anyt, fx.a) - assert_true(is_proper_subtype(fx.ga, fx.ga)) - assert_true(is_proper_subtype(fx.gdyn, fx.gdyn)) - assert_false(is_proper_subtype(fx.ga, fx.gdyn)) - assert_false(is_proper_subtype(fx.gdyn, fx.ga)) + assert is_proper_subtype(fx.ga, fx.ga) + assert is_proper_subtype(fx.gdyn, fx.gdyn) + assert not is_proper_subtype(fx.ga, fx.gdyn) + assert not is_proper_subtype(fx.gdyn, fx.ga) - assert_true(is_proper_subtype(fx.t, fx.t)) - assert_false(is_proper_subtype(fx.t, fx.s)) + assert is_proper_subtype(fx.t, fx.t) + assert not is_proper_subtype(fx.t, fx.s) - assert_true(is_proper_subtype(fx.a, UnionType([fx.a, fx.b]))) - assert_true(is_proper_subtype(UnionType([fx.a, fx.b]), - UnionType([fx.a, fx.b, fx.c]))) - assert_false(is_proper_subtype(UnionType([fx.a, fx.b]), - UnionType([fx.b, fx.c]))) + assert is_proper_subtype(fx.a, UnionType([fx.a, fx.b])) + assert is_proper_subtype(UnionType([fx.a, fx.b]), + UnionType([fx.a, fx.b, fx.c])) + assert not is_proper_subtype(UnionType([fx.a, fx.b]), + UnionType([fx.b, fx.c])) def test_is_proper_subtype_covariance(self) -> None: fx_co = self.fx_co - assert_true(is_proper_subtype(fx_co.gsab, fx_co.gb)) - assert_true(is_proper_subtype(fx_co.gsab, fx_co.ga)) - assert_false(is_proper_subtype(fx_co.gsaa, fx_co.gb)) - assert_true(is_proper_subtype(fx_co.gb, fx_co.ga)) - assert_false(is_proper_subtype(fx_co.ga, fx_co.gb)) + assert is_proper_subtype(fx_co.gsab, fx_co.gb) + assert is_proper_subtype(fx_co.gsab, fx_co.ga) + assert not is_proper_subtype(fx_co.gsaa, fx_co.gb) + assert is_proper_subtype(fx_co.gb, fx_co.ga) + assert not is_proper_subtype(fx_co.ga, fx_co.gb) def test_is_proper_subtype_contravariance(self) -> None: fx_contra = self.fx_contra - assert_true(is_proper_subtype(fx_contra.gsab, fx_contra.gb)) - assert_false(is_proper_subtype(fx_contra.gsab, fx_contra.ga)) - assert_true(is_proper_subtype(fx_contra.gsaa, fx_contra.gb)) - assert_false(is_proper_subtype(fx_contra.gb, fx_contra.ga)) - assert_true(is_proper_subtype(fx_contra.ga, fx_contra.gb)) + assert is_proper_subtype(fx_contra.gsab, fx_contra.gb) + assert not is_proper_subtype(fx_contra.gsab, fx_contra.ga) + assert is_proper_subtype(fx_contra.gsaa, fx_contra.gb) + assert not is_proper_subtype(fx_contra.gb, fx_contra.ga) + assert is_proper_subtype(fx_contra.ga, fx_contra.gb) def test_is_proper_subtype_invariance(self) -> None: fx = self.fx - assert_true(is_proper_subtype(fx.gsab, fx.gb)) - assert_false(is_proper_subtype(fx.gsab, fx.ga)) - assert_false(is_proper_subtype(fx.gsaa, fx.gb)) - assert_false(is_proper_subtype(fx.gb, fx.ga)) - assert_false(is_proper_subtype(fx.ga, fx.gb)) + assert is_proper_subtype(fx.gsab, fx.gb) + assert not is_proper_subtype(fx.gsab, fx.ga) + assert not is_proper_subtype(fx.gsaa, fx.gb) + assert not is_proper_subtype(fx.gb, fx.ga) + assert not is_proper_subtype(fx.ga, fx.gb) def test_is_proper_subtype_and_subtype_literal_types(self) -> None: fx = self.fx @@ -302,79 +302,79 @@ def test_is_proper_subtype_and_subtype_literal_types(self) -> None: lit2 = fx.lit2 lit3 = fx.lit3 - assert_true(is_proper_subtype(lit1, fx.a)) - assert_false(is_proper_subtype(lit1, fx.d)) - assert_false(is_proper_subtype(fx.a, lit1)) - assert_true(is_proper_subtype(fx.uninhabited, lit1)) - assert_false(is_proper_subtype(lit1, fx.uninhabited)) - assert_true(is_proper_subtype(lit1, lit1)) - assert_false(is_proper_subtype(lit1, lit2)) - assert_false(is_proper_subtype(lit2, lit3)) - - assert_true(is_subtype(lit1, fx.a)) - assert_false(is_subtype(lit1, fx.d)) - assert_false(is_subtype(fx.a, lit1)) - assert_true(is_subtype(fx.uninhabited, lit1)) - assert_false(is_subtype(lit1, fx.uninhabited)) - assert_true(is_subtype(lit1, lit1)) - assert_false(is_subtype(lit1, lit2)) - assert_false(is_subtype(lit2, lit3)) - - assert_false(is_proper_subtype(lit1, fx.anyt)) - assert_false(is_proper_subtype(fx.anyt, lit1)) - - assert_true(is_subtype(lit1, fx.anyt)) - assert_true(is_subtype(fx.anyt, lit1)) + assert is_proper_subtype(lit1, fx.a) + assert not is_proper_subtype(lit1, fx.d) + assert not is_proper_subtype(fx.a, lit1) + assert is_proper_subtype(fx.uninhabited, lit1) + assert not is_proper_subtype(lit1, fx.uninhabited) + assert is_proper_subtype(lit1, lit1) + assert not is_proper_subtype(lit1, lit2) + assert not is_proper_subtype(lit2, lit3) + + assert is_subtype(lit1, fx.a) + assert not is_subtype(lit1, fx.d) + assert not is_subtype(fx.a, lit1) + assert is_subtype(fx.uninhabited, lit1) + assert not is_subtype(lit1, fx.uninhabited) + assert is_subtype(lit1, lit1) + assert not is_subtype(lit1, lit2) + assert not is_subtype(lit2, lit3) + + assert not is_proper_subtype(lit1, fx.anyt) + assert not is_proper_subtype(fx.anyt, lit1) + + assert is_subtype(lit1, fx.anyt) + assert is_subtype(fx.anyt, lit1) def test_subtype_aliases(self) -> None: A1, _ = self.fx.def_alias_1(self.fx.a) AA1, _ = self.fx.def_alias_1(self.fx.a) - assert_true(is_subtype(A1, AA1)) - assert_true(is_subtype(AA1, A1)) + assert is_subtype(A1, AA1) + assert is_subtype(AA1, A1) A2, _ = self.fx.def_alias_2(self.fx.a) AA2, _ = self.fx.def_alias_2(self.fx.a) - assert_true(is_subtype(A2, AA2)) - assert_true(is_subtype(AA2, A2)) + assert is_subtype(A2, AA2) + assert is_subtype(AA2, A2) B1, _ = self.fx.def_alias_1(self.fx.b) B2, _ = self.fx.def_alias_2(self.fx.b) - assert_true(is_subtype(B1, A1)) - assert_true(is_subtype(B2, A2)) - assert_false(is_subtype(A1, B1)) - assert_false(is_subtype(A2, B2)) + assert is_subtype(B1, A1) + assert is_subtype(B2, A2) + assert not is_subtype(A1, B1) + assert not is_subtype(A2, B2) - assert_false(is_subtype(A2, A1)) - assert_true(is_subtype(A1, A2)) + assert not is_subtype(A2, A1) + assert is_subtype(A1, A2) # can_be_true / can_be_false def test_empty_tuple_always_false(self) -> None: tuple_type = self.tuple() - assert_true(tuple_type.can_be_false) - assert_false(tuple_type.can_be_true) + assert tuple_type.can_be_false + assert not tuple_type.can_be_true def test_nonempty_tuple_always_true(self) -> None: tuple_type = self.tuple(AnyType(TypeOfAny.special_form), AnyType(TypeOfAny.special_form)) - assert_true(tuple_type.can_be_true) - assert_false(tuple_type.can_be_false) + assert tuple_type.can_be_true + assert not tuple_type.can_be_false def test_union_can_be_true_if_any_true(self) -> None: union_type = UnionType([self.fx.a, self.tuple()]) - assert_true(union_type.can_be_true) + assert union_type.can_be_true def test_union_can_not_be_true_if_none_true(self) -> None: union_type = UnionType([self.tuple(), self.tuple()]) - assert_false(union_type.can_be_true) + assert not union_type.can_be_true def test_union_can_be_false_if_any_false(self) -> None: union_type = UnionType([self.fx.a, self.tuple()]) - assert_true(union_type.can_be_false) + assert union_type.can_be_false def test_union_can_not_be_false_if_none_false(self) -> None: union_type = UnionType([self.tuple(self.fx.a), self.tuple(self.fx.d)]) - assert_false(union_type.can_be_false) + assert not union_type.can_be_false # true_only / false_only @@ -385,16 +385,16 @@ def test_true_only_of_false_type_is_uninhabited(self) -> None: def test_true_only_of_true_type_is_idempotent(self) -> None: always_true = self.tuple(AnyType(TypeOfAny.special_form)) to = true_only(always_true) - assert_true(always_true is to) + assert always_true is to def test_true_only_of_instance(self) -> None: to = true_only(self.fx.a) assert_equal(str(to), "A") - assert_true(to.can_be_true) - assert_false(to.can_be_false) + assert to.can_be_true + assert not to.can_be_false assert_type(Instance, to) # The original class still can be false - assert_true(self.fx.a.can_be_false) + assert self.fx.a.can_be_false def test_true_only_of_union(self) -> None: tup_type = self.tuple(AnyType(TypeOfAny.special_form)) @@ -404,9 +404,9 @@ def test_true_only_of_union(self) -> None: to = true_only(union_type) assert isinstance(to, UnionType) assert_equal(len(to.items), 2) - assert_true(to.items[0].can_be_true) - assert_false(to.items[0].can_be_false) - assert_true(to.items[1] is tup_type) + assert to.items[0].can_be_true + assert not to.items[0].can_be_false + assert to.items[1] is tup_type def test_false_only_of_true_type_is_uninhabited(self) -> None: with strict_optional_set(True): @@ -424,16 +424,16 @@ def test_false_only_tuple(self) -> None: def test_false_only_of_false_type_is_idempotent(self) -> None: always_false = NoneType() fo = false_only(always_false) - assert_true(always_false is fo) + assert always_false is fo def test_false_only_of_instance(self) -> None: fo = false_only(self.fx.a) assert_equal(str(fo), "A") - assert_false(fo.can_be_true) - assert_true(fo.can_be_false) + assert not fo.can_be_true + assert fo.can_be_false assert_type(Instance, fo) # The original class still can be true - assert_true(self.fx.a.can_be_true) + assert self.fx.a.can_be_true def test_false_only_of_union(self) -> None: with strict_optional_set(True): @@ -446,9 +446,9 @@ def test_false_only_of_union(self) -> None: fo = false_only(union_type) assert isinstance(fo, UnionType) assert_equal(len(fo.items), 2) - assert_false(fo.items[0].can_be_true) - assert_true(fo.items[0].can_be_false) - assert_true(fo.items[1] is tup_type) + assert not fo.items[0].can_be_true + assert fo.items[0].can_be_false + assert fo.items[1] is tup_type def test_simplified_union(self) -> None: fx = self.fx @@ -609,16 +609,16 @@ def test_mixed_truth_restricted_type_simple(self) -> None: true_a = true_only(self.fx.a) false_o = false_only(self.fx.o) j = join_simple(self.fx.o, true_a, false_o) - assert_true(j.can_be_true) - assert_true(j.can_be_false) + assert j.can_be_true + assert j.can_be_false def test_mixed_truth_restricted_type(self) -> None: # join_types against differently restricted truthiness types drops restrictions. true_any = true_only(AnyType(TypeOfAny.special_form)) false_o = false_only(self.fx.o) j = join_types(true_any, false_o) - assert_true(j.can_be_true) - assert_true(j.can_be_false) + assert j.can_be_true + assert j.can_be_false def test_other_mixed_types(self) -> None: # In general, joining unrelated types produces object. @@ -737,7 +737,7 @@ def test_simple_type_objects(self) -> None: self.assert_join(t1, t1, t1) j = join_types(t1, t1) assert isinstance(j, CallableType) - assert_true(j.is_type_obj()) + assert j.is_type_obj() self.assert_join(t1, t2, tr) self.assert_join(t1, self.fx.type_type, self.fx.type_type) @@ -802,10 +802,8 @@ def assert_simple_join(self, s: Type, t: Type, join: Type) -> None: expected = str(join) assert_equal(actual, expected, 'join({}, {}) == {{}} ({{}} expected)'.format(s, t)) - assert_true(is_subtype(s, result), - '{} not subtype of {}'.format(s, result)) - assert_true(is_subtype(t, result), - '{} not subtype of {}'.format(t, result)) + assert is_subtype(s, result), '{} not subtype of {}'.format(s, result) + assert is_subtype(t, result), '{} not subtype of {}'.format(t, result) def tuple(self, *a: Type) -> TupleType: return TupleType(list(a), self.fx.std_tuple) @@ -998,8 +996,8 @@ def test_literal_type(self) -> None: self.assert_meet(lit1, self.fx.anyt, lit1) self.assert_meet(lit1, self.fx.o, lit1) - assert_true(is_same_type(lit1, narrow_declared_type(lit1, a))) - assert_true(is_same_type(lit2, narrow_declared_type(lit2, a))) + assert is_same_type(lit1, narrow_declared_type(lit1, a)) + assert is_same_type(lit2, narrow_declared_type(lit2, a)) # FIX generic interfaces + ranges @@ -1019,10 +1017,8 @@ def assert_simple_meet(self, s: Type, t: Type, meet: Type) -> None: expected = str(meet) assert_equal(actual, expected, 'meet({}, {}) == {{}} ({{}} expected)'.format(s, t)) - assert_true(is_subtype(result, s), - '{} not subtype of {}'.format(result, s)) - assert_true(is_subtype(result, t), - '{} not subtype of {}'.format(result, t)) + assert is_subtype(result, s), '{} not subtype of {}'.format(result, s) + assert is_subtype(result, t), '{} not subtype of {}'.format(result, t) def tuple(self, *a: Type) -> TupleType: return TupleType(list(a), self.fx.std_tuple) diff --git a/mypyc/test/testutil.py b/mypyc/test/testutil.py index 7ef1f941aa41..14ff057ab871 100644 --- a/mypyc/test/testutil.py +++ b/mypyc/test/testutil.py @@ -58,11 +58,12 @@ def use_custom_builtins(builtins_path: str, testcase: DataDrivenTestCase) -> Ite default_builtins = True # Actually peform the test case. - yield None - - if default_builtins: - # Clean up. - os.remove(builtins) + try: + yield None + finally: + if default_builtins: + # Clean up. + os.remove(builtins) def perform_test(func: Callable[[DataDrivenTestCase], None], @@ -156,6 +157,8 @@ def assert_test_output(testcase: DataDrivenTestCase, message: str, expected: Optional[List[str]] = None, formatted: Optional[List[str]] = None) -> None: + __tracebackhide__ = True + expected_output = expected if expected is not None else testcase.output if expected_output != actual and testcase.config.getoption('--update-data', False): update_testcase_output(testcase, actual)