Implemented the behavior of ignoring duplicate added filenames.

pull/13171/head
Joshua Haberman 3 years ago
parent 89ff28cead
commit 8f0a2cd603
  1. 1
      python/BUILD
  2. 32
      python/descriptor_pool.c
  3. 3
      python/pb_unit_tests/descriptor_pool_test_wrapper.py
  4. 20
      python/pb_unit_tests/descriptor_test_wrapper.py
  5. 4
      python/protobuf.c
  6. 1
      python/protobuf.h

@ -69,6 +69,7 @@ cc_binary(
"//:reflection",
"//:textformat",
"//:upb",
"//:descriptor_upb_proto_reflection",
"//upb/util:compare",
"//upb/util:def_to_proto",
"//upb/util:required_fields",

@ -27,10 +27,13 @@
#include "python/descriptor_pool.h"
#include "python/convert.h"
#include "python/descriptor.h"
#include "python/message.h"
#include "python/protobuf.h"
#include "upb/def.h"
#include "upb/util/def_to_proto.h"
#include "google/protobuf/descriptor.upbdefs.h"
// -----------------------------------------------------------------------------
// DescriptorPool
@ -47,6 +50,14 @@ PyObject* PyUpb_DescriptorPool_GetDefaultPool() {
return s->default_pool;
}
const upb_msgdef* PyUpb_DescriptorPool_GetFileProtoDef(void) {
PyUpb_ModuleState* s = PyUpb_ModuleState_Get();
if (!s->c_descriptor_symtab) {
s->c_descriptor_symtab = upb_symtab_new();
}
return google_protobuf_FileDescriptorProto_getmsgdef(s->c_descriptor_symtab);
}
static PyObject* PyUpb_DescriptorPool_DoCreateWithCache(
PyTypeObject* type, PyObject* db, PyUpb_WeakMap* obj_cache) {
PyUpb_DescriptorPool* pool = (void*)PyType_GenericAlloc(type, 0);
@ -146,6 +157,27 @@ static PyObject* PyUpb_DescriptorPool_AddSerializedFile(
goto done;
}
upb_strview name = google_protobuf_FileDescriptorProto_name(proto);
const upb_filedef* file =
upb_symtab_lookupfile2(self->symtab, name.data, name.size);
if (file) {
// If the existing file is equal to the new file, then silently ignore the
// duplicate add.
google_protobuf_FileDescriptorProto* existing =
upb_FileDef_ToProto(file, arena);
if (!existing) {
PyErr_SetNone(PyExc_MemoryError);
goto done;
}
const upb_msgdef* m = PyUpb_DescriptorPool_GetFileProtoDef();
if (PyUpb_Message_IsEqual(proto, existing, m)) {
Py_INCREF(Py_None);
result = Py_None;
goto done;
}
}
upb_status status;
upb_status_clear(&status);

@ -49,13 +49,10 @@ def wrap(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.DefaultDescriptorPoolTest, "testAddFileDescriptor")
wrap(descriptor_pool_test.DefaultDescriptorPoolTest, "testAddSerializedFile")
wrap(descriptor_pool_test.DefaultDescriptorPoolTest, "testComplexNesting")
wrap(descriptor_pool_test.DefaultDescriptorPoolTest, "testEnumDefaultValue")
wrap(descriptor_pool_test.SecondaryDescriptorFromDescriptorDB, "testFindAllExtensions")
wrap(descriptor_pool_test.SecondaryDescriptorFromDescriptorDB, "testFindEnumTypeByName")
wrap(descriptor_pool_test.SecondaryDescriptorFromDescriptorDB, "testFindExtensionByName")

@ -30,29 +30,9 @@ descriptor_test.DescriptorCopyToProtoTest.testCopyToProto_TypeError.__unittest_e
descriptor_test.GeneratedDescriptorTest.testDescriptor.__unittest_expecting_failure__ = True
descriptor_test.MakeDescriptorTest.testCamelcaseName.__unittest_expecting_failure__ = True
descriptor_test.MakeDescriptorTest.testJsonName.__unittest_expecting_failure__ = True
descriptor_test.NewDescriptorTest.testAggregateOptions.__unittest_expecting_failure__ = True
descriptor_test.NewDescriptorTest.testComplexExtensionOptions.__unittest_expecting_failure__ = True
descriptor_test.NewDescriptorTest.testContainingServiceFixups.__unittest_expecting_failure__ = True
descriptor_test.NewDescriptorTest.testContainingTypeFixups.__unittest_expecting_failure__ = True
descriptor_test.NewDescriptorTest.testCustomOptionsCopyTo.__unittest_expecting_failure__ = True
descriptor_test.NewDescriptorTest.testDefault.__unittest_expecting_failure__ = True
descriptor_test.NewDescriptorTest.testDifferentCustomOptionTypes.__unittest_expecting_failure__ = True
descriptor_test.NewDescriptorTest.testEnumFixups.__unittest_expecting_failure__ = True
descriptor_test.NewDescriptorTest.testEnumValueName.__unittest_expecting_failure__ = True
descriptor_test.NewDescriptorTest.testFileDescriptor.__unittest_expecting_failure__ = True
descriptor_test.NewDescriptorTest.testFileDescriptorReferences.__unittest_expecting_failure__ = True
descriptor_test.NewDescriptorTest.testGetOptions.__unittest_expecting_failure__ = True
descriptor_test.NewDescriptorTest.testImmutableCppDescriptor.__unittest_expecting_failure__ = True
descriptor_test.NewDescriptorTest.testNestedOptions.__unittest_expecting_failure__ = True
descriptor_test.NewDescriptorTest.testSimpleCustomOptions.__unittest_expecting_failure__ = True
# We must skip these tests entirely (rather than running them with
# __unittest_expecting_failure__) because they error out in setUp():
#
# TypeError: Couldn't build proto file into descriptor pool: duplicate file name (some/filename/some.proto)
#
# TODO: change to __unittest_expecting_failure__ when we have some solution for duplicated filenames
descriptor_test.DescriptorTest.__unittest_skip__ = True
if __name__ == '__main__':
unittest.main(module=descriptor_test, verbosity=2)

@ -38,6 +38,9 @@
static void PyUpb_ModuleDealloc(void *module) {
PyUpb_ModuleState *s = PyModule_GetState(module);
PyUpb_WeakMap_Free(s->obj_cache);
if (s->c_descriptor_symtab) {
upb_symtab_free(s->c_descriptor_symtab);
}
}
PyObject* PyUpb_SetAllowOversizeProtos(PyObject* m, PyObject* arg) {
@ -322,6 +325,7 @@ PyMODINIT_FUNC PyInit__message(void) {
state->allow_oversize_protos = false;
state->wkt_bases = NULL;
state->obj_cache = PyUpb_WeakMap_New();
state->c_descriptor_symtab = NULL;
if (!PyUpb_InitDescriptorContainers(m) || !PyUpb_InitDescriptorPool(m) ||
!PyUpb_InitDescriptor(m) || !PyUpb_InitArena(m) ||

@ -63,6 +63,7 @@ typedef struct {
// From descriptor_pool.c
PyTypeObject *descriptor_pool_type;
upb_symtab* c_descriptor_symtab;
// From extension_dict.c
PyTypeObject* extension_dict_type;

Loading…
Cancel
Save