I am able to replicate. This only happens in the Pythonista console, NOT in Pythonista programs. The workaround is:
def my_workaround():
sys.setrecursionlimit(512)
foo()
print(sys.getrecursionlimit())
my_workaround()
The behavior that you are seeing is an artifact of the Pythonista console which needs to compensate for the fact that Apple only allows iOS apps to have a single thread of execution. When you are not feeding a constant set of commands into the console, it seems to reset some of its values including recursion limit. By defining a function (or a series of ;-separated commands), you keep the console from doing that reset until after your function returns.
To see the behavior clearly, check out:
import sys
def recursion_gsg(x):
print(sys.getrecursionlimit())
sys.setrecursionlimit(x)
print(sys.getrecursionlimit())
def recursion_test():
orig = sys.getrecursionlimit()
print('=' * 10)
recursion_gsg(350)
recursion_gsg(512)
recursion_gsg(1024)
recursion_gsg(orig)
recursion_test()
If you type that line-by-line into the Pythonista console then you get the expected output:
==========
300
350
350
512
512
1024
1024
300
However, if you now type in each line of recursion_test() into the console as a unique command, you get:
==========
300
350
300
512
300
1024
300
300