Implemented IsInitialized(), fixing several more tests.
diff --git a/python/message.c b/python/message.c
index 371348c..d7c44ba 100644
--- a/python/message.c
+++ b/python/message.c
@@ -923,6 +923,37 @@
: upb_msg_whichoneof(self->ptr.msg, oneof) != NULL);
}
+static PyObject* PyUpb_CMessage_FindInitializationErrors(PyObject* _self,
+ PyObject* arg);
+
+static PyObject* PyUpb_CMessage_IsInitialized(PyObject* _self, PyObject* args) {
+ PyObject* errors = NULL;
+ if (!PyArg_ParseTuple(args, "|O", &errors)) {
+ return NULL;
+ }
+ upb_msg* msg = PyUpb_CMessage_GetIfReified(_self);
+ if (!msg) Py_RETURN_NONE; // TODO
+ if (errors) {
+ PyObject* list = PyUpb_CMessage_FindInitializationErrors(_self, NULL);
+ if (!list) return NULL;
+ if (PyList_Size(list) == 0) {
+ return PyBool_FromLong(true);
+ }
+ PyObject* extend_name = PyUnicode_FromString("extend");
+ if (extend_name == NULL) {
+ Py_DECREF(list);
+ return NULL;
+ }
+ PyObject_CallMethodObjArgs(errors, extend_name, list, NULL);
+ return PyBool_FromLong(false);
+ } else {
+ const upb_msgdef* m = PyUpb_CMessage_GetMsgdef(_self);
+ const upb_symtab* symtab = upb_filedef_symtab(upb_msgdef_file(m));
+ bool initialized = !upb_util_HasUnsetRequired(msg, m, symtab, NULL);
+ return PyBool_FromLong(initialized);
+ }
+}
+
static PyObject* PyUpb_CMessage_ListFields(PyObject* _self, PyObject* arg) {
PyObject* list = PyList_New(0);
upb_msg* msg = PyUpb_CMessage_GetIfReified(_self);
@@ -1157,14 +1188,15 @@
upb_msg* msg = PyUpb_CMessage_GetIfReified(_self);
if (!msg) return PyList_New(0);
const upb_msgdef* msgdef = _PyUpb_CMessage_GetMsgdef(self);
- const upb_symtab* ext_pool = NULL; // TODO
+ const upb_symtab* ext_pool = upb_filedef_symtab(upb_msgdef_file(msgdef));
upb_FieldPathEntry* fields;
PyObject* ret = PyList_New(0);
if (upb_util_HasUnsetRequired(msg, msgdef, ext_pool, &fields)) {
char* buf = NULL;
size_t size = 0;
size_t i = 0;
- while (fields) {
+ assert(fields->field);
+ while (fields->field) {
upb_FieldPathEntry* field = fields;
size_t need = upb_FieldPath_ToText(&fields, buf, size);
if (need >= size) {
@@ -1175,7 +1207,7 @@
need = upb_FieldPath_ToText(&fields, buf, size);
assert(size > need);
}
- PyList_SetItem(ret, i, PyUnicode_FromString(buf));
+ PyList_Append(ret, PyUnicode_FromString(buf));
}
free(buf);
}
@@ -1348,18 +1380,16 @@
// "Copies a protocol message into the current message." },
{"DiscardUnknownFields", (PyCFunction)PyUpb_CMessage_DiscardUnknownFields,
METH_NOARGS, "Discards the unknown fields."},
- {"FindInitializationErrors",
- (PyCFunction)PyUpb_CMessage_FindInitializationErrors, METH_NOARGS,
- "Finds unset required fields."},
+ {"FindInitializationErrors", PyUpb_CMessage_FindInitializationErrors,
+ METH_NOARGS, "Finds unset required fields."},
{"FromString", PyUpb_CMessage_FromString, METH_O | METH_CLASS,
"Creates new method instance from given serialized data."},
{"HasExtension", PyUpb_CMessage_HasExtension, METH_O,
"Checks if a message field is set."},
{"HasField", PyUpb_CMessage_HasField, METH_O,
"Checks if a message field is set."},
- // TODO(https://github.com/protocolbuffers/upb/issues/459)
- //{ "IsInitialized", (PyCFunction)IsInitialized, METH_VARARGS,
- // "Checks if all required fields of a protocol message are set." },
+ {"IsInitialized", PyUpb_CMessage_IsInitialized, METH_VARARGS,
+ "Checks if all required fields of a protocol message are set."},
{"ListFields", PyUpb_CMessage_ListFields, METH_NOARGS,
"Lists all set fields of a message."},
{"MergeFrom", PyUpb_CMessage_MergeFrom, METH_O,