#! /usr/bin/env python3"""Find the maximum recursion limit that prevents interpreter termination.This script finds the maximum safe recursion limit on a particularplatform. If you need to change the recursion limit on your system,this script will tell you a safe upper bound. To use the new limit,call sys.setrecursionlimit().This module implements several ways to create infinite recursion inPython. Different implementations end up pushing different numbers ofC stack frames, depending on how many calls through Python's abstractC API occur.After each round of tests, it prints a message:"Limit of NNNN is fine".The highest printed value of "NNNN" is therefore the highest potentiallysafe limit for your system (which depends on the OS, architecture, but alsothe compilation flags). Please note that it is practically impossible totest all possible recursion paths in the interpreter, so the results ofthis test should not be trusted blindly -- although they give a good hintof which values are reasonable.NOTE: When the C stack space allocated by your system is exceeded dueto excessive recursion, exact behaviour depends on the platform, althoughthe interpreter will always fail in a likely brutal way: either asegmentation fault, a MemoryError, or just a silent abort.NB: A program that does not use __methods__ can set a higher limit."""import sysimport itertoolsclass RecursiveBlowup1:def __init__(self):self.__init__()def test_init():return RecursiveBlowup1()class RecursiveBlowup2:def __repr__(self):return repr(self)def test_repr():return repr(RecursiveBlowup2())class RecursiveBlowup4:def __add__(self, x):return x + selfdef test_add():return RecursiveBlowup4() + RecursiveBlowup4()class RecursiveBlowup5:def __getattr__(self, attr):return getattr(self, attr)def test_getattr():return RecursiveBlowup5().attrclass RecursiveBlowup6:def __getitem__(self, item):return self[item - 2] + self[item - 1]def test_getitem():return RecursiveBlowup6()[5]def test_recurse():return test_recurse()def test_cpickle(_cache={}):import iotry:import _pickleexcept ImportError:print("cannot import _pickle, skipped!")returnk, l = None, Nonefor n in itertools.count():try:l = _cache[n]continue # Already tried and it works, let's save some timeexcept KeyError:for i in range(100):l = [k, l]k = {i: l}_pickle.Pickler(io.BytesIO(), protocol=-1).dump(l)_cache[n] = ldef test_compiler_recursion():# The compiler uses a scaling factor to support additional levels# of recursion. This is a sanity check of that scaling to ensure# it still raises RecursionError even at higher recursion limitscompile("()" * (10 * sys.getrecursionlimit()), "<single>", "single")def check_limit(n, test_func_name):sys.setrecursionlimit(n)if test_func_name.startswith("test_"):print(test_func_name[5:])else:print(test_func_name)test_func = globals()[test_func_name]try:test_func()# AttributeError can be raised because of the way e.g. PyDict_GetItem()# silences all exceptions and returns NULL, which is usually interpreted# as "missing attribute".except (RecursionError, AttributeError):passelse:print("Yikes!")if __name__ == '__main__':limit = 1000while 1:check_limit(limit, "test_recurse")check_limit(limit, "test_add")check_limit(limit, "test_repr")check_limit(limit, "test_init")check_limit(limit, "test_getattr")check_limit(limit, "test_getitem")check_limit(limit, "test_cpickle")check_limit(limit, "test_compiler_recursion")print("Limit of %d is fine" % limit)limit = limit + 100
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。