Skip to content

Commit ca960a8

Browse files
Emit FutureWarning instead of DeprecationWarning for re-initialization.
1 parent d7da0f8 commit ca960a8

File tree

2 files changed

+20
-27
lines changed

2 files changed

+20
-27
lines changed

Lib/test/test_struct.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -591,27 +591,27 @@ def test_Struct_reinitialization(self):
591591
# Struct instance. This test can be used to detect the leak
592592
# when running with regrtest -L.
593593
s = struct.Struct('>h')
594-
with self.assertWarns(DeprecationWarning):
594+
msg = 'Re-initialization .* will not work'
595+
with self.assertWarnsRegex(FutureWarning, msg):
595596
s.__init__('>hh')
596597
self.assertEqual(s.format, '>hh')
597598
packed = b'\x00\x01\x00\x02'
598599
self.assertEqual(s.pack(1, 2), packed)
599600
self.assertEqual(s.unpack(packed), (1, 2))
600601

601-
with self.assertWarns(DeprecationWarning):
602-
s.__init__('>hh')
602+
s.__init__('>hh') # same format
603603
self.assertEqual(s.format, '>hh')
604604
self.assertEqual(s.pack(1, 2), packed)
605605
self.assertEqual(s.unpack(packed), (1, 2))
606606

607-
with self.assertWarns(DeprecationWarning):
607+
with self.assertWarnsRegex(FutureWarning, msg):
608608
with self.assertRaises(UnicodeEncodeError):
609609
s.__init__('\udc00')
610610
self.assertEqual(s.format, '>hh')
611611
self.assertEqual(s.pack(1, 2), packed)
612612
self.assertEqual(s.unpack(packed), (1, 2))
613613

614-
with self.assertWarns(DeprecationWarning):
614+
with self.assertWarnsRegex(FutureWarning, msg):
615615
with self.assertRaises(struct.error):
616616
s.__init__('$')
617617
self.assertEqual(s.format, '>hh')
@@ -873,10 +873,10 @@ def __init__(self, *args, **kwargs):
873873
my_struct = MyStruct(format='$')
874874
self.assertEqual(my_struct.pack(12345), b'\x30\x39')
875875
with self.assertWarnsRegex(DeprecationWarning, warnmsg + ".*can't encode"):
876-
my_struct = MyStruct('\u20ac')
876+
my_struct = MyStruct('\udc00')
877877
self.assertEqual(my_struct.pack(12345), b'\x30\x39')
878878
with self.assertWarnsRegex(DeprecationWarning, warnmsg + ".*can't encode"):
879-
my_struct = MyStruct(format='\u20ac')
879+
my_struct = MyStruct(format='\udc00')
880880
self.assertEqual(my_struct.pack(12345), b'\x30\x39')
881881

882882
def test_custom_struct_new(self):
@@ -885,7 +885,7 @@ class MyStruct(struct.Struct):
885885
def __new__(cls, *args, **kwargs):
886886
return super().__new__(cls, '>h')
887887

888-
for format in '>h', '<h', 42, '$', '\u20ac':
888+
for format in '>h', '<h', 42, '$', '\u20ac', '\udc00', b'\xa4':
889889
with self.subTest(format=format):
890890
my_struct = MyStruct(format)
891891
self.assertEqual(my_struct.format, '>h')
@@ -929,10 +929,10 @@ def __init__(self, newargs, initargs):
929929
with self.assertRaises(struct.error):
930930
MyStruct(('>h',), ('$',))
931931
with self.assertRaises(UnicodeEncodeError):
932-
MyStruct(('\u20ac',), ('>h',))
932+
MyStruct(('\udc00',), ('>h',))
933933
with self.assertWarns(FutureWarning):
934934
with self.assertRaises(UnicodeEncodeError):
935-
MyStruct(('>h',), ('\u20ac',))
935+
MyStruct(('>h',), ('\udc00',))
936936
with self.assertWarns(FutureWarning):
937937
my_struct = MyStruct(('>h',), ('<h',))
938938
self.assertEqual(my_struct.format, '<h')
@@ -955,7 +955,7 @@ class MyStruct(struct.Struct):
955955
with self.assertRaises(struct.error):
956956
MyStruct('$')
957957
with self.assertRaises(UnicodeEncodeError):
958-
MyStruct('\u20ac')
958+
MyStruct('\udc00')
959959
with self.assertRaises(TypeError):
960960
MyStruct('>h', 42)
961961
with self.assertRaises(TypeError):

Modules/_struct.c

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1944,13 +1944,13 @@ Struct___init___impl(PyStructObject *self, PyObject *format)
19441944
}
19451945
}
19461946
else if (!same_format(self, format)) {
1947-
if (!self->init_called) {
1948-
if (PyErr_WarnEx(PyExc_FutureWarning,
1949-
"Different format arguments for __new__() "
1950-
"and __init__() methods of Struct", 1))
1951-
{
1952-
return -1;
1953-
}
1947+
const char *msg = self->init_called
1948+
? "Re-initialization of Struct by calling the __init__() method "
1949+
"will not work in future Python versions"
1950+
: "Different format arguments for __new__() and __init__() "
1951+
"methods of Struct";
1952+
if (PyErr_WarnEx(PyExc_FutureWarning, msg, 1)) {
1953+
return -1;
19541954
}
19551955
if (set_format(self, format) < 0) {
19561956
return -1;
@@ -1963,15 +1963,8 @@ Struct___init___impl(PyStructObject *self, PyObject *format)
19631963
static int
19641964
s_init(PyObject *self, PyObject *args, PyObject *kwargs)
19651965
{
1966-
if (((PyStructObject *)self)->init_called) {
1967-
if (PyErr_WarnEx(PyExc_DeprecationWarning,
1968-
"Explicit call of __init__() on "
1969-
"initialized Struct is deprecated", 1))
1970-
{
1971-
return -1;
1972-
}
1973-
}
1974-
else if (Py_TYPE(self)->tp_init == s_init
1966+
if (!((PyStructObject *)self)->init_called
1967+
&& Py_TYPE(self)->tp_init == s_init
19751968
&& ((PyStructObject *)self)->s_format != Py_None)
19761969
{
19771970
/* Struct.__init__() was called implicitly.

0 commit comments

Comments
 (0)