# This can be surprising sometimes. The following is valid: a = {} a['x'] = a = {} assert a == {} # But the following throws a TypeError (since ``a`` is assigned to 1 first): def _a(): a = {} a = a['x'] = 1 assert_raises(TypeError, _a) # This means that the following is valid python. It will create a infinitely # recursive dictionary. aaa = aaa[0] = {} assert aaa[0] == aaa # Likewise the following creates an infinite list: aab = aab[0] = [0] assert aab[0] == aab # Expressions are evaluated first though
# Naturally, this can lead to memory errors if, for instance, some process # begins infinite recursion. # # Consequently, Python sets a maximum limit on the interpreter stack to prevent # overflows on the C stack that might crash Python. # # (NOTE: The highest possible limit is platform dependent and setting a # too-high limit can lead to a crash.) import sys assert sys.getrecursionlimit() == 1000 # NOTE: This is 996 because the stack has to actually call this # If it were outside of this test, 999 would work assert_raises(None, lambda: fact(996)) assert_raises(RuntimeError, lambda: fact(1000)) # There are a number of ways to get around this issue. # One way is to simply use `reduce`: import operator def fact_r(n): return reduce(operator.mul, xrange(1, n + 1), 1) assert fact_r(10) == fact(10) assert_raises(None, lambda: fact_r(1000))
import re import sre_constants from helpers import assert_raises assert_raises(sre_constants.error, re.sub, "(a)|b", "\\1", "b")