Commit 58a42244 authored by Eric Smith's avatar Eric Smith

Issue #1588: Add complex.__format__.

parent 738a41dd
...@@ -54,6 +54,12 @@ PyAPI_FUNC(double) PyComplex_RealAsDouble(PyObject *op); ...@@ -54,6 +54,12 @@ PyAPI_FUNC(double) PyComplex_RealAsDouble(PyObject *op);
PyAPI_FUNC(double) PyComplex_ImagAsDouble(PyObject *op); PyAPI_FUNC(double) PyComplex_ImagAsDouble(PyObject *op);
PyAPI_FUNC(Py_complex) PyComplex_AsCComplex(PyObject *op); PyAPI_FUNC(Py_complex) PyComplex_AsCComplex(PyObject *op);
/* Format the object based on the format_spec, as defined in PEP 3101
(Advanced String Formatting). */
PyAPI_FUNC(PyObject *) _PyComplex_FormatAdvanced(PyObject *obj,
Py_UNICODE *format_spec,
Py_ssize_t format_spec_len);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
...@@ -436,7 +436,66 @@ class ComplexTest(unittest.TestCase): ...@@ -436,7 +436,66 @@ class ComplexTest(unittest.TestCase):
self.assertFloatsAreIdentical(0.0 + z.imag, self.assertFloatsAreIdentical(0.0 + z.imag,
0.0 + roundtrip.imag) 0.0 + roundtrip.imag)
def test_format(self):
# empty format string is same as str()
self.assertEqual(format(1+3j, ''), str(1+3j))
self.assertEqual(format(1.5+3.5j, ''), str(1.5+3.5j))
self.assertEqual(format(3j, ''), str(3j))
self.assertEqual(format(3.2j, ''), str(3.2j))
self.assertEqual(format(3+0j, ''), str(3+0j))
self.assertEqual(format(3.2+0j, ''), str(3.2+0j))
self.assertEqual(format(1+3j, 'g'), '1+3j')
self.assertEqual(format(3j, 'g'), '0+3j')
self.assertEqual(format(1.5+3.5j, 'g'), '1.5+3.5j')
self.assertEqual(format(1.5+3.5j, '+g'), '+1.5+3.5j')
self.assertEqual(format(1.5-3.5j, '+g'), '+1.5-3.5j')
self.assertEqual(format(1.5-3.5j, '-g'), '1.5-3.5j')
self.assertEqual(format(1.5+3.5j, ' g'), ' 1.5+3.5j')
self.assertEqual(format(1.5-3.5j, ' g'), ' 1.5-3.5j')
self.assertEqual(format(-1.5+3.5j, ' g'), '-1.5+3.5j')
self.assertEqual(format(-1.5-3.5j, ' g'), '-1.5-3.5j')
self.assertEqual(format(-1.5-3.5e-20j, 'g'), '-1.5-3.5e-20j')
self.assertEqual(format(-1.5-3.5j, 'f'), '-1.500000-3.500000j')
self.assertEqual(format(-1.5-3.5j, 'F'), '-1.500000-3.500000j')
self.assertEqual(format(-1.5-3.5j, 'e'), '-1.500000e+00-3.500000e+00j')
self.assertEqual(format(-1.5-3.5j, '.2e'), '-1.50e+00-3.50e+00j')
self.assertEqual(format(-1.5-3.5j, '.2E'), '-1.50E+00-3.50E+00j')
self.assertEqual(format(-1.5e10-3.5e5j, '.2G'), '-1.5E+10-3.5E+05j')
self.assertEqual(format(1.5+3j, '<20g'), '1.5+3j ')
self.assertEqual(format(1.5+3j, '*<20g'), '1.5+3j**************')
self.assertEqual(format(1.5+3j, '>20g'), ' 1.5+3j')
self.assertEqual(format(1.5+3j, '^20g'), ' 1.5+3j ')
self.assertEqual(format(1.5+3j, '<20'), '(1.5+3j) ')
self.assertEqual(format(1.5+3j, '>20'), ' (1.5+3j)')
self.assertEqual(format(1.5+3j, '^20'), ' (1.5+3j) ')
self.assertEqual(format(1.123-3.123j, '^20.2'), ' (1.1-3.1j) ')
self.assertEqual(format(1.5+3j, '<20.2f'), '1.50+3.00j ')
self.assertEqual(format(1.5e20+3j, '<20.2f'), '150000000000000000000.00+3.00j')
self.assertEqual(format(1.5e20+3j, '>40.2f'), ' 150000000000000000000.00+3.00j')
self.assertEqual(format(1.5e20+3j, '^40,.2f'), ' 150,000,000,000,000,000,000.00+3.00j ')
self.assertEqual(format(1.5e21+3j, '^40,.2f'), ' 1,500,000,000,000,000,000,000.00+3.00j ')
self.assertEqual(format(1.5e21+3000j, ',.2f'), '1,500,000,000,000,000,000,000.00+3,000.00j')
# alternate is invalid
self.assertRaises(ValueError, (1.5+0.5j).__format__, '#f')
# zero padding is invalid
self.assertRaises(ValueError, (1.5+0.5j).__format__, '010f')
# '=' alignment is invalid
self.assertRaises(ValueError, (1.5+3j).__format__, '=20')
# integer presentation types are an error
for t in 'bcdoxX':
self.assertRaises(ValueError, (1.5+0.5j).__format__, t)
# make sure everything works in ''.format()
self.assertEqual('*{0:.3f}*'.format(3.14159+2.71828j), '*3.142+2.718j*')
def test_main(): def test_main():
support.run_unittest(ComplexTest) support.run_unittest(ComplexTest)
......
...@@ -12,6 +12,9 @@ What's New in Python 3.1 beta 1? ...@@ -12,6 +12,9 @@ What's New in Python 3.1 beta 1?
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #1588: Add complex.__format__. For example,
format(complex(1, 2./3), '.5') now produces a sensible result.
- Issue #5864: Fix empty format code formatting for floats so that it - Issue #5864: Fix empty format code formatting for floats so that it
never gives more than the requested number of significant digits. never gives more than the requested number of significant digits.
......
...@@ -681,6 +681,23 @@ complex_getnewargs(PyComplexObject *v) ...@@ -681,6 +681,23 @@ complex_getnewargs(PyComplexObject *v)
return Py_BuildValue("(dd)", c.real, c.imag); return Py_BuildValue("(dd)", c.real, c.imag);
} }
PyDoc_STRVAR(complex__format__doc,
"complex.__format__() -> str\n"
"\n"
"Converts to a string according to format_spec.");
static PyObject *
complex__format__(PyObject* self, PyObject* args)
{
PyObject *format_spec;
if (!PyArg_ParseTuple(args, "U:__format__", &format_spec))
return NULL;
return _PyComplex_FormatAdvanced(self,
PyUnicode_AS_UNICODE(format_spec),
PyUnicode_GET_SIZE(format_spec));
}
#if 0 #if 0
static PyObject * static PyObject *
complex_is_finite(PyObject *self) complex_is_finite(PyObject *self)
...@@ -705,6 +722,8 @@ static PyMethodDef complex_methods[] = { ...@@ -705,6 +722,8 @@ static PyMethodDef complex_methods[] = {
complex_is_finite_doc}, complex_is_finite_doc},
#endif #endif
{"__getnewargs__", (PyCFunction)complex_getnewargs, METH_NOARGS}, {"__getnewargs__", (PyCFunction)complex_getnewargs, METH_NOARGS},
{"__format__", (PyCFunction)complex__format__,
METH_VARARGS, complex__format__doc},
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
......
This diff is collapsed.
...@@ -6,8 +6,9 @@ ...@@ -6,8 +6,9 @@
#include "../Objects/stringlib/unicodedefs.h" #include "../Objects/stringlib/unicodedefs.h"
#define FORMAT_STRING _PyUnicode_FormatAdvanced #define FORMAT_STRING _PyUnicode_FormatAdvanced
#define FORMAT_LONG _PyLong_FormatAdvanced #define FORMAT_LONG _PyLong_FormatAdvanced
#define FORMAT_FLOAT _PyFloat_FormatAdvanced #define FORMAT_FLOAT _PyFloat_FormatAdvanced
#define FORMAT_COMPLEX _PyComplex_FormatAdvanced
#include "../Objects/stringlib/formatter.h" #include "../Objects/stringlib/formatter.h"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment