diff options
Diffstat (limited to 'Lib/test/test_compile.py')
-rw-r--r-- | Lib/test/test_compile.py | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index ccd08db..b1f55bb 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -1,3 +1,4 @@ +import math import unittest import sys import _ast @@ -501,8 +502,43 @@ if 1: check_limit("a", "*a") -def test_main(): - support.run_unittest(TestSpecifics) +class TestStackSize(unittest.TestCase): + # These tests check that the computed stack size for a code object + # stays within reasonable bounds (see issue #21523 for an example + # dysfunction). + N = 100 + + def check_stack_size(self, code): + # To assert that the alleged stack size is not O(N), we + # check that it is smaller than log(N). + if isinstance(code, str): + code = compile(code, "<foo>", "single") + max_size = math.ceil(math.log(len(code.co_code))) + self.assertLessEqual(code.co_stacksize, max_size) + + def test_and(self): + self.check_stack_size("x and " * self.N + "x") + + def test_or(self): + self.check_stack_size("x or " * self.N + "x") + + def test_and_or(self): + self.check_stack_size("x and x or " * self.N + "x") + + def test_chained_comparison(self): + self.check_stack_size("x < " * self.N + "x") + + def test_if_else(self): + self.check_stack_size("x if x else " * self.N + "x") + + def test_binop(self): + self.check_stack_size("x + " * self.N + "x") + + def test_func_and(self): + code = "def f(x):\n" + code += " x and x\n" * self.N + self.check_stack_size(code) + if __name__ == "__main__": - test_main() + unittest.main() |