The current implementation seems to capture the source variables rather than the result of the expression, which of course leads to this behaviour:
def ident(o):
return o
items = [ident"{x}" for x in range(10)]
strs = [o.getvalue() for o in items]
strs
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
I didn’t go too far into edge cases around comprehensions, async, and the like, but I would assume they exist based on this implementation.
Compare to this behaviour, which is what I mean by eagerly evaluating each expression:
class ident:
def __init__(self, x):
self.x = x
def getvalue(self):
return self.x
items = [ident(x) for x in range(10)]
strs = [o.getvalue() for o in items]
strs
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
(Edit again). And the most compelling example I have for doing things eagerly:
def ident(o):
return o
with lock:
s = ident"{calculate_under_lock()}"
s.getvalue()
How do you communicate to users that their expressions aren’t calculated when/where they think they will be? The complexity goes way up for each use, for not a lot of real benefit. Evaluating the expressions in the context they are written saves all the trouble.