All tests passing!
diff --git a/python/descriptor.c b/python/descriptor.c
index 3877e55..a9718da 100644
--- a/python/descriptor.c
+++ b/python/descriptor.c
@@ -30,6 +30,7 @@
#include "python/convert.h"
#include "python/descriptor_containers.h"
#include "python/descriptor_pool.h"
+#include "python/message.h"
#include "python/protobuf.h"
#include "upb/def.h"
#include "upb/util/def_to_proto.h"
@@ -144,13 +145,9 @@
typedef void* PyUpb_ToProto_Func(const void* def, upb_arena* arena);
-static PyObject* PyUpb_DescriptorBase_CopyToProto(PyObject* _self,
- PyUpb_ToProto_Func* func,
- const upb_msglayout* layout,
- PyObject* py_proto) {
+static PyObject* PyUpb_DescriptorBase_GetSerializedProto(
+ PyObject* _self, PyUpb_ToProto_Func* func, const upb_msglayout* layout) {
PyUpb_DescriptorBase* self = (void*)_self;
- PyObject* ret = NULL;
- PyObject* str = NULL;
upb_arena* arena = upb_arena_new();
if (!arena) PYUPB_RETURN_OOM;
upb_msg* proto = func(self->def, arena);
@@ -158,20 +155,23 @@
size_t size;
char* pb = upb_encode(proto, layout, arena, &size);
if (!pb) goto oom;
- str = PyBytes_FromStringAndSize(pb, size);
- if (!str) goto oom;
- // Disabled until python/message.c is reviewed and checked in.
- // PyObject *ret = PyUpb_CMessage_MergeFromString(py_proto, str);
- PyErr_Format(PyExc_NotImplementedError, "Not yet implemented");
-
-done:
- Py_XDECREF(str);
+ PyObject* str = PyBytes_FromStringAndSize(pb, size);
upb_arena_free(arena);
- return ret;
+ return str;
oom:
PyErr_SetNone(PyExc_MemoryError);
- goto done;
+ return NULL;
+}
+
+static PyObject* PyUpb_DescriptorBase_CopyToProto(PyObject* _self,
+ PyUpb_ToProto_Func* func,
+ const upb_msglayout* layout,
+ PyObject* py_proto) {
+ PyObject* serialized =
+ PyUpb_DescriptorBase_GetSerializedProto(_self, func, layout);
+ if (!serialized) return NULL;
+ return PyUpb_CMessage_MergeFromString(py_proto, serialized);
}
static void PyUpb_DescriptorBase_Dealloc(PyUpb_DescriptorBase* base) {
@@ -1065,6 +1065,13 @@
return PyUnicode_FromString(upb_filedef_package(self->def));
}
+static PyObject* PyUpb_FileDescriptor_GetSerializedPb(PyObject* self,
+ void* closure) {
+ return PyUpb_DescriptorBase_GetSerializedProto(
+ self, (PyUpb_ToProto_Func*)&upb_FileDef_ToProto,
+ &google_protobuf_FileDescriptorProto_msginit);
+}
+
static PyObject* PyUpb_FileDescriptor_GetMessageTypesByName(PyObject* _self,
void* closure) {
static PyUpb_ByNameMap_Funcs funcs = {
@@ -1180,6 +1187,7 @@
{"pool", PyUpb_FileDescriptor_GetPool, NULL, "pool"},
{"name", (getter)PyUpb_FileDescriptor_GetName, NULL, "name"},
{"package", PyUpb_FileDescriptor_GetPackage, NULL, "package"},
+ {"serialized_pb", PyUpb_FileDescriptor_GetSerializedPb},
{"message_types_by_name", PyUpb_FileDescriptor_GetMessageTypesByName, NULL,
"Messages by name"},
{"enum_types_by_name", PyUpb_FileDescriptor_GetEnumTypesByName, NULL,
diff --git a/python/descriptor_pool.c b/python/descriptor_pool.c
index e48b82c..e816f4e 100644
--- a/python/descriptor_pool.c
+++ b/python/descriptor_pool.c
@@ -40,7 +40,6 @@
PyObject_HEAD
upb_symtab* symtab;
PyObject* db;
- PyObject* serialized_pb_dict;
} PyUpb_DescriptorPool;
PyObject* PyUpb_DescriptorPool_GetDefaultPool() {
@@ -53,7 +52,6 @@
PyUpb_DescriptorPool* pool = (void*)PyType_GenericAlloc(type, 0);
pool->symtab = upb_symtab_new();
pool->db = db;
- pool->serialized_pb_dict = PyDict_New();
Py_XINCREF(pool->db);
PyUpb_WeakMap_Add(obj_cache, pool->symtab, &pool->ob_base);
return &pool->ob_base;
@@ -88,18 +86,11 @@
static void PyUpb_DescriptorPool_Dealloc(PyUpb_DescriptorPool* self) {
PyUpb_DescriptorPool_Clear(self);
- Py_DECREF(self->serialized_pb_dict);
upb_symtab_free(self->symtab);
PyUpb_ObjCache_Delete(self->symtab);
PyUpb_Dealloc(self);
}
-PyObject* PyUpb_DescriptorPool_GetSerializedPb(PyObject* _self,
- const char* filename) {
- PyUpb_DescriptorPool* self = (PyUpb_DescriptorPool*)_self;
- return PyDict_GetItemString(self->serialized_pb_dict, filename);
-}
-
/*
* DescriptorPool.__new__()
*
@@ -166,9 +157,6 @@
goto done;
}
- PyDict_SetItemString(self->serialized_pb_dict, upb_filedef_name(filedef),
- serialized_pb);
-
result = PyUpb_FileDescriptor_Get(filedef);
done:
diff --git a/python/descriptor_pool.h b/python/descriptor_pool.h
index f43764e..caded66 100644
--- a/python/descriptor_pool.h
+++ b/python/descriptor_pool.h
@@ -32,8 +32,11 @@
#include "protobuf.h"
+// Returns a serialized protocol buffer for the given filename, which much have
+// been previously loaded into this DescriptorPool.
PyObject* PyUpb_DescriptorPool_GetSerializedPb(PyObject* _self,
const char* filename);
+
PyObject* PyUpb_DescriptorPool_Get(const upb_symtab* symtab);
upb_symtab* PyUpb_DescriptorPool_GetSymtab(PyObject* pool);
PyObject* PyUpb_DescriptorPool_GetDefaultPool(void);
diff --git a/python/minimal_test.py b/python/minimal_test.py
index 0c73a4b..26d6553 100644
--- a/python/minimal_test.py
+++ b/python/minimal_test.py
@@ -31,6 +31,10 @@
from google.protobuf.pyext import _message
from google.protobuf.internal import api_implementation
from google.protobuf import unittest_pb2
+from google.protobuf import descriptor_pool
+from google.protobuf.internal import factory_test1_pb2
+from google.protobuf.internal import factory_test2_pb2
+from google.protobuf import descriptor_pb2
class TestMessageExtension(unittest.TestCase):
diff --git a/python/pb_unit_tests/descriptor_database_test_wrapper.py b/python/pb_unit_tests/descriptor_database_test_wrapper.py
index 69fe7de..125533e 100644
--- a/python/pb_unit_tests/descriptor_database_test_wrapper.py
+++ b/python/pb_unit_tests/descriptor_database_test_wrapper.py
@@ -26,8 +26,5 @@
from google.protobuf.internal import descriptor_database_test
import unittest
-descriptor_database_test.DescriptorDatabaseTest.testAdd.__unittest_expecting_failure__ = True
-descriptor_database_test.DescriptorDatabaseTest.testConflictRegister.__unittest_expecting_failure__ = True
-
if __name__ == '__main__':
unittest.main(module=descriptor_database_test, verbosity=2)
diff --git a/python/pb_unit_tests/descriptor_pool_test_wrapper.py b/python/pb_unit_tests/descriptor_pool_test_wrapper.py
index 2eadd9c..1314f1b 100644
--- a/python/pb_unit_tests/descriptor_pool_test_wrapper.py
+++ b/python/pb_unit_tests/descriptor_pool_test_wrapper.py
@@ -25,48 +25,47 @@
from google.protobuf.internal import descriptor_pool_test
import unittest
+import copy
print(unittest)
descriptor_pool_test.AddDescriptorTest.testAddTypeError.__unittest_expecting_failure__ = True
-descriptor_pool_test.AddDescriptorTest.testEmptyDescriptorPool.__unittest_expecting_failure__ = True
descriptor_pool_test.AddDescriptorTest.testEnum.__unittest_expecting_failure__ = True
descriptor_pool_test.AddDescriptorTest.testFile.__unittest_expecting_failure__ = True
descriptor_pool_test.AddDescriptorTest.testFileDescriptorOptionsWithCustomDescriptorPool.__unittest_expecting_failure__ = True
descriptor_pool_test.AddDescriptorTest.testMessage.__unittest_expecting_failure__ = True
descriptor_pool_test.AddDescriptorTest.testService.__unittest_expecting_failure__ = True
+descriptor_pool_test.CreateDescriptorPoolTest.testFindFieldByName.__unittest_expecting_failure__ = True
+descriptor_pool_test.CreateDescriptorPoolTest.testFindMessageTypeByName.__unittest_expecting_failure__ = True
+descriptor_pool_test.CreateDescriptorPoolTest.testFindService.__unittest_expecting_failure__ = True
+descriptor_pool_test.CreateDescriptorPoolTest.testFindTypeErrors.__unittest_expecting_failure__ = True
+descriptor_pool_test.CreateDescriptorPoolTest.testUserDefinedDB.__unittest_expecting_failure__ = True
+descriptor_pool_test.SecondaryDescriptorFromDescriptorDB.testErrorCollector.__unittest_expecting_failure__ = True
-# We must skip these tests entirely (rather than running them with
-# __unittest_expecting_failure__) because they error out in setUp():
-#
-# AttributeError: 'google.protobuf.pyext._message.FileDescriptor' object has no attribute 'serialized_pb'
-#
-# TODO: change to __unittest_expecting_failure__ when serialized_pb is available.
-descriptor_pool_test.CreateDescriptorPoolTest.testAddSerializedFile.__unittest_skip__ = True
-descriptor_pool_test.CreateDescriptorPoolTest.testComplexNesting.__unittest_skip__ = True
-descriptor_pool_test.CreateDescriptorPoolTest.testConflictRegister.__unittest_skip__ = True
-descriptor_pool_test.CreateDescriptorPoolTest.testDefaultValueForCustomMessages.__unittest_skip__ = True
-descriptor_pool_test.CreateDescriptorPoolTest.testEnumDefaultValue.__unittest_skip__ = True
-descriptor_pool_test.CreateDescriptorPoolTest.testExtensionsAreNotFields.__unittest_skip__ = True
-descriptor_pool_test.CreateDescriptorPoolTest.testFindAllExtensions.__unittest_skip__ = True
-descriptor_pool_test.CreateDescriptorPoolTest.testFindEnumTypeByName.__unittest_skip__ = True
-descriptor_pool_test.CreateDescriptorPoolTest.testFindEnumTypeByNameFailure.__unittest_skip__ = True
-descriptor_pool_test.CreateDescriptorPoolTest.testFindExtensionByName.__unittest_skip__ = True
-descriptor_pool_test.CreateDescriptorPoolTest.testFindExtensionByNumber.__unittest_skip__ = True
-descriptor_pool_test.CreateDescriptorPoolTest.testFindFieldByName.__unittest_skip__ = True
-descriptor_pool_test.CreateDescriptorPoolTest.testFindFileByName.__unittest_skip__ = True
-descriptor_pool_test.CreateDescriptorPoolTest.testFindFileByNameFailure.__unittest_skip__ = True
-descriptor_pool_test.CreateDescriptorPoolTest.testFindFileContainingSymbol.__unittest_skip__ = True
-descriptor_pool_test.CreateDescriptorPoolTest.testFindFileContainingSymbolFailure.__unittest_skip__ = True
-descriptor_pool_test.CreateDescriptorPoolTest.testFindMessageTypeByName.__unittest_skip__ = True
-descriptor_pool_test.CreateDescriptorPoolTest.testFindMessageTypeByNameFailure.__unittest_skip__ = True
-descriptor_pool_test.DefaultDescriptorPoolTest.testFindMethods.__unittest_skip__ = True
-descriptor_pool_test.CreateDescriptorPoolTest.testFindOneofByName.__unittest_skip__ = True
-descriptor_pool_test.CreateDescriptorPoolTest.testFindService.__unittest_skip__ = True
-descriptor_pool_test.CreateDescriptorPoolTest.testFindTypeErrors.__unittest_skip__ = True
-descriptor_pool_test.CreateDescriptorPoolTest.testUserDefinedDB.__unittest_skip__ = True
-descriptor_pool_test.CreateDescriptorPoolTest.testAddFileDescriptor.__unittest_skip__ = True
-descriptor_pool_test.SecondaryDescriptorFromDescriptorDB.testErrorCollector.__unittest_skip__ = True
+# Some tests are defined in a base class and inherited by multiple sub-classes.
+# If only some of the subclasses fail, we need to duplicate the test method
+# before marking it, otherwise the mark will affect all subclasses.
+def wrap(cls, method):
+ existing = getattr(cls, method)
+ setattr(cls, method, lambda self: existing(self))
+ getattr(cls, method).__unittest_expecting_failure__ = True
+
+wrap(descriptor_pool_test.CreateDescriptorPoolTest, "testAddFileDescriptor")
+wrap(descriptor_pool_test.CreateDescriptorPoolTest, "testAddSerializedFile")
+wrap(descriptor_pool_test.CreateDescriptorPoolTest, "testComplexNesting")
+wrap(descriptor_pool_test.CreateDescriptorPoolTest, "testExtensionsAreNotFields")
+wrap(descriptor_pool_test.DefaultDescriptorPoolTest, "testAddFileDescriptor")
+wrap(descriptor_pool_test.DefaultDescriptorPoolTest, "testAddSerializedFile")
+wrap(descriptor_pool_test.DefaultDescriptorPoolTest, "testComplexNesting")
+wrap(descriptor_pool_test.DefaultDescriptorPoolTest, "testEnumDefaultValue")
+wrap(descriptor_pool_test.DefaultDescriptorPoolTest, "testExtensionsAreNotFields")
+wrap(descriptor_pool_test.SecondaryDescriptorFromDescriptorDB, "testFindAllExtensions")
+wrap(descriptor_pool_test.SecondaryDescriptorFromDescriptorDB, "testFindEnumTypeByName")
+wrap(descriptor_pool_test.SecondaryDescriptorFromDescriptorDB, "testFindExtensionByName")
+wrap(descriptor_pool_test.SecondaryDescriptorFromDescriptorDB, "testFindExtensionByNumber")
+wrap(descriptor_pool_test.SecondaryDescriptorFromDescriptorDB, "testFindFileByName")
+wrap(descriptor_pool_test.SecondaryDescriptorFromDescriptorDB, "testFindFileContainingSymbol")
+wrap(descriptor_pool_test.SecondaryDescriptorFromDescriptorDB, "testFindOneofByName")
if __name__ == '__main__':
unittest.main(module=descriptor_pool_test, verbosity=2)
diff --git a/python/pb_unit_tests/generator_test_wrapper.py b/python/pb_unit_tests/generator_test_wrapper.py
index 3cb7caf..ea78705 100644
--- a/python/pb_unit_tests/generator_test_wrapper.py
+++ b/python/pb_unit_tests/generator_test_wrapper.py
@@ -28,7 +28,6 @@
generator_test.GeneratorTest.testBadIdentifiers.__unittest_expecting_failure__ = True
generator_test.GeneratorTest.testExtensionScope.__unittest_expecting_failure__ = True
-generator_test.GeneratorTest.testFileDescriptor.__unittest_expecting_failure__ = True
generator_test.GeneratorTest.testMessageWithCustomOptions.__unittest_expecting_failure__ = True
generator_test.GeneratorTest.testOneof.__unittest_expecting_failure__ = True
generator_test.GeneratorTest.testOptions.__unittest_expecting_failure__ = True
diff --git a/upb/util/def_to_proto.c b/upb/util/def_to_proto.c
index fdde5cc..e813f7a 100644
--- a/upb/util/def_to_proto.c
+++ b/upb/util/def_to_proto.c
@@ -392,10 +392,14 @@
google_protobuf_FileDescriptorProto_set_name(
proto, strviewdup(ctx, upb_filedef_name(f)));
- size_t n = strlen(upb_filedef_package(f));
- if (n) {
- google_protobuf_FileDescriptorProto_set_package(
- proto, strviewdup(ctx, upb_filedef_package(f)));
+ const char* package = upb_filedef_package(f);
+ size_t n;
+ if (package) {
+ n = strlen(package);
+ if (n) {
+ google_protobuf_FileDescriptorProto_set_package(
+ proto, strviewdup(ctx, upb_filedef_package(f)));
+ }
}
if (upb_filedef_syntax(f) == UPB_SYNTAX_PROTO3) {