Skip to content

Commit 1658213

Browse files
anandoleecopybara-github
authored andcommitted
BREAKING CHANGE in v26: Reject extend repeated field with none iterable (Raise TypeError)
For example m.repeated_int32.extend(None) will be rejected PiperOrigin-RevId: 595840357
1 parent c51f111 commit 1658213

File tree

3 files changed

+19
-25
lines changed

3 files changed

+19
-25
lines changed

python/google/protobuf/internal/containers.py

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -136,17 +136,7 @@ def insert(self, key: int, value: _T) -> None:
136136

137137
def extend(self, elem_seq: Iterable[_T]) -> None:
138138
"""Extends by appending the given iterable. Similar to list.extend()."""
139-
# TODO: Change OSS to raise error too
140-
if elem_seq is None:
141-
return
142-
try:
143-
elem_seq_iter = iter(elem_seq)
144-
except TypeError:
145-
if not elem_seq:
146-
warnings.warn('Value is not iterable. Please remove the wrong '
147-
'usage. This will be changed to raise TypeError soon.')
148-
return
149-
raise
139+
elem_seq_iter = iter(elem_seq)
150140
new_values = [self._type_checker.CheckValue(elem) for elem in elem_seq_iter]
151141
if new_values:
152142
self._values.extend(new_values)

python/google/protobuf/internal/message_test.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,12 @@ def testExtendInt32WithNothing(self, message_module):
10121012
m = message_module.TestAllTypes()
10131013
self.assertSequenceEqual([], m.repeated_int32)
10141014

1015+
for falsy_value in MessageTest.FALSY_VALUES:
1016+
with self.assertRaises(TypeError) as context:
1017+
m.repeated_int32.extend(falsy_value)
1018+
self.assertIn('iterable', str(context.exception))
1019+
self.assertSequenceEqual([], m.repeated_int32)
1020+
10151021
for empty_value in MessageTest.EMPTY_VALUES:
10161022
m.repeated_int32.extend(empty_value)
10171023
self.assertSequenceEqual([], m.repeated_int32)
@@ -1021,6 +1027,12 @@ def testExtendFloatWithNothing(self, message_module):
10211027
m = message_module.TestAllTypes()
10221028
self.assertSequenceEqual([], m.repeated_float)
10231029

1030+
for falsy_value in MessageTest.FALSY_VALUES:
1031+
with self.assertRaises(TypeError) as context:
1032+
m.repeated_float.extend(falsy_value)
1033+
self.assertIn('iterable', str(context.exception))
1034+
self.assertSequenceEqual([], m.repeated_float)
1035+
10241036
for empty_value in MessageTest.EMPTY_VALUES:
10251037
m.repeated_float.extend(empty_value)
10261038
self.assertSequenceEqual([], m.repeated_float)
@@ -1030,6 +1042,12 @@ def testExtendStringWithNothing(self, message_module):
10301042
m = message_module.TestAllTypes()
10311043
self.assertSequenceEqual([], m.repeated_string)
10321044

1045+
for falsy_value in MessageTest.FALSY_VALUES:
1046+
with self.assertRaises(TypeError) as context:
1047+
m.repeated_string.extend(falsy_value)
1048+
self.assertIn('iterable', str(context.exception))
1049+
self.assertSequenceEqual([], m.repeated_string)
1050+
10331051
for empty_value in MessageTest.EMPTY_VALUES:
10341052
m.repeated_string.extend(empty_value)
10351053
self.assertSequenceEqual([], m.repeated_string)

python/google/protobuf/pyext/repeated_scalar_container.cc

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -443,20 +443,6 @@ static int AssSubscript(PyObject* pself, PyObject* slice, PyObject* value) {
443443
PyObject* Extend(RepeatedScalarContainer* self, PyObject* value) {
444444
cmessage::AssureWritable(self->parent);
445445

446-
// TODO: Remove this in OSS
447-
if (value == Py_None) {
448-
PyErr_Warn(nullptr,
449-
"Value is not iterable. Please remove the wrong usage."
450-
" This will be changed to raise TypeError soon.");
451-
Py_RETURN_NONE;
452-
}
453-
if ((Py_TYPE(value)->tp_as_sequence == nullptr) && PyObject_Not(value)) {
454-
PyErr_Warn(nullptr,
455-
"Value is not iterable. Please remove the wrong usage."
456-
" This will be changed to raise TypeError soon.");
457-
Py_RETURN_NONE;
458-
}
459-
460446
ScopedPyObjectPtr iter(PyObject_GetIter(value));
461447
if (iter == nullptr) {
462448
PyErr_SetString(PyExc_TypeError, "Value must be iterable");

0 commit comments

Comments
 (0)