6
6
*/
7
7
package com .oracle .graal .python .runtime .formatting ;
8
8
9
+ import static com .oracle .graal .python .nodes .SpecialMethodNames .__GETITEM__ ;
9
10
import static com .oracle .graal .python .nodes .SpecialMethodNames .__INDEX__ ;
10
11
import static com .oracle .graal .python .nodes .SpecialMethodNames .__INT__ ;
11
12
import static com .oracle .graal .python .runtime .exception .PythonErrorType .MemoryError ;
17
18
import java .math .MathContext ;
18
19
19
20
import com .oracle .graal .python .builtins .PythonBuiltinClassType ;
21
+ import com .oracle .graal .python .builtins .objects .PNone ;
20
22
import com .oracle .graal .python .builtins .objects .PythonAbstractObject ;
21
23
import com .oracle .graal .python .builtins .objects .floats .PFloat ;
22
24
import com .oracle .graal .python .builtins .objects .function .PKeyword ;
@@ -219,6 +221,24 @@ protected InternalFormat.Formatter formatInteger(Object intObj, InternalFormat.S
219
221
return fi ;
220
222
}
221
223
224
+ /**
225
+ * Should this argument be treated as a mapping or as a single argument. This logic differs
226
+ * between string and bytes formatting.
227
+ */
228
+ protected abstract boolean useAsMapping (Object args1 , PythonObjectLibrary lib , Object lazyClass );
229
+
230
+ protected boolean isString (Object args1 , Object lazyClass ) {
231
+ return PGuards .isString (args1 ) || isSubtype (lazyClass , PythonBuiltinClassType .PString );
232
+ }
233
+
234
+ protected boolean isMapping (Object args1 ) {
235
+ return lookupAttribute (args1 , __GETITEM__ ) != PNone .NO_VALUE ;
236
+ }
237
+
238
+ protected static boolean isSubtype (Object lazyClass , PythonBuiltinClassType clazz ) {
239
+ return IsSubtypeNodeGen .getUncached ().execute (lazyClass , clazz );
240
+ }
241
+
222
242
/**
223
243
* Main service of this class: format one or more arguments with the format string supplied at
224
244
* construction.
@@ -238,15 +258,16 @@ private T formatImpl(Object args1) {
238
258
239
259
// We need to do a full subtype-check because native objects may inherit from tuple but have
240
260
// Java type 'PythonNativeObject' (e.g. 'namedtuple' alias 'structseq').
241
- boolean tupleArgs = PGuards .isPTuple (args1 ) || IsSubtypeNodeGen .getUncached ().execute (PythonObjectLibrary .getUncached ().getLazyPythonClass (args1 ), PythonBuiltinClassType .PTuple );
242
- assert tupleArgs || !PGuards .isPTuple (args1 );
261
+ PythonObjectLibrary args1Lib = PythonObjectLibrary .getFactory ().getUncached (args1 );
262
+ final Object args1LazyClass = args1Lib .getLazyPythonClass (args1 );
263
+ boolean tupleArgs = PGuards .isPTuple (args1 ) || isSubtype (args1LazyClass , PythonBuiltinClassType .PTuple );
243
264
if (tupleArgs ) {
244
265
// We will simply work through the tuple elements
245
266
argIndex = 0 ;
246
267
} else {
247
268
// Not a tuple, but possibly still some kind of container: use
248
269
// special argIndex values.
249
- if (! PGuards . isString (args1 ) && PythonObjectLibrary . getUncached (). isMapping ( args1 )) {
270
+ if (useAsMapping (args1 , args1Lib , args1LazyClass )) {
250
271
mapping = args1 ;
251
272
argIndex = -3 ;
252
273
}
0 commit comments