5 ms·
Yikes. Don't get me wrong, I totally understand the reasoning why this would be useful (though I violently disagree with the idea of deferring the evaluation of
by formerly_proven 2y ago
Yikes. Don't get me wrong, I totally understand the reasoning why this would be useful (though I violently disagree with the idea of deferring the evaluation of the contained expressions), but it's also so very kitchensinky and adds so little over just calling a function (which doesn't require a 20-page explainer, as everyone already knows how function calls work). It also promotes using what looks like string interpolation (and what might be string interpolation, you can't tell at the "call site") for things which we know string interpolation is the wrong tool. The API also seems really, I dunno, weird to me. The string is split around interpolations and verbatim portions result in one argument, which is "string-like", while interpolations become four-tuple-like (one of which is a lambda, which you call to perform the deferred interpolation). This seems really awkward to me for building stuff like the suggested use cases of XML/HTML or SQL templating.
Also the scoping rules of this are a special case which doesn't appear in regular Python code so far: "The use of annotation scope means it’s not possible to fully desugar interpolations into Python code. Instead it’s as if one is writing interpolation_lambda: tag, not lambda: tag, where a hypothetical interpolation_lambda keyword variant uses annotation scope instead of the standard function scope." -- i.e. it's "as if you wrapped all interpolation expressions in a lambda: <expr>, except it uses different scoping rules".
- masklinn 2y ago> This seems really awkward to me for building stuff like the suggested use cases of XML/HTML or SQL templating. Compared to what? At the end of the day you're still doing string formatting, if you want parsing, then you'd feed the item into a parser, which this doesn't preclude. The interface sounds a lot better than JS's anyway, as that completely separates the literal strings and the interpolations so you have to re-intersperse them which is muggy. > interpolations become four-tuple-like They become an Interpolation object, which can be unpacked if you find that more convenient, but you can access the members if you prefer: - 0 is getvalue is the callable to retrieve the evaluated expression - 1 is expr is the raw text form of the expression - 2 is conv is the !conversion tag (s, r, or a) - 3 is format_spec
- jimbaker 2y agoThe intent here is to support the following approach for tag function authors: 1. Parse to an AST, generally using an off-the-shelf parser. In practice, it's possible to rewrite interpolations with a placeholder suitable for a given language, eg x$Nx for HTML. Of course if that doesn't actually work, you might have to write/modify an existing parser. Hopefully we can cleverly avoid this extra work. 2. Walk/compile the AST, filling interpolations, but taking in account the context. This can for example take the form of building appropriate query strings that avoid Bobby Tables SQL injection, whether by mapping to SQL placeholders or with appropriate quoting (such as for a column or table name). 3. Memoize these steps, much as we see with builtin DSLs in Python, like the re module; see https://github.com/python/cpython/blob/3.12/Lib/re/__init__.py#L331 https://github.com/python/cpython/blob/3.12/Lib/re/__init__.... We do plan to make this easier/faster by supporting getting the original source of the template string (Template.source), vs the *args approach we show in the PEP at the start of this discussion (this will become Template.args instead; Template here is the proposed protocol of the object passed in). Related is my post here: https://discuss.python.org/t/pep-750-tag-strings-for-writing-domain-specific-languages/60408/108 https://discuss.python.org/t/pep-750-tag-strings-for-writing...