I still need to think about it some more, but I’m leaning towards accepting all of @jimbaker’s concerns with the PEP 501 amendments as valid, which would leave bikeshedding over names as the only remaining differences between the PEPs.
I’ll note that the suggested property based wrapper would still eagerly evaluate at interpolation time (since the attribute lookup is also eager), but a format based lazy evaluation wrapper would work:
class on_format:
def __init__(self, callable):
self._callable = callable
def __format__(self, spec):
return format(self._callable(), spec)
do_something_with(t'{on_format(lambda: 42)}')
Template renderers could also easily define their own wrapper class for deferred evaluation rather than relying on an existing one.
Edit: now that I’ve been talked back out of making changes to conversion specifiers, I’m also back to thinking they should be applied eagerly by the compiler so template renderers never see them outside the full source string (they just see the resulting strings in the individual interpolation fields). The original version of PEP 750 needed lazy conversion specifiers because it had lazy field evaluation, but that isn’t true anymore.