Inner functions can read nonlocal variables in 2.x, just not rebind them. This is annoying, but you can work around it. Just create a dictionary, and store your data as elements therein. Inner functions are not prohibited from mutating the objects that nonlocal variables refer to.
def outer():
d = {'y' : 0}
def inner():
d['y'] += 1
return d['y']
return inner
f = outer()
print(f(), f(), f()) #prints 1 2 3
Or using nonlocal class:
def outer():
class context:
y = 0
def inner():
context.y += 1
return context.y
return inner
It works because you can modify nonlocal variables. But you cannot do assignment to nonlocal variables.