Fixed disconnecting before Clear().

pull/13171/head
Joshua Haberman 3 years ago
parent 075f4a2aec
commit 1be47593f0
  1. 8
      python/map.c
  2. 32
      python/message.c
  3. 2
      python/pb_unit_tests/reflection_test_wrapper.py
  4. 8
      python/repeated.c
  5. 2
      python/repeated.h

@ -105,6 +105,14 @@ PyObject* PyUpb_MapContainer_NewStub(PyObject* parent, const upb_fielddef* f,
void PyUpb_MapContainer_Reify(PyObject* _self, upb_map* map) {
PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
if (!map) {
const upb_fielddef* f = PyUpb_MapContainer_GetField(self);
upb_arena* arena = PyUpb_Arena_Get(self->arena);
const upb_msgdef* entry_m = upb_fielddef_msgsubdef(f);
const upb_fielddef* key_f = upb_msgdef_field(entry_m, 0);
const upb_fielddef* val_f = upb_msgdef_field(entry_m, 1);
map = upb_map_new(arena, upb_fielddef_type(key_f), upb_fielddef_type(val_f));
}
PyUpb_ObjCache_Add(map, &self->ob_base);
Py_DECREF(self->ptr.parent);
self->ptr.map = map; // Overwrites self->ptr.parent.

@ -550,6 +550,10 @@ static void PyUpb_CMessage_SyncSubobjs(PyUpb_CMessage* self);
static void PyUpb_CMessage_Reify(PyUpb_CMessage* self, const upb_fielddef* f,
upb_msg* msg) {
assert(f == PyUpb_CMessage_GetFieldDef(self));
if (!msg) {
const upb_msgdef* msgdef = PyUpb_CMessage_GetMsgdef((PyObject*)self);
msg = upb_msg_new(msgdef, PyUpb_Arena_Get(self->arena));
}
PyUpb_ObjCache_Add(msg, &self->ob_base);
Py_DECREF(&self->ptr.parent->ob_base);
self->ptr.msg = msg; // Overwrites self->ptr.parent
@ -585,7 +589,7 @@ static void PyUpb_CMessage_SyncSubobjs(PyUpb_CMessage* self) {
PyObject* obj;
// The last ref to this message could disappear during iteration.
// When we call PyUpb_*Container_SwitchToSet() below, the container will drop
// When we call PyUpb_*Container_Reify() below, the container will drop
// its ref on `self`. If that was the last ref on self, the object will be
// deleted, and `subobj_map` along with it. We need it to live until we are
// done iterating.
@ -1047,6 +1051,32 @@ static PyObject* PyUpb_CMessage_ByteSize(PyObject* self, PyObject* args) {
static PyObject* PyUpb_CMessage_Clear(PyUpb_CMessage* self, PyObject* args) {
PyUpb_CMessage_EnsureReified(self);
const upb_msgdef* msgdef = _PyUpb_CMessage_GetMsgdef(self);
PyUpb_WeakMap* subobj_map = self->unset_subobj_map;
if (subobj_map) {
upb_msg* msg = PyUpb_CMessage_GetMsg(self);
intptr_t iter = PYUPB_WEAKMAP_BEGIN;
const void* key;
PyObject* obj;
while (PyUpb_WeakMap_Next(subobj_map, &key, &obj, &iter)) {
const upb_fielddef* f = key;
PyUpb_WeakMap_DeleteIter(subobj_map, &iter);
if (upb_fielddef_ismap(f)) {
assert(upb_msg_get(msg, f).map_val == NULL);
PyUpb_MapContainer_Reify(obj, NULL);
} else if (upb_fielddef_isseq(f)) {
assert(upb_msg_get(msg, f).array_val == NULL);
PyUpb_RepeatedContainer_Reify(obj, NULL);
} else {
assert(!upb_msg_has(msg, f));
PyUpb_CMessage* sub = (void*)obj;
assert(self == sub->ptr.parent);
PyUpb_CMessage_Reify(sub, f, NULL);
}
}
}
upb_msg_clear(self->ptr.msg, msgdef);
Py_RETURN_NONE;
}

@ -46,8 +46,6 @@ reflection_test.ReflectionTest.testConstructorTypeError_proto2.__unittest_expect
reflection_test.ReflectionTest.testConstructorTypeError_proto3.__unittest_expecting_failure__ = True
reflection_test.ReflectionTest.testDeepCopy_proto2.__unittest_expecting_failure__ = True
reflection_test.ReflectionTest.testDeepCopy_proto3.__unittest_expecting_failure__ = True
reflection_test.ReflectionTest.testDisconnectingBeforeClear_proto2.__unittest_expecting_failure__ = True
reflection_test.ReflectionTest.testDisconnectingBeforeClear_proto3.__unittest_expecting_failure__ = True
reflection_test.ReflectionTest.testEnum_KeysAndValues_proto2.__unittest_expecting_failure__ = True
reflection_test.ReflectionTest.testEnum_KeysAndValues_proto3.__unittest_expecting_failure__ = True
reflection_test.ReflectionTest.testEnum_Name_proto2.__unittest_expecting_failure__ = True

@ -106,14 +106,20 @@ static upb_array* PyUpb_RepeatedContainer_GetIfReified(
return PyUpb_RepeatedContainer_IsStub(self) ? NULL : self->ptr.arr;
}
void PyUpb_RepeatedContainer_Reify(PyObject* _self, upb_array* arr) {
upb_array* PyUpb_RepeatedContainer_Reify(PyObject* _self, upb_array* arr) {
PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)_self;
assert(PyUpb_RepeatedContainer_IsStub(self));
if (!arr) {
const upb_fielddef* f = PyUpb_RepeatedContainer_GetField(self);
upb_arena* arena = PyUpb_Arena_Get(self->arena);
arr = upb_array_new(arena, upb_fielddef_type(f));
}
PyUpb_ObjCache_Add(arr, &self->ob_base);
Py_DECREF(self->ptr.parent);
self->ptr.arr = arr; // Overwrites self->ptr.parent.
self->field &= ~(uintptr_t)1;
assert(!PyUpb_RepeatedContainer_IsStub(self));
return arr;
}
upb_array* PyUpb_RepeatedContainer_EnsureReified(PyObject* _self) {

@ -48,7 +48,7 @@ PyObject* PyUpb_RepeatedContainer_GetOrCreateWrapper(upb_array* arr,
PyObject* arena);
// Reifies a repeated field stub to point to the concrete data in `arr`.
void PyUpb_RepeatedContainer_Reify(PyObject* self, upb_array* arr);
upb_array* PyUpb_RepeatedContainer_Reify(PyObject* self, upb_array* arr);
// Reifies this repeated object if it is not already reified.
upb_array* PyUpb_RepeatedContainer_EnsureReified(PyObject* self);

Loading…
Cancel
Save