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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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