Index: Objects/stringlib/formatter.h =================================================================== --- Objects/stringlib/formatter.h (revision 83227) +++ Objects/stringlib/formatter.h (working copy) @@ -1136,9 +1136,10 @@ /* Omitted type specifier. Should be like str(self). */ type = 'g'; default_precision = PyFloat_STR_PRECISION; - add_parens = 1; - if (re == 0.0) + if (re == 0.0 && copysign(1.0, re) == 1.0) skip_re = 1; + else + add_parens = 1; } if (type == 'n') @@ -1223,8 +1224,11 @@ n_re_digits, n_re_remainder, re_has_decimal, &locale, &tmp_format); - /* Same formatting, but always include a sign. */ - tmp_format.sign = '+'; + /* Same formatting, but always include a sign, unless the real part is + * going to be omitted, in which case we use whatever sign convention was + * requested by the original format. */ + if (!skip_re) + tmp_format.sign = '+'; n_im_total = calc_number_widths(&im_spec, 0, im_sign_char, p_im, n_im_digits, n_im_remainder, im_has_decimal, &locale, &tmp_format); Index: Lib/test/test_complex.py =================================================================== --- Lib/test/test_complex.py (revision 83227) +++ Lib/test/test_complex.py (working copy) @@ -506,6 +506,16 @@ self.assertEqual(format(z, '-'), str(z)) self.assertEqual(format(z, '<'), str(z)) self.assertEqual(format(z, '10'), str(z)) + z = complex(0.0, 3.0) + self.assertEqual(format(z, ''), str(z)) + self.assertEqual(format(z, '-'), str(z)) + self.assertEqual(format(z, '<'), str(z)) + self.assertEqual(format(z, '2'), str(z)) + z = complex(-0.0, 2.0) + self.assertEqual(format(z, ''), str(z)) + self.assertEqual(format(z, '-'), str(z)) + self.assertEqual(format(z, '<'), str(z)) + self.assertEqual(format(z, '3'), str(z)) self.assertEqual(format(1+3j, 'g'), '1+3j') self.assertEqual(format(3j, 'g'), '0+3j')