Skip to content

Commit fff147f

Browse files
committed
gh-78724: deprecate incomplete initialization of struct.Struct()
* ``Struct.__new__()`` will require a mandatory argument (format) * Calls of ``__init__()`` method on initialized Struct are deprecated
1 parent ce6bae9 commit fff147f

File tree

5 files changed

+40
-2
lines changed

5 files changed

+40
-2
lines changed

Doc/deprecations/pending-removal-in-3.20.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
Pending removal in Python 3.20
22
------------------------------
33

4+
* Calling the ``Struct.__new__()`` without required argument now is
5+
deprecated and will be removed in Python 3.20. Calling
6+
:meth:`~object.__init__` method on initialized :class:`~struct.Struct`
7+
objects is deprecated and will be removed in Python 3.20.
8+
9+
(Contributed by Sergey B Kirpichev in :gh:`78724`.)
10+
411
* The ``__version__``, ``version`` and ``VERSION`` attributes have been
512
deprecated in these standard library modules and will be removed in
613
Python 3.20. Use :py:data:`sys.version_info` instead.

Doc/whatsnew/3.15.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,15 @@ New deprecations
11371137

11381138
(Contributed by Bénédikt Tran in :gh:`134978`.)
11391139

1140+
* :mod:`struct`:
1141+
1142+
* Calling the ``Struct.__new__()`` without required argument now is
1143+
deprecated and will be removed in Python 3.20. Calling
1144+
:meth:`~object.__init__` method on initialized :class:`~struct.Struct`
1145+
objects is deprecated and will be removed in Python 3.20.
1146+
1147+
(Contributed by Sergey B Kirpichev in :gh:`78724`.)
1148+
11401149
* ``__version__``
11411150

11421151
* The ``__version__``, ``version`` and ``VERSION`` attributes have been

Lib/test/test_struct.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import unittest
88
import struct
99
import sys
10+
import warnings
1011
import weakref
1112

1213
from test import support
@@ -575,7 +576,11 @@ def test_Struct_reinitialization(self):
575576
# Struct instance. This test can be used to detect the leak
576577
# when running with regrtest -L.
577578
s = struct.Struct('i')
578-
s.__init__('ii')
579+
with self.assertWarns(DeprecationWarning):
580+
s.__init__('ii')
581+
with warnings.catch_warnings():
582+
warnings.simplefilter("error", DeprecationWarning)
583+
self.assertRaises(DeprecationWarning, s.__init__, 'ii')
579584

580585
def check_sizeof(self, format_str, number_of_codes):
581586
# The size of 'PyStructObject'
@@ -783,7 +788,8 @@ class MyStruct(struct.Struct):
783788
def __init__(self):
784789
super().__init__('>h')
785790

786-
my_struct = MyStruct()
791+
with self.assertWarns(DeprecationWarning):
792+
my_struct = MyStruct()
787793
self.assertEqual(my_struct.pack(12345), b'\x30\x39')
788794

789795
def test_repr(self):
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Calling the ``Struct.__new__()`` without required argument now is deprecated.
2+
Calling :meth:`~object.__init__` method on initialized :class:`~struct.Struct`
3+
objects is deprecated. Patch by Sergey B Kirpichev.

Modules/_struct.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1762,6 +1762,12 @@ s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
17621762
{
17631763
PyObject *self;
17641764

1765+
if (PyTuple_GET_SIZE(args) != 1
1766+
&& PyErr_WarnEx(PyExc_DeprecationWarning,
1767+
"Struct().__new__() has one required argument", 1))
1768+
{
1769+
return NULL;
1770+
}
17651771
assert(type != NULL);
17661772
allocfunc alloc_func = PyType_GetSlot(type, Py_tp_alloc);
17671773
assert(alloc_func != NULL);
@@ -1796,6 +1802,13 @@ Struct___init___impl(PyStructObject *self, PyObject *format)
17961802
{
17971803
int ret = 0;
17981804

1805+
if (self->s_codes
1806+
&& PyErr_WarnEx(PyExc_DeprecationWarning,
1807+
("Explicit call of __init__() on "
1808+
"initialized Struct() is deprecated"), 1))
1809+
{
1810+
return -1;
1811+
}
17991812
if (PyUnicode_Check(format)) {
18001813
format = PyUnicode_AsASCIIString(format);
18011814
if (format == NULL)

0 commit comments

Comments
 (0)