On 08/24/2015 06:37 PM, Nathaniel Smith wrote:
On Mon, Aug 24, 2015 at 1:57 PM, Mike Miller
wrote: Hi, here's my latest idea, riffing on other's latest this weekend.
Let's call these e-strings (for expression), as it's easier to refer to the letter of the proposals than three digit numbers.
So, an e-string looks like an f-string, though at compile-time, it is converted to an object instead (like i-string):
print(e'Hello {friend}, filename: {filename}.') # converts to ==>
print(estr('Hello {friend}, filename: {filename}.', friend=friend, filename=filename))
An estr is a subclass of str, therefore able to do the nice things a string can do. Rendering is deferred, and it also has a raw member, escape(), and translate() methods:
class estr(str): # init: saves self.raw, args, kwargs for later # methods, ops render it # def escape(self, escape_func): # handles escaping # def translate(self, template, safe=True): # optional i18n support
To make it as simple as possible to use by end-developers, it 1) doesn't require str() to be run explicitly, it renders itself when needed via its various methods and operators. Look for .raw, if you need the original.
This is a really interesting idea.
You could potentially re-use PyUnicode_READY to do the default rendering.
I doubt you could get this to work, although feel free to prove me wrong. I think you'll end up with the same decision Pathlib made (PEP 428): don't derive from str.
Some things to think about:
- If I concatenate two e-string objects, or an e-string and a regular string, or interpolate an e-string into an e-string, then what happens?
- How problematic will it be that an e-string pins all the interpolated objects in memory for its lifetime?
Well, it seems to work for logging, but those don't tend to stay around very long. But this is one of the reasons to play with a sample implementation, to understand these sorts of issues. Eric.