Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions Doc/library/array.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,6 @@ defined:
+-----------+--------------------+-------------------+-----------------------+-------+
| ``'d'`` | double | float | 8 | |
+-----------+--------------------+-------------------+-----------------------+-------+
| ``'F'`` | float complex | complex | 8 | \(4) |
+-----------+--------------------+-------------------+-----------------------+-------+
| ``'D'`` | double complex | complex | 16 | \(4) |
+-----------+--------------------+-------------------+-----------------------+-------+
| ``'Zf'`` | float complex | complex | 8 | \(4) |
+-----------+--------------------+-------------------+-----------------------+-------+
| ``'Zd'`` | double complex | complex | 16 | \(4) |
Expand Down Expand Up @@ -84,7 +80,7 @@ Notes:
.. versionadded:: 3.15

(4)
Complex types (``F``, ``D``, ``Zf`` and ``Zd``) are available unconditionally,
Complex types (``Zf`` and ``Zd``) are available unconditionally,
regardless on support for complex types (the Annex G of the C11 standard)
by the C compiler.
As specified in the C11 standard, each complex type is represented by a
Expand Down
6 changes: 3 additions & 3 deletions Doc/whatsnew/3.15.rst
Original file line number Diff line number Diff line change
Expand Up @@ -671,8 +671,8 @@ Other language changes
(Contributed by James Hilton-Balfe in :gh:`128335`.)

* The class :class:`memoryview` now supports the :c:expr:`float complex` and
:c:expr:`double complex` C types: formatting characters ``'F'``/``'Zf'``
and ``'D'``/``'Zd'`` respectively.
:c:expr:`double complex` C types: formatting characters ``'Zf'`` and ``'Zd'``
respectively.
(Contributed by Victor Stinner in :gh:`146151` and :gh:`148675`.)

* Allow the *count* argument of :meth:`bytes.replace` to be a keyword.
Expand Down Expand Up @@ -724,7 +724,7 @@ array
-----

* Support the :c:expr:`float complex` and :c:expr:`double complex` C types:
formatting characters ``'F'``/``'Zf'`` and ``'D'``/``'Zd'`` respectively.
formatting characters ``'Zf'`` and ``'Zd'`` respectively.
(Contributed by Victor Stinner in :gh:`146151` and :gh:`148675`.)

* Support half-floats (16-bit IEEE 754 binary interchange format): formatting
Expand Down
20 changes: 2 additions & 18 deletions Lib/test/test_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def __init__(self, typecode, newarg=None):

typecodes = (
'u', 'w', 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L',
'f', 'd', 'q', 'Q', 'F', 'D', 'e', 'Zf', 'Zd')
'f', 'd', 'q', 'Q', 'e', 'Zf', 'Zd')


class MiscTest(unittest.TestCase):
Expand Down Expand Up @@ -210,14 +210,6 @@ def test_numbers(self):
[9006104071832581.0, float('inf'), float('-inf'), -0.0]),
(['d'], IEEE_754_DOUBLE_BE, '>dddd',
[9006104071832581.0, float('inf'), float('-inf'), -0.0]),
(['F'], IEEE_754_FLOAT_COMPLEX_LE, '<FFFF',
[16711938.0j, float('inf'), complex('1-infj'), -0.0]),
(['F'], IEEE_754_FLOAT_COMPLEX_BE, '>FFFF',
[16711938.0j, float('inf'), complex('1-infj'), -0.0]),
(['D'], IEEE_754_DOUBLE_COMPLEX_LE, '<DDDD',
[9006104071832581.0j, float('inf'), complex('1-infj'), -0.0]),
(['D'], IEEE_754_DOUBLE_COMPLEX_BE, '>DDDD',
[9006104071832581.0j, float('inf'), complex('1-infj'), -0.0]),
(['Zf'], IEEE_754_FLOAT_COMPLEX_LE, '<ZfZfZfZf',
[16711938.0j, float('inf'), complex('1-infj'), -0.0]),
(['Zf'], IEEE_754_FLOAT_COMPLEX_BE, '>ZfZfZfZf',
Expand Down Expand Up @@ -1645,18 +1637,10 @@ def test_alloc_overflow(self):


class ComplexFloatTest(CFPTest, unittest.TestCase):
typecode = 'F'
minitemsize = 8

class ComplexDoubleTest(CFPTest, unittest.TestCase):
typecode = 'D'
minitemsize = 16

class ComplexZfFloatTest(CFPTest, unittest.TestCase):
typecode = 'Zf'
minitemsize = 8

class ComplexZdDoubleTest(CFPTest, unittest.TestCase):
class ComplexDoubleTest(CFPTest, unittest.TestCase):
typecode = 'Zd'
minitemsize = 16

Expand Down
12 changes: 5 additions & 7 deletions Lib/test/test_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
'h':0, 'H':0, 'i':0, 'I':0,
'l':0, 'L':0, 'n':0, 'N':0,
'e':0, 'f':0, 'd':0, 'P':0,
'F':0, 'D':0, 'Zf':0, 'Zd':0,
'Zf':0, 'Zd':0,
}

# NumPy does not have 'n' or 'N':
Expand All @@ -94,8 +94,6 @@
'q':(-(1<<63), 1<<63), 'Q':(0, 1<<64),
'e':(-65519, 65520), 'f':(-(1<<63), 1<<63),
'd':(-(1<<1023), 1<<1023),
'F':(-(1<<63), 1<<63),
'D':(-(1<<1023), 1<<1023),
'Zf':(-(1<<63), 1<<63),
'Zd':(-(1<<1023), 1<<1023),
}
Expand All @@ -112,9 +110,9 @@ def native_type_range(fmt):
lh = (-(1<<63), 1<<63)
elif fmt == 'd':
lh = (-(1<<1023), 1<<1023)
elif fmt in ('F', 'Zf'):
elif fmt == 'Zf':
lh = (-(1<<63), 1<<63)
elif fmt in ('D', 'Zd'):
elif fmt == 'Zd':
lh = (-(1<<1023), 1<<1023)
else:
for exp in (128, 127, 64, 63, 32, 31, 16, 15, 8, 7):
Expand Down Expand Up @@ -184,7 +182,7 @@ def randrange_fmt(mode, char, obj):
if char in 'efd':
x = struct.pack(char, x)
x = struct.unpack(char, x)[0]
if char in ('F', 'D', 'Zf', 'Zd'):
if char in ('Zf', 'Zd'):
y = randrange(*fmtdict[mode][char])
x = complex(x, y)
x = struct.pack(char, x)
Expand Down Expand Up @@ -3055,7 +3053,7 @@ def test_memoryview_assign(self):
continue
m2 = m1.cast(fmt)
lo, hi = _range
if fmt in ("d", "f", "D", "F", "Zd", "Zf"):
if fmt in ("d", "f", "Zd", "Zf"):
lo, hi = -2**1024, 2**1024
if fmt != 'P': # PyLong_AsVoidPtr() accepts negative numbers
self.assertRaises(ValueError, m2.__setitem__, 0, lo-1)
Expand Down
6 changes: 1 addition & 5 deletions Lib/test/test_memoryview.py
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,7 @@ def check_equal(view, is_equal):
check_equal(m, True)

# Test complex formats
for complex_format in ('F', 'D', 'Zf', 'Zd'):
for complex_format in ('Zf', 'Zd'):
with self.subTest(format=complex_format):
data = struct.pack(complex_format * 3, 1.0, 2.0, float('nan'))
m = memoryview(data).cast(complex_format)
Expand Down Expand Up @@ -719,10 +719,6 @@ def test_half_float(self):
def test_complex_types(self):
float_complex_data = struct.pack('FFF', 0.0, -1.5j, 1+2j)
double_complex_data = struct.pack('DDD', 0.0, -1.5j, 1+2j)
float_complex_view = memoryview(float_complex_data).cast('F')
double_complex_view = memoryview(double_complex_data).cast('D')
self.assertEqual(float_complex_view.nbytes * 2, double_complex_view.nbytes)
self.assertListEqual(float_complex_view.tolist(), double_complex_view.tolist())
float_complex_view = memoryview(float_complex_data).cast('Zf')
double_complex_view = memoryview(double_complex_data).cast('Zd')
self.assertEqual(float_complex_view.nbytes * 2, double_complex_view.nbytes)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Remove ``F`` and ``D`` formats from :mod:`array` and :class:`memoryview`.
Patch by Victor Stinner.
21 changes: 3 additions & 18 deletions Modules/arraymodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -782,8 +782,6 @@ static const struct arraydescr descriptors[] = {
{"e", sizeof(short), e_getitem, e_setitem, NULL, 0, 0},
{"f", sizeof(float), f_getitem, f_setitem, NULL, 0, 0},
{"d", sizeof(double), d_getitem, d_setitem, NULL, 0, 0},
{"F", 2*sizeof(float), cf_getitem, cf_setitem, NULL, 0, 0},
{"D", 2*sizeof(double), cd_getitem, cd_setitem, NULL, 0, 0},
{"Zf", 2*sizeof(float), cf_getitem, cf_setitem, NULL, 0, 0},
{"Zd", 2*sizeof(double), cd_getitem, cd_setitem, NULL, 0, 0},
{NULL, 0, 0, 0, 0, 0, 0} /* Sentinel */
Expand Down Expand Up @@ -1612,9 +1610,7 @@ array_array_byteswap_impl(arrayobject *self)
}
break;
case 8:
if (strcmp(self->ob_descr->typecode, "F") != 0
&& strcmp(self->ob_descr->typecode, "Zf") != 0)
{
if (strcmp(self->ob_descr->typecode, "Zf") != 0) {
for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 8) {
char p0 = p[0];
char p1 = p[1];
Expand Down Expand Up @@ -1648,8 +1644,7 @@ array_array_byteswap_impl(arrayobject *self)
}
break;
case 16:
assert(strcmp(self->ob_descr->typecode, "D") == 0
|| strcmp(self->ob_descr->typecode, "Zd") == 0);
assert(strcmp(self->ob_descr->typecode, "Zd") == 0);
for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 8) {
char t0 = p[0];
char t1 = p[1];
Expand Down Expand Up @@ -2159,14 +2154,6 @@ typecode_to_mformat_code(const char *typecode)
case 'd':
return _PY_FLOAT_BIG_ENDIAN ? IEEE_754_DOUBLE_BE : IEEE_754_DOUBLE_LE;

case 'F':
return _PY_FLOAT_BIG_ENDIAN ? \
IEEE_754_FLOAT_COMPLEX_BE : IEEE_754_FLOAT_COMPLEX_LE;

case 'D':
return _PY_FLOAT_BIG_ENDIAN ? \
IEEE_754_DOUBLE_COMPLEX_BE : IEEE_754_DOUBLE_COMPLEX_LE;

case 'Z': {
switch (typecode[1]) {
case 'f':
Expand Down Expand Up @@ -3167,7 +3154,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
}
Py_XDECREF(it);
PyErr_SetString(PyExc_ValueError,
"bad typecode (must be b, B, u, w, h, H, i, I, l, L, q, Q, e, f, d, F, D, Zf or Zd)");
"bad typecode (must be b, B, u, w, h, H, i, I, l, L, q, Q, e, f, d, Zf or Zd)");
return NULL;
}

Expand Down Expand Up @@ -3205,8 +3192,6 @@ The following type codes are defined:\n\
'e' 16-bit IEEE floats 2\n\
'f' floating-point 4\n\
'd' floating-point 8\n\
'F' float complex 8\n\
'D' double complex 16\n\
'Zf' float complex 8\n\
'Zd' double complex 16\n\
\n\
Expand Down
48 changes: 0 additions & 48 deletions Objects/memoryobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1217,8 +1217,6 @@ get_native_fmtchar(const char **result, const char *fmt)
case 'f': size = sizeof(float); break;
case 'd': size = sizeof(double); break;
case 'e': size = sizeof(float) / 2; break;
case 'F': size = 2*sizeof(float); break;
case 'D': size = 2*sizeof(double); break;
case '?': size = sizeof(_Bool); break;
case 'P': size = sizeof(void *); break;
case 'Z': {
Expand Down Expand Up @@ -1284,8 +1282,6 @@ get_native_fmtstr(const char *fmt)
case 'f': RETURN("f");
case 'd': RETURN("d");
case 'e': RETURN("e");
case 'F': RETURN("F");
case 'D': RETURN("D");
case 'Z': {
switch (fmt[1]) {
case 'f': RETURN("Zf");
Expand Down Expand Up @@ -1865,16 +1861,6 @@ unpack_single(PyMemoryViewObject *self, const char *ptr, const char *fmt)
case 'e': d[0] = PyFloat_Unpack2(ptr, endian); goto convert_double;

/* complexes */
case 'F':
d[0] = PyFloat_Unpack4(ptr, endian);
d[1] = PyFloat_Unpack4(ptr + sizeof(float), endian);
goto convert_double_complex;

case 'D':
d[0] = PyFloat_Unpack8(ptr, endian);
d[1] = PyFloat_Unpack8(ptr + sizeof(double), endian);
goto convert_double_complex;

case 'Z': {
switch (fmt[1]) {
case 'f':
Expand Down Expand Up @@ -2055,24 +2041,6 @@ pack_single(PyMemoryViewObject *self, char *ptr, PyObject *item, const char *fmt
break;

/* complexes */
case 'F': case 'D':
c = PyComplex_AsCComplex(item);
if (c.real == -1.0 && PyErr_Occurred()) {
goto err_occurred;
}
CHECK_RELEASED_INT_AGAIN(self);
if (fmt[0] == 'D') {
double x[2] = {c.real, c.imag};

memcpy(ptr, &x, sizeof(x));
}
else {
float x[2] = {(float)c.real, (float)c.imag};

memcpy(ptr, &x, sizeof(x));
}
break;

case 'Z': {
switch (fmt[1]) {
case 'f': case 'd':
Expand Down Expand Up @@ -3138,22 +3106,6 @@ unpack_cmp(const char *p, const char *q, const char *fmt,
}

/* complexes */
case 'F':
{
float x[2], y[2];

memcpy(&x, p, sizeof(x));
memcpy(&y, q, sizeof(y));
return (x[0] == y[0]) && (x[1] == y[1]);
}
case 'D':
{
double x[2], y[2];

memcpy(&x, p, sizeof(x));
memcpy(&y, q, sizeof(y));
return (x[0] == y[0]) && (x[1] == y[1]);
}
case 'Z': {
switch (fmt[1]) {
case 'f':
Expand Down
Loading