[Python-ideas] String interpolation for all literal strings
Nick Coghlan
ncoghlan at gmail.com
Fri Aug 7 13:55:49 CEST 2015
On 7 August 2015 at 20:13, Guido van Rossum <guido at python.org> wrote:
> On Fri, Aug 7, 2015 at 11:50 AM, Nick Coghlan <ncoghlan at gmail.com> wrote:
>> An opt-in translation interpolator might then look like:
>>
>> def __interpolate__(target, expressions, values, format_spec):
>> if not all(expr.isidentifier() for expr in expressions):
>> raise ValueError("Only variable substitions are permitted
>> for il8n interpolation")
>> if any(spec for spec in format_specs):
>> raise ValueError("Format specifications are not permitted
>> for il8n interpolation")
>> catalog_str = target % tuple("${%s}" % expr for expr in
>> expressions)
>> translated = _(catalog_str)
>> values = {k:v for k, v in zip(expressions, values)}
>> return string.Template(translated).safe_substitute()
>>
>> The string extractor for the il8n library providing that
>> implementation would also need to know to do the transformation from
>> f-string formatting to string.Template formatting when generating the
>> catalog strings
>
>
> OK, that sounds reasonable, except that translators need to control
> substitution order, so s % tuple(...) doesn't work. However, if we use
> s.format(...) we can use "This interpolates {0} and {1}", and then I'm
> satisfied. (Further details of the signature of __interpolate__ TBD.)
If we do go down this path of making it possible to override the
interpolation behaviour, I agree we should reserve judgment on a
signature for __interpolate__
However, the concept sketch *does* handle the reordering problem by
using mod-formatting to create a PEP 292 translation string and then
using name based formatting on that. To work through an example where
the "translation" is from active to passive voice in English rather
than between languages:
f"\{a} affected \{b}"
-> __interpolate__("%s affected %s", ("a", "b"), (a, b), ("", ""))
-> "${a} affected ${b}" # catalog_str
-> "${b} was affected by ${a}" # translated
The reconstructued values mapping passed to
string.Template.safe_substitute() ends up containing {"a":a, "b":b},
so it is able to handle the field reordering because the final
substitution is name based.
The filtering on the passed in expressions and format specifications
serves to ensure that that particular il8n interpolator is only used
with human-translator-friendly PEP 292 compatible translation strings
(the message extractor would also be able to check that statically)
I considered a few other signatures (like an ordered dict, or a tuple
of 3-tuples, or assuming the formatting would be done with
str.format_map), but they ended up being more complicated for the two
example cases I was exploring.
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
More information about the Python-ideas
mailing list