@@ -312,14 +312,14 @@ private void WriteConversion() {
312312 case 'a' : AppendAscii ( ) ; return ;
313313 // signed integer decimal
314314 case 'd' :
315- case 'i' : AppendInt ( ) ; return ;
315+ case 'i' : AppendInt ( _curCh ) ; return ;
316316 // unsigned octal
317- case 'o' : AppendOctal ( ) ; return ;
317+ case 'o' : AppendBase ( _curCh , 8 ) ; return ;
318318 // unsigned decimal
319- case 'u' : AppendInt ( ) ; return ;
319+ case 'u' : AppendInt ( _curCh ) ; return ;
320320 // unsigned hexadecimal
321- case 'x' : AppendHex ( _curCh ) ; return ;
322- case 'X' : AppendHex ( _curCh ) ; return ;
321+ case 'x' :
322+ case 'X' : AppendBase ( _curCh , 16 ) ; return ;
323323 // floating point exponential format
324324 case 'e' :
325325 // floating point decimal
@@ -385,25 +385,43 @@ private void WriteConversion() {
385385 throw PythonOps . KeyError ( key ) ;
386386 }
387387
388- private object GetIntegerValue ( out bool fPos , bool allowDouble = true ) {
389- if ( ! allowDouble && _opts . Value is float || _opts . Value is double || _opts . Value is Extensible < double > ) {
388+ private object GetIntegerValue ( char format , out bool fPos , bool allowDouble = true ) {
389+ if ( ! allowDouble && ( _opts . Value is float || _opts . Value is double || _opts . Value is Extensible < double > ) ) {
390390 // TODO: this should fail in 3.5
391391 PythonOps . Warn ( _context , PythonExceptions . DeprecationWarning , "automatic int conversions have been deprecated" ) ;
392392 }
393393
394- object val ;
395- if ( _context . LanguageContext . TryConvertToInt32 ( _opts . Value , out int intVal ) ) {
396- val = intVal ;
397- fPos = intVal >= 0 ;
398- } else {
399- if ( Converter . TryConvertToBigInteger ( _opts . Value , out BigInteger bigInt ) ) {
400- val = bigInt ;
401- fPos = bigInt >= BigInteger . Zero ;
402- } else {
403- throw PythonOps . TypeError ( "int argument required" ) ;
394+ switch ( _opts . Value ) {
395+ case float :
396+ case double :
397+ case Extensible < double > :
398+ if ( _context . LanguageContext . TryConvertToInt32 ( _opts . Value , out int intVal ) ) {
399+ fPos = intVal >= 0 ;
400+ return intVal ;
401+ }
402+ if ( Converter . TryConvertToBigInteger ( _opts . Value , out BigInteger bigInt ) ) {
403+ fPos = bigInt >= BigInteger . Zero ;
404+ return bigInt ;
405+ }
406+ break ;
407+ }
408+
409+ try {
410+ if ( PythonOps . TryToIndex ( _opts . Value , out object ? index ) ) {
411+ fPos = index switch {
412+ int i => i >= 0 ,
413+ BigInteger bi => bi >= BigInteger . Zero ,
414+ _ => throw new InvalidOperationException ( ) , // unreachable
415+ } ;
416+ return index ;
404417 }
418+ } catch ( TypeErrorException ) { }
419+
420+ if ( allowDouble ) {
421+ throw PythonOps . TypeError ( "%{0} format: a number is required, not {1}" , format , PythonOps . GetPythonTypeName ( _opts . Value ) ) ;
422+ } else {
423+ throw PythonOps . TypeError ( "%{0} format: an integer is required, not {1}" , format , PythonOps . GetPythonTypeName ( _opts . Value ) ) ;
405424 }
406- return val ;
407425 }
408426
409427 private void AppendChar ( ) {
@@ -451,8 +469,8 @@ private void CheckDataUsed() {
451469 }
452470 }
453471
454- private void AppendInt ( ) {
455- object val = GetIntegerValue ( out bool fPos ) ;
472+ private void AppendInt ( char format ) {
473+ object val = GetIntegerValue ( format , out bool fPos ) ;
456474
457475 if ( _opts . LeftAdj ) {
458476 string str = ZeroPadInt ( val , fPos , _opts . Precision ) ;
@@ -730,7 +748,7 @@ private static string GetAltFormPrefixForRadix(char format, int radix) {
730748 /// special forms for Python.
731749 /// </summary>
732750 private void AppendBase ( char format , int radix ) {
733- var str = ProcessNumber ( format , radix , ref _opts , GetIntegerValue ( out bool fPos , allowDouble : false ) ) ;
751+ var str = ProcessNumber ( format , radix , ref _opts , GetIntegerValue ( format , out bool fPos , allowDouble : false ) ) ;
734752
735753 if ( ! fPos ) {
736754 // if negative number, the leading space has no impact
@@ -849,14 +867,6 @@ private static void AppendNumberReversed(StringBuilder str, string res) {
849867 }
850868 }
851869
852- private void AppendHex ( char format ) {
853- AppendBase ( format , 16 ) ;
854- }
855-
856- private void AppendOctal ( ) {
857- AppendBase ( 'o' , 8 ) ;
858- }
859-
860870 private void AppendBytes ( ) {
861871 Debug . Assert ( _asBytes ) ;
862872 if ( _opts . Value is Bytes bytes || Bytes . TryInvokeBytesOperator ( _context , _opts . Value , out bytes ! ) ) {
0 commit comments