I'm receiving digests and seem to not have each individual mail, so here's a digested response:
One side of this that's not discussed is the possible optimization. I can imagine if you've got a lot of objectproperty write and -reads this could actually make certain use cases a lot faster such as this one, saving 6 opcodes:
def __init__(self, left, top, width, height, content):
self.left = left
self.top = top
self.width = width
self.height = height
self.content = content.upper()
self.decideColors()
self.draw()
versus:
def __init__(self, left, top, width, height, content):
with self:
.left = left
.top = top
.width = width
.height = height
.content = content.upper()
.decideColors()
.draw()
The suggestion that you could accomplish this with a (peephole) optimizer does not seem quite correct to me:
x = myobject.b()
...
z = myobject.c()
does not necessarily have a consistent pointer to myobject although it would require some acrobatics to change them in a way that can not be seen by an optimizer.
You can think about exec() or even another thread intervening into a generator function, not something I would do but who knows.
The advantage of the construct is that the .dotted variable is guaranteed to point to the same physical object in memory with an increased reference count during the statement and a decrease happening at dedent.
Django would break when the 'using' keyword would be used for that, but the choice of keyword is arbitrary. Maybe an extended use of the 'with' word would be elegant, when the object would not have an __enter__ and/or __exit__ function it could still run for the purpose of this mechanism. The disadvantage is that you could not use the with construct for this purpose only without also triggering the __enter__ function.