(self)
| 780 | # semantics, it's a more an implementation detail. |
| 781 | @support.cpython_only |
| 782 | def test_merge_constants(self): |
| 783 | # Issue #25843: compile() must merge constants which are equal |
| 784 | # and have the same type. |
| 785 | |
| 786 | def check_same_constant(const): |
| 787 | ns = {} |
| 788 | code = "f1, f2 = lambda: %r, lambda: %r" % (const, const) |
| 789 | exec(code, ns) |
| 790 | f1 = ns['f1'] |
| 791 | f2 = ns['f2'] |
| 792 | self.assertIs(f1.__code__.co_consts, f2.__code__.co_consts) |
| 793 | self.check_constant(f1, const) |
| 794 | self.assertEqual(repr(f1()), repr(const)) |
| 795 | |
| 796 | check_same_constant(None) |
| 797 | check_same_constant(0.0) |
| 798 | check_same_constant(b'abc') |
| 799 | check_same_constant('abc') |
| 800 | |
| 801 | # Note: "lambda: ..." emits "LOAD_CONST Ellipsis", |
| 802 | # whereas "lambda: Ellipsis" emits "LOAD_GLOBAL Ellipsis" |
| 803 | f1, f2 = lambda: ..., lambda: ... |
| 804 | self.assertIs(f1.__code__.co_consts, f2.__code__.co_consts) |
| 805 | self.check_constant(f1, Ellipsis) |
| 806 | self.assertEqual(repr(f1()), repr(Ellipsis)) |
| 807 | |
| 808 | # Merge constants in tuple or frozenset |
| 809 | f1, f2 = lambda: "not a name", lambda: ("not a name",) |
| 810 | f3 = lambda x: x in {("not a name",)} |
| 811 | self.assertIs(f1.__code__.co_consts[0], |
| 812 | f2.__code__.co_consts[1][0]) |
| 813 | self.assertIs(next(iter(f3.__code__.co_consts[1])), |
| 814 | f2.__code__.co_consts[1]) |
| 815 | |
| 816 | # {0} is converted to a constant frozenset({0}) by the peephole |
| 817 | # optimizer |
| 818 | f1, f2 = lambda x: x in {0}, lambda x: x in {0} |
| 819 | self.assertIs(f1.__code__.co_consts, f2.__code__.co_consts) |
| 820 | self.check_constant(f1, frozenset({0})) |
| 821 | self.assertTrue(f1(0)) |
| 822 | |
| 823 | # Merging equal co_linetable is not a strict requirement |
| 824 | # for the Python semantics, it's a more an implementation detail. |
nothing calls this directly
no test coverage detected