|
3 | 3 | from typing import List
|
4 | 4 |
|
5 | 5 | from mypy.myunit import (
|
6 |
| - Suite, assert_equal, assert_true, assert_false |
| 6 | + Suite, assert_equal, assert_true, assert_false, assert_type |
7 | 7 | )
|
8 | 8 | from mypy.erasetype import erase_type
|
9 | 9 | from mypy.expandtype import expand_type
|
10 |
| -from mypy.join import join_types |
| 10 | +from mypy.join import join_types, join_simple |
11 | 11 | from mypy.meet import meet_types
|
12 | 12 | from mypy.types import (
|
13 | 13 | UnboundType, AnyType, Void, CallableType, TupleType, TypeVarDef, Type,
|
14 |
| - Instance, NoneTyp, ErrorType, Overloaded, TypeType, |
| 14 | + Instance, NoneTyp, ErrorType, Overloaded, TypeType, UnionType, UninhabitedType, |
| 15 | + true_only, false_only |
15 | 16 | )
|
16 | 17 | from mypy.nodes import ARG_POS, ARG_OPT, ARG_STAR, CONTRAVARIANT, INVARIANT, COVARIANT
|
17 | 18 | from mypy.subtypes import is_subtype, is_more_precise, is_proper_subtype
|
@@ -232,6 +233,95 @@ def test_is_proper_subtype_invariance(self):
|
232 | 233 | assert_false(is_proper_subtype(fx.gb, fx.ga))
|
233 | 234 | assert_false(is_proper_subtype(fx.ga, fx.gb))
|
234 | 235 |
|
| 236 | + # can_be_true / can_be_false |
| 237 | + |
| 238 | + def test_empty_tuple_always_false(self): |
| 239 | + tuple_type = self.tuple() |
| 240 | + assert_true(tuple_type.can_be_false) |
| 241 | + assert_false(tuple_type.can_be_true) |
| 242 | + |
| 243 | + def test_nonempty_tuple_always_true(self): |
| 244 | + tuple_type = self.tuple(AnyType(), AnyType()) |
| 245 | + assert_true(tuple_type.can_be_true) |
| 246 | + assert_false(tuple_type.can_be_false) |
| 247 | + |
| 248 | + def test_union_can_be_true_if_any_true(self): |
| 249 | + union_type = UnionType([self.fx.a, self.tuple()]) |
| 250 | + assert_true(union_type.can_be_true) |
| 251 | + |
| 252 | + def test_union_can_not_be_true_if_none_true(self): |
| 253 | + union_type = UnionType([self.tuple(), self.tuple()]) |
| 254 | + assert_false(union_type.can_be_true) |
| 255 | + |
| 256 | + def test_union_can_be_false_if_any_false(self): |
| 257 | + union_type = UnionType([self.fx.a, self.tuple()]) |
| 258 | + assert_true(union_type.can_be_false) |
| 259 | + |
| 260 | + def test_union_can_not_be_false_if_none_false(self): |
| 261 | + union_type = UnionType([self.tuple(self.fx.a), self.tuple(self.fx.d)]) |
| 262 | + assert_false(union_type.can_be_false) |
| 263 | + |
| 264 | + # true_only / false_only |
| 265 | + |
| 266 | + def test_true_only_of_false_type_is_uninhabited(self): |
| 267 | + to = true_only(NoneTyp()) |
| 268 | + assert_type(UninhabitedType, to) |
| 269 | + |
| 270 | + def test_true_only_of_true_type_is_idempotent(self): |
| 271 | + always_true = self.tuple(AnyType()) |
| 272 | + to = true_only(always_true) |
| 273 | + assert_true(always_true is to) |
| 274 | + |
| 275 | + def test_true_only_of_instance(self): |
| 276 | + to = true_only(self.fx.a) |
| 277 | + assert_equal(str(to), "A") |
| 278 | + assert_true(to.can_be_true) |
| 279 | + assert_false(to.can_be_false) |
| 280 | + assert_type(Instance, to) |
| 281 | + # The original class still can be false |
| 282 | + assert_true(self.fx.a.can_be_false) |
| 283 | + |
| 284 | + def test_true_only_of_union(self): |
| 285 | + tup_type = self.tuple(AnyType()) |
| 286 | + # Union of something that is unknown, something that is always true, something |
| 287 | + # that is always false |
| 288 | + union_type = UnionType([self.fx.a, tup_type, self.tuple()]) |
| 289 | + to = true_only(union_type) |
| 290 | + assert_equal(len(to.items), 2) |
| 291 | + assert_true(to.items[0].can_be_true) |
| 292 | + assert_false(to.items[0].can_be_false) |
| 293 | + assert_true(to.items[1] is tup_type) |
| 294 | + |
| 295 | + def test_false_only_of_true_type_is_uninhabited(self): |
| 296 | + fo = false_only(self.tuple(AnyType())) |
| 297 | + assert_type(UninhabitedType, fo) |
| 298 | + |
| 299 | + def test_false_only_of_false_type_is_idempotent(self): |
| 300 | + always_false = NoneTyp() |
| 301 | + fo = false_only(always_false) |
| 302 | + assert_true(always_false is fo) |
| 303 | + |
| 304 | + def test_false_only_of_instance(self): |
| 305 | + fo = false_only(self.fx.a) |
| 306 | + assert_equal(str(fo), "A") |
| 307 | + assert_false(fo.can_be_true) |
| 308 | + assert_true(fo.can_be_false) |
| 309 | + assert_type(Instance, fo) |
| 310 | + # The original class still can be true |
| 311 | + assert_true(self.fx.a.can_be_true) |
| 312 | + |
| 313 | + def test_false_only_of_union(self): |
| 314 | + tup_type = self.tuple() |
| 315 | + # Union of something that is unknown, something that is always true, something |
| 316 | + # that is always false |
| 317 | + union_type = UnionType([self.fx.a, self.tuple(AnyType()), tup_type]) |
| 318 | + assert_equal(len(union_type.items), 3) |
| 319 | + fo = false_only(union_type) |
| 320 | + assert_equal(len(fo.items), 2) |
| 321 | + assert_false(fo.items[0].can_be_true) |
| 322 | + assert_true(fo.items[0].can_be_false) |
| 323 | + assert_true(fo.items[1] is tup_type) |
| 324 | + |
235 | 325 | # Helpers
|
236 | 326 |
|
237 | 327 | def tuple(self, *a):
|
@@ -343,6 +433,22 @@ def test_any_type(self):
|
343 | 433 | self.callable(self.fx.a, self.fx.b)]:
|
344 | 434 | self.assert_join(t, self.fx.anyt, self.fx.anyt)
|
345 | 435 |
|
| 436 | + def test_mixed_truth_restricted_type_simple(self): |
| 437 | + # join_simple against differently restricted truthiness types drops restrictions. |
| 438 | + true_a = true_only(self.fx.a) |
| 439 | + false_o = false_only(self.fx.o) |
| 440 | + j = join_simple(self.fx.o, true_a, false_o) |
| 441 | + assert_true(j.can_be_true) |
| 442 | + assert_true(j.can_be_false) |
| 443 | + |
| 444 | + def test_mixed_truth_restricted_type(self): |
| 445 | + # join_types against differently restricted truthiness types drops restrictions. |
| 446 | + true_any = true_only(AnyType()) |
| 447 | + false_o = false_only(self.fx.o) |
| 448 | + j = join_types(true_any, false_o) |
| 449 | + assert_true(j.can_be_true) |
| 450 | + assert_true(j.can_be_false) |
| 451 | + |
346 | 452 | def test_other_mixed_types(self):
|
347 | 453 | # In general, joining unrelated types produces object.
|
348 | 454 | for t1 in [self.fx.a, self.fx.t, self.tuple(),
|
|
0 commit comments