are not generated by the parser or accepted by the code generator.
* The ``dims`` property of ``ast.Tuple`` will be removed in Python 3.21. Use
the ``ast.Tuple.elts`` property instead.
+
+* :mod:`struct`:
+
+ * Soft-deprecated since Python 3.15, using ``'F'`` and ``'D'`` type codes are now
+ deprecated. These codes will be removed in Python 3.21. Use instead
+ two-letter forms ``'Zf'`` and ``'Zd'``.
(Contributed by Gregory P. Smith in :gh:`86519` and
Hugo van Kemenade in :gh:`148100`.)
-
-* Using ``'F'`` and ``'D'`` format type codes of the :mod:`struct` module
- now are :term:`soft deprecated` in favor of two-letter forms ``'Zf'``
- and ``'Zd'``.
- (Contributed by Sergey B Kirpichev in :gh:`121249`.)
.. versionchanged:: 3.15
Added support for the ``'Zf'`` and ``'Zd'`` formats.
- ``'F'`` and ``'D'`` formats are :term:`soft deprecated`.
+
+.. versionchanged:: 3.16
+ ``'F'`` and ``'D'`` formats are deprecated.
.. seealso::
3.9, now issues a deprecation warning on use. This property is slated for
removal in 3.21. Use ``ast.Tuple.elts`` instead.
+* :mod:`struct`:
+
+ * Soft-deprecated since Python 3.15, using ``'F'`` and ``'D'`` type codes are now
+ deprecated. These codes will be removed in Python 3.21. Use instead
+ two-letter forms ``'Zf'`` and ``'Zd'``.
+ (Contributed by Sergey B Kirpichev in :gh:`121249`.)
+
.. Add deprecations above alphabetically, not here at the end.
.. include:: ../deprecations/pending-removal-in-3.17.rst
self.assertIs(c_float_complex.__ctype_le__.__ctype_be__,
c_float_complex)
s = c_float_complex(math.pi+1j)
- self.assertEqual(bin(struct.pack("F", math.pi+1j)), bin(s))
+ self.assertEqual(bin(struct.pack("Zf", math.pi+1j)), bin(s))
self.assertAlmostEqual(s.value, math.pi+1j, places=6)
s = c_float_complex.__ctype_le__(math.pi+1j)
self.assertAlmostEqual(s.value, math.pi+1j, places=6)
- self.assertEqual(bin(struct.pack("<F", math.pi+1j)), bin(s))
+ self.assertEqual(bin(struct.pack("<Zf", math.pi+1j)), bin(s))
s = c_float_complex.__ctype_be__(math.pi+1j)
self.assertAlmostEqual(s.value, math.pi+1j, places=6)
- self.assertEqual(bin(struct.pack(">F", math.pi+1j)), bin(s))
+ self.assertEqual(bin(struct.pack(">Zf", math.pi+1j)), bin(s))
@unittest.skipUnless(hasattr(ctypes, 'c_double_complex'), "No complex types")
def test_endian_double_complex(self):
self.assertIs(c_double_complex.__ctype_le__.__ctype_be__,
c_double_complex)
s = c_double_complex(math.pi+1j)
- self.assertEqual(bin(struct.pack("D", math.pi+1j)), bin(s))
+ self.assertEqual(bin(struct.pack("Zd", math.pi+1j)), bin(s))
self.assertAlmostEqual(s.value, math.pi+1j, places=6)
s = c_double_complex.__ctype_le__(math.pi+1j)
self.assertAlmostEqual(s.value, math.pi+1j, places=6)
- self.assertEqual(bin(struct.pack("<D", math.pi+1j)), bin(s))
+ self.assertEqual(bin(struct.pack("<Zd", math.pi+1j)), bin(s))
s = c_double_complex.__ctype_be__(math.pi+1j)
self.assertAlmostEqual(s.value, math.pi+1j, places=6)
- self.assertEqual(bin(struct.pack(">D", math.pi+1j)), bin(s))
+ self.assertEqual(bin(struct.pack(">Zd", math.pi+1j)), bin(s))
def test_endian_other(self):
self.assertIs(c_byte.__ctype_le__, c_byte)
self.assertListEqual(half_view.tolist(), float_view.tolist())
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_data = struct.pack('ZfZfZf', 0.0, -1.5j, 1+2j)
+ double_complex_data = struct.pack('ZdZdZd', 0.0, -1.5j, 1+2j)
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)
import unittest
import struct
import sys
+import warnings
import weakref
from test import support
values = [complex(*_) for _ in combinations([1, -1, 0.0, -0.0, 2,
-3, INF, -INF, NAN], 2)]
for z in values:
- for f in [
- 'F', 'D', 'Zf', 'Zd',
- '>F', '>D', '>Zf', '>Zd',
- '<F', '<D', '<Zf', '<Zd',
- ]:
+ for f in ['Zf', 'Zd', '>Zf', '>Zd', '<Zf', '<Zd']:
with self.subTest(z=z, format=f):
round_trip = struct.unpack(f, struct.pack(f, z))[0]
self.assertComplexesAreIdentical(z, round_trip)
+ z = 1+1j
+ for fmt in ['F', 'D', '>F', '>D', '<F', '<D']:
+ with self.subTest(format=fmt):
+ with warnings.catch_warnings():
+ warnings.simplefilter("error", DeprecationWarning)
+ self.assertRaises(DeprecationWarning, struct.pack, fmt, z)
+ with warnings.catch_warnings():
+ with self.assertWarns(DeprecationWarning):
+ b = struct.pack(fmt, z)
+
+ with warnings.catch_warnings():
+ warnings.simplefilter("error", DeprecationWarning)
+ self.assertRaises(DeprecationWarning, struct.unpack, fmt, b)
+ with self.assertWarns(DeprecationWarning):
+ round_trip = struct.unpack(fmt, b)[0]
+ self.assertComplexesAreIdentical(z, round_trip)
@unittest.skipIf(
support.is_android or support.is_apple_mobile,
--- /dev/null
+Deprecate using ``'F'`` and ``'D'`` type codes in the :mod:`struct` module.
if (e == NULL)
return -1;
+ if (strcmp(e->format, "F") == 0) {
+ if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "The 'F' type code is deprecated, use 'Zf'", 1))
+ {
+ return -1;
+ }
+ }
+ if (strcmp(e->format, "D") == 0) {
+ if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "The 'D' type code is deprecated, use 'Zd'", 1))
+ {
+ return -1;
+ }
+ }
+
switch (c) {
case 's': _Py_FALLTHROUGH;
case 'p':
}
v = PyBytes_FromStringAndSize(res + 1, n);
} else {
+ if (strcmp(e->format, "F") == 0) {
+ if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "The 'F' type code is deprecated, use 'Zf'", 1))
+ {
+ goto fail;
+ }
+ }
+ if (strcmp(e->format, "D") == 0) {
+ if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "The 'D' type code is deprecated, use 'Zd'", 1))
+ {
+ goto fail;
+ }
+ }
v = e->unpack(state, res, e);
}
if (v == NULL)