diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 4c7dbbc65a6d4c95a99c4eb8a3b825cedd36cc77_Q3l0aG9uL0NvbXBpbGVyL0V4cHJOb2Rlcy5weQ==..0f6af780d201b1cef4e1ad0697a8bb75777e7914_Q3l0aG9uL0NvbXBpbGVyL0V4cHJOb2Rlcy5weQ== 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -3293,7 +3293,7 @@ # {}-delimited portions of an f-string # # value ExprNode The expression itself - # conversion_char str or None Type conversion (!s, !r, !a, or none) + # conversion_char str or None Type conversion (!s, !r, !a, or none, or 'd' for integer conversion) # format_spec JoinedStrNode or None Format string passed to __format__ # c_format_spec str or None If not None, formatting can be done at the C level @@ -3308,6 +3308,7 @@ 's': 'PyObject_Unicode', 'r': 'PyObject_Repr', 'a': 'PyObject_ASCII', # NOTE: mapped to PyObject_Repr() in Py2 + 'd': '__Pyx_PyNumber_IntOrLong', # NOTE: internal mapping for '%d' formatting }.get def may_be_none(self): diff --git a/Cython/Compiler/Optimize.py b/Cython/Compiler/Optimize.py index 4c7dbbc65a6d4c95a99c4eb8a3b825cedd36cc77_Q3l0aG9uL0NvbXBpbGVyL09wdGltaXplLnB5..0f6af780d201b1cef4e1ad0697a8bb75777e7914_Q3l0aG9uL0NvbXBpbGVyL09wdGltaXplLnB5 100644 --- a/Cython/Compiler/Optimize.py +++ b/Cython/Compiler/Optimize.py @@ -4382,8 +4382,9 @@ break if format_type in u'asrfdoxX': format_spec = s[1:] + conversion_char = None if format_type in u'doxX' and u'.' in format_spec: # Precision is not allowed for integers in format(), but ok in %-formatting. can_be_optimised = False elif format_type in u'ars': format_spec = format_spec[:-1] @@ -4385,7 +4386,11 @@ if format_type in u'doxX' and u'.' in format_spec: # Precision is not allowed for integers in format(), but ok in %-formatting. can_be_optimised = False elif format_type in u'ars': format_spec = format_spec[:-1] + conversion_char = format_type + elif format_type == u'd': + # '%d' formatting supports float, but '{obj:d}' does not => convert to int first. + conversion_char = 'd' substrings.append(ExprNodes.FormattedValueNode( arg.pos, value=arg, @@ -4390,6 +4395,6 @@ substrings.append(ExprNodes.FormattedValueNode( arg.pos, value=arg, - conversion_char=format_type if format_type in u'ars' else None, + conversion_char=conversion_char, format_spec=ExprNodes.UnicodeNode( pos, value=EncodedString(format_spec), constant_result=format_spec) if format_spec else None, diff --git a/tests/run/fstring.pyx b/tests/run/fstring.pyx index 4c7dbbc65a6d4c95a99c4eb8a3b825cedd36cc77_dGVzdHMvcnVuL2ZzdHJpbmcucHl4..0f6af780d201b1cef4e1ad0697a8bb75777e7914_dGVzdHMvcnVuL2ZzdHJpbmcucHl4 100644 --- a/tests/run/fstring.pyx +++ b/tests/run/fstring.pyx @@ -533,5 +533,5 @@ "//FormattedValueNode", "//JoinedStrNode", ) -def generated_fstring(int i, unicode u not None, o): +def generated_fstring(int i, float f, unicode u not None, o): """ @@ -537,5 +537,5 @@ """ - >>> i, u, o = 11, u'xyz', [1] + >>> i, f, u, o = 11, 1.3125, u'xyz', [1] >>> print((( ... u"(i) %s-%.3s-%r-%.3r-%d-%3d-%o-%04o-%x-%4x-%X-%03X-%.1f-%04.2f %% " ... u"(u) %s-%.2s-%r-%.7r %% " @@ -539,8 +539,9 @@ >>> print((( ... u"(i) %s-%.3s-%r-%.3r-%d-%3d-%o-%04o-%x-%4x-%X-%03X-%.1f-%04.2f %% " ... u"(u) %s-%.2s-%r-%.7r %% " - ... u"(o) %s-%.2s-%r-%.2r" + ... u"(o) %s-%.2s-%r-%.2r %% " + ... u"(f) %.2f-%d" ... ) % ( ... i, i, i, i, i, i, i, i, i, i, i, i, i, i, ... u, u, u, u, ... o, o, o, o, @@ -543,5 +544,6 @@ ... ) % ( ... i, i, i, i, i, i, i, i, i, i, i, i, i, i, ... u, u, u, u, ... o, o, o, o, + ... f, f, ... )).replace("-u'xyz'", "-'xyz'")) @@ -547,3 +549,3 @@ ... )).replace("-u'xyz'", "-'xyz'")) - (i) 11-11-11-11-11- 11-13-0013-b- b-B-00B-11.0-11.00 % (u) xyz-xy-'xyz'-'xyz' % (o) [1]-[1-[1]-[1 + (i) 11-11-11-11-11- 11-13-0013-b- b-B-00B-11.0-11.00 % (u) xyz-xy-'xyz'-'xyz' % (o) [1]-[1-[1]-[1 % (f) 1.31-1 @@ -549,7 +551,7 @@ - >>> print(generated_fstring(i, u, o).replace("-u'xyz'", "-'xyz'")) - (i) 11-11-11-11-11- 11-13-0013-b- b-B-00B-11.0-11.00 % (u) xyz-xy-'xyz'-'xyz' % (o) [1]-[1-[1]-[1 + >>> print(generated_fstring(i, f, u, o).replace("-u'xyz'", "-'xyz'")) + (i) 11-11-11-11-11- 11-13-0013-b- b-B-00B-11.0-11.00 % (u) xyz-xy-'xyz'-'xyz' % (o) [1]-[1-[1]-[1 % (f) 1.31-1 """ return ( u"(i) %s-%.3s-%r-%.3r-%d-%3d-%o-%04o-%x-%4x-%X-%03X-%.1f-%04.2f %% " u"(u) %s-%.2s-%r-%.7r %% " @@ -552,9 +554,10 @@ """ return ( u"(i) %s-%.3s-%r-%.3r-%d-%3d-%o-%04o-%x-%4x-%X-%03X-%.1f-%04.2f %% " u"(u) %s-%.2s-%r-%.7r %% " - u"(o) %s-%.2s-%r-%.2r" + u"(o) %s-%.2s-%r-%.2r %% " + u"(f) %.2f-%d" ) % ( i, i, i, i, i, i, i, i, i, i, i, i, i, i, u, u, u, u, o, o, o, o, @@ -557,7 +560,8 @@ ) % ( i, i, i, i, i, i, i, i, i, i, i, i, i, i, u, u, u, u, o, o, o, o, + f, f, )