|
9 | 9 | from typing import Any, NoReturn |
10 | 10 | from typing import TypeVar, AnyStr |
11 | 11 | from typing import T, KT, VT # Not in __all__. |
12 | | -from typing import Union, Optional |
| 12 | +from typing import Union, Optional, Literal |
13 | 13 | from typing import Tuple, List, MutableMapping |
14 | 14 | from typing import Callable |
15 | 15 | from typing import Generic, ClassVar, Final, final |
@@ -489,6 +489,68 @@ def test_ellipsis_in_generic(self): |
489 | 489 | typing.List[Callable[..., str]] |
490 | 490 |
|
491 | 491 |
|
| 492 | +class LiteralTests(BaseTestCase): |
| 493 | + def test_basics(self): |
| 494 | + # All of these are allowed. |
| 495 | + Literal[1] |
| 496 | + Literal[1, 2, 3] |
| 497 | + Literal["x", "y", "z"] |
| 498 | + Literal[None] |
| 499 | + Literal[True] |
| 500 | + Literal[1, "2", False] |
| 501 | + Literal[Literal[1, 2], Literal[4, 5]] |
| 502 | + Literal[b"foo", u"bar"] |
| 503 | + |
| 504 | + def test_illegal_parameters_do_not_raise_runtime_errors(self): |
| 505 | + # Type checkers should reject these types, but we do not |
| 506 | + # raise errors at runtime to maintain maximium flexibility. |
| 507 | + Literal[int] |
| 508 | + Literal[3j + 2, ..., ()] |
| 509 | + Literal[{"foo": 3, "bar": 4}] |
| 510 | + Literal[T] |
| 511 | + |
| 512 | + def test_literals_inside_other_types(self): |
| 513 | + List[Literal[1, 2, 3]] |
| 514 | + List[Literal[("foo", "bar", "baz")]] |
| 515 | + |
| 516 | + def test_repr(self): |
| 517 | + self.assertEqual(repr(Literal[1]), "typing.Literal[1]") |
| 518 | + self.assertEqual(repr(Literal[1, True, "foo"]), "typing.Literal[1, True, 'foo']") |
| 519 | + self.assertEqual(repr(Literal[int]), "typing.Literal[int]") |
| 520 | + self.assertEqual(repr(Literal), "typing.Literal") |
| 521 | + self.assertEqual(repr(Literal[None]), "typing.Literal[None]") |
| 522 | + |
| 523 | + def test_cannot_init(self): |
| 524 | + with self.assertRaises(TypeError): |
| 525 | + Literal() |
| 526 | + with self.assertRaises(TypeError): |
| 527 | + Literal[1]() |
| 528 | + with self.assertRaises(TypeError): |
| 529 | + type(Literal)() |
| 530 | + with self.assertRaises(TypeError): |
| 531 | + type(Literal[1])() |
| 532 | + |
| 533 | + def test_no_isinstance_or_issubclass(self): |
| 534 | + with self.assertRaises(TypeError): |
| 535 | + isinstance(1, Literal[1]) |
| 536 | + with self.assertRaises(TypeError): |
| 537 | + isinstance(int, Literal[1]) |
| 538 | + with self.assertRaises(TypeError): |
| 539 | + issubclass(1, Literal[1]) |
| 540 | + with self.assertRaises(TypeError): |
| 541 | + issubclass(int, Literal[1]) |
| 542 | + |
| 543 | + def test_no_subclassing(self): |
| 544 | + with self.assertRaises(TypeError): |
| 545 | + class Foo(Literal[1]): pass |
| 546 | + with self.assertRaises(TypeError): |
| 547 | + class Bar(Literal): pass |
| 548 | + |
| 549 | + def test_no_multiple_subscripts(self): |
| 550 | + with self.assertRaises(TypeError): |
| 551 | + Literal[1][1] |
| 552 | + |
| 553 | + |
492 | 554 | XK = TypeVar('XK', str, bytes) |
493 | 555 | XV = TypeVar('XV') |
494 | 556 |
|
|
0 commit comments