@@ -150,6 +150,131 @@ func (a String) M__ge__(other Object) (Object, error) {
150
150
151
151
// % operator
152
152
153
+ /*
154
+
155
+ 4.7.2. printf-style String Formatting
156
+
157
+ Note The formatting operations described here exhibit a variety of
158
+ quirks that lead to a number of common errors (such as failing to
159
+ display tuples and dictionaries correctly). Using the newer
160
+ str.format() interface helps avoid these errors, and also provides a
161
+ generally more powerful, flexible and extensible approach to
162
+ formatting text.
163
+
164
+ String objects have one unique built-in operation: the % operator
165
+ (modulo). This is also known as the string formatting or interpolation
166
+ operator. Given format % values (where format is a string), %
167
+ conversion specifications in format are replaced with zero or more
168
+ elements of values. The effect is similar to using the sprintf() in
169
+ the C language.
170
+
171
+ If format requires a single argument, values may be a single non-tuple
172
+ object. [5] Otherwise, values must be a tuple with exactly the number
173
+ of items specified by the format string, or a single mapping object
174
+ (for example, a dictionary).
175
+
176
+ A conversion specifier contains two or more characters and has the
177
+ following components, which must occur in this order:
178
+
179
+ The '%' character, which marks the start of the specifier.
180
+
181
+ Mapping key (optional), consisting of a parenthesised sequence of
182
+ characters (for example, (somename)).
183
+
184
+ Conversion flags (optional), which affect the result of some
185
+ conversion types.
186
+
187
+ Minimum field width (optional). If specified as an '*' (asterisk), the
188
+ actual width is read from the next element of the tuple in values, and
189
+ the object to convert comes after the minimum field width and optional
190
+ precision.
191
+
192
+ Precision (optional), given as a '.' (dot) followed by the
193
+ precision. If specified as '*' (an asterisk), the actual precision is
194
+ read from the next element of the tuple in values, and the value to
195
+ convert comes after the precision.
196
+
197
+ Length modifier (optional).
198
+
199
+ Conversion type.
200
+
201
+ When the right argument is a dictionary (or other mapping type), then
202
+ the formats in the string must include a parenthesised mapping key
203
+ into that dictionary inserted immediately after the '%' character. The
204
+ mapping key selects the value to be formatted from the mapping. For
205
+ example:
206
+
207
+ >>>
208
+ >>> print('%(language)s has %(number)03d quote types.' %
209
+ ... {'language': "Python", "number": 2})
210
+ Python has 002 quote types.
211
+
212
+ In this case no * specifiers may occur in a format (since they require
213
+ a sequential parameter list).
214
+
215
+ The conversion flag characters are:
216
+
217
+ Flag Meaning
218
+ '#' The value conversion will use the “alternate form” (where defined below).
219
+ '0' The conversion will be zero padded for numeric values.
220
+ '-' The converted value is left adjusted (overrides the '0' conversion if both are given).
221
+ ' ' (a space) A blank should be left before a positive number (or empty string) produced by a signed conversion.
222
+ '+' A sign character ('+' or '-') will precede the conversion (overrides a “space” flag).
223
+
224
+ A length modifier (h, l, or L) may be present, but is ignored as it is
225
+ not necessary for Python – so e.g. %ld is identical to %d.
226
+
227
+ The conversion types are:
228
+
229
+ Conversion Meaning Notes
230
+ 'd' Signed integer decimal.
231
+ 'i' Signed integer decimal.
232
+ 'o' Signed octal value. (1)
233
+ 'u' Obsolete type – it is identical to 'd'. (7)
234
+ 'x' Signed hexadecimal (lowercase). (2)
235
+ 'X' Signed hexadecimal (uppercase). (2)
236
+ 'e' Floating point exponential format (lowercase). (3)
237
+ 'E' Floating point exponential format (uppercase). (3)
238
+ 'f' Floating point decimal format. (3)
239
+ 'F' Floating point decimal format. (3)
240
+ 'g' Floating point format. Uses lowercase exponential format if exponent is less than -4 or not less than precision, decimal format otherwise. (4)
241
+ 'G' Floating point format. Uses uppercase exponential format if exponent is less than -4 or not less than precision, decimal format otherwise. (4)
242
+ 'c' Single character (accepts integer or single character string).
243
+ 'r' String (converts any Python object using repr()). (5)
244
+ 's' String (converts any Python object using str()). (5)
245
+ 'a' String (converts any Python object using ascii()). (5)
246
+ '%' No argument is converted, results in a '%' character in the result.
247
+ Notes:
248
+
249
+ The alternate form causes a leading zero ('0') to be inserted between
250
+ left-hand padding and the formatting of the number if the leading
251
+ character of the result is not already a zero.
252
+
253
+ The alternate form causes a leading '0x' or '0X' (depending on whether
254
+ the 'x' or 'X' format was used) to be inserted between left-hand
255
+ padding and the formatting of the number if the leading character of
256
+ the result is not already a zero.
257
+
258
+ The alternate form causes the result to always contain a decimal
259
+ point, even if no digits follow it.
260
+
261
+ The precision determines the number of digits after the decimal point
262
+ and defaults to 6.
263
+
264
+ The alternate form causes the result to always contain a decimal
265
+ point, and trailing zeroes are not removed as they would otherwise be.
266
+
267
+ The precision determines the number of significant digits before and
268
+ after the decimal point and defaults to 6.
269
+
270
+ If precision is N, the output is truncated to N characters.
271
+
272
+ See PEP 237. Since Python strings have an explicit length, %s
273
+ conversions do not assume that '\0' is the end of the string.
274
+
275
+ Changed in version 3.1: %f conversions for numbers whose absolute
276
+ value is over 1e50 are no longer replaced by %g conversions.
277
+ */
153
278
func (a String ) M__mod__ (other Object ) (Object , error ) {
154
279
var values Tuple
155
280
switch b := other .(type ) {
@@ -159,7 +284,14 @@ func (a String) M__mod__(other Object) (Object, error) {
159
284
values = Tuple {other }
160
285
}
161
286
// FIXME not a full implementation ;-)
162
- return String (fmt .Sprintf ("%s %#v" , a , values )), nil
287
+ params := make ([]interface {}, len (values ))
288
+ for i := range values {
289
+ params [i ] = values [i ]
290
+ }
291
+ s := string (a )
292
+ s = strings .Replace (s , "%s" , "%v" , - 1 )
293
+ s = strings .Replace (s , "%r" , "%#v" , - 1 )
294
+ return String (fmt .Sprintf (s , params ... )), nil
163
295
}
164
296
165
297
func (a String ) M__rmod__ (other Object ) (Object , error ) {
0 commit comments