OLD | NEW |
1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
4 // | 4 // |
5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
7 // met: | 7 // met: |
8 // | 8 // |
9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
(...skipping 21 matching lines...) Expand all Loading... |
32 | 32 |
33 #include <google/protobuf/pyext/map_container.h> | 33 #include <google/protobuf/pyext/map_container.h> |
34 | 34 |
35 #include <memory> | 35 #include <memory> |
36 #ifndef _SHARED_PTR_H | 36 #ifndef _SHARED_PTR_H |
37 #include <google/protobuf/stubs/shared_ptr.h> | 37 #include <google/protobuf/stubs/shared_ptr.h> |
38 #endif | 38 #endif |
39 | 39 |
40 #include <google/protobuf/stubs/logging.h> | 40 #include <google/protobuf/stubs/logging.h> |
41 #include <google/protobuf/stubs/common.h> | 41 #include <google/protobuf/stubs/common.h> |
42 #include <google/protobuf/stubs/scoped_ptr.h> | |
43 #include <google/protobuf/map_field.h> | 42 #include <google/protobuf/map_field.h> |
44 #include <google/protobuf/map.h> | 43 #include <google/protobuf/map.h> |
45 #include <google/protobuf/message.h> | 44 #include <google/protobuf/message.h> |
| 45 #include <google/protobuf/pyext/message_factory.h> |
46 #include <google/protobuf/pyext/message.h> | 46 #include <google/protobuf/pyext/message.h> |
| 47 #include <google/protobuf/pyext/repeated_composite_container.h> |
47 #include <google/protobuf/pyext/scoped_pyobject_ptr.h> | 48 #include <google/protobuf/pyext/scoped_pyobject_ptr.h> |
48 | 49 |
49 #if PY_MAJOR_VERSION >= 3 | 50 #if PY_MAJOR_VERSION >= 3 |
50 #define PyInt_FromLong PyLong_FromLong | 51 #define PyInt_FromLong PyLong_FromLong |
51 #define PyInt_FromSize_t PyLong_FromSize_t | 52 #define PyInt_FromSize_t PyLong_FromSize_t |
52 #endif | 53 #endif |
53 | 54 |
54 namespace google { | 55 namespace google { |
55 namespace protobuf { | 56 namespace protobuf { |
56 namespace python { | 57 namespace python { |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 PyObject* Clear(PyObject* _self) { | 323 PyObject* Clear(PyObject* _self) { |
323 MapContainer* self = GetMap(_self); | 324 MapContainer* self = GetMap(_self); |
324 Message* message = self->GetMutableMessage(); | 325 Message* message = self->GetMutableMessage(); |
325 const Reflection* reflection = message->GetReflection(); | 326 const Reflection* reflection = message->GetReflection(); |
326 | 327 |
327 reflection->ClearField(message, self->parent_field_descriptor); | 328 reflection->ClearField(message, self->parent_field_descriptor); |
328 | 329 |
329 Py_RETURN_NONE; | 330 Py_RETURN_NONE; |
330 } | 331 } |
331 | 332 |
| 333 PyObject* GetEntryClass(PyObject* _self) { |
| 334 MapContainer* self = GetMap(_self); |
| 335 CMessageClass* message_class = message_factory::GetMessageClass( |
| 336 cmessage::GetFactoryForMessage(self->parent), |
| 337 self->parent_field_descriptor->message_type()); |
| 338 Py_XINCREF(message_class); |
| 339 return reinterpret_cast<PyObject*>(message_class); |
| 340 } |
| 341 |
332 PyObject* MapReflectionFriend::Contains(PyObject* _self, PyObject* key) { | 342 PyObject* MapReflectionFriend::Contains(PyObject* _self, PyObject* key) { |
333 MapContainer* self = GetMap(_self); | 343 MapContainer* self = GetMap(_self); |
334 | 344 |
335 const Message* message = self->message; | 345 const Message* message = self->message; |
336 const Reflection* reflection = message->GetReflection(); | 346 const Reflection* reflection = message->GetReflection(); |
337 MapKey map_key; | 347 MapKey map_key; |
338 | 348 |
339 if (!PythonToMapKey(key, self->key_field_descriptor, &map_key)) { | 349 if (!PythonToMapKey(key, self->key_field_descriptor, &map_key)) { |
340 return NULL; | 350 return NULL; |
341 } | 351 } |
342 | 352 |
343 if (reflection->ContainsMapKey(*message, self->parent_field_descriptor, | 353 if (reflection->ContainsMapKey(*message, self->parent_field_descriptor, |
344 map_key)) { | 354 map_key)) { |
345 Py_RETURN_TRUE; | 355 Py_RETURN_TRUE; |
346 } else { | 356 } else { |
347 Py_RETURN_FALSE; | 357 Py_RETURN_FALSE; |
348 } | 358 } |
349 } | 359 } |
350 | 360 |
351 // Initializes the underlying Message object of "to" so it becomes a new parent | 361 // Initializes the underlying Message object of "to" so it becomes a new parent |
352 // repeated scalar, and copies all the values from "from" to it. A child scalar | 362 // map container, and copies all the values from "from" to it. A child map |
353 // container can be released by passing it as both from and to (e.g. making it | 363 // container can be released by passing it as both from and to (e.g. making it |
354 // the recipient of the new parent message and copying the values from itself). | 364 // the recipient of the new parent message and copying the values from itself). |
| 365 // In fact, this is the only supported use at the moment. |
355 static int InitializeAndCopyToParentContainer(MapContainer* from, | 366 static int InitializeAndCopyToParentContainer(MapContainer* from, |
356 MapContainer* to) { | 367 MapContainer* to) { |
357 // For now we require from == to, re-evaluate if we want to support deep copy | 368 // For now we require from == to, re-evaluate if we want to support deep copy |
358 // as in repeated_scalar_container.cc. | 369 // as in repeated_scalar_container.cc. |
359 GOOGLE_DCHECK(from == to); | 370 GOOGLE_DCHECK(from == to); |
360 Message* new_message = from->message->New(); | 371 Message* new_message = from->message->New(); |
361 | 372 |
362 if (MapReflectionFriend::Length(reinterpret_cast<PyObject*>(from)) > 0) { | 373 if (MapReflectionFriend::Length(reinterpret_cast<PyObject*>(from)) > 0) { |
363 // A somewhat roundabout way of copying just one field from old_message to | 374 // A somewhat roundabout way of copying just one field from old_message to |
364 // new_message. This is the best we can do with what Reflection gives us. | 375 // new_message. This is the best we can do with what Reflection gives us. |
365 Message* mutable_old = from->GetMutableMessage(); | 376 Message* mutable_old = from->GetMutableMessage(); |
366 vector<const FieldDescriptor*> fields; | 377 std::vector<const FieldDescriptor*> fields; |
367 fields.push_back(from->parent_field_descriptor); | 378 fields.push_back(from->parent_field_descriptor); |
368 | 379 |
369 // Move the map field into the new message. | 380 // Move the map field into the new message. |
370 mutable_old->GetReflection()->SwapFields(mutable_old, new_message, fields); | 381 mutable_old->GetReflection()->SwapFields(mutable_old, new_message, fields); |
371 | 382 |
372 // If/when we support from != to, this will be required also to copy the | 383 // If/when we support from != to, this will be required also to copy the |
373 // map field back into the existing message: | 384 // map field back into the existing message: |
374 // mutable_old->MergeFrom(*new_message); | 385 // mutable_old->MergeFrom(*new_message); |
375 } | 386 } |
376 | 387 |
(...skipping 16 matching lines...) Expand all Loading... |
393 | 404 |
394 | 405 |
395 // ScalarMap /////////////////////////////////////////////////////////////////// | 406 // ScalarMap /////////////////////////////////////////////////////////////////// |
396 | 407 |
397 PyObject *NewScalarMapContainer( | 408 PyObject *NewScalarMapContainer( |
398 CMessage* parent, const google::protobuf::FieldDescriptor* parent_field_desc
riptor) { | 409 CMessage* parent, const google::protobuf::FieldDescriptor* parent_field_desc
riptor) { |
399 if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) { | 410 if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) { |
400 return NULL; | 411 return NULL; |
401 } | 412 } |
402 | 413 |
403 #if PY_MAJOR_VERSION >= 3 | 414 ScopedPyObjectPtr obj(PyType_GenericAlloc(ScalarMapContainer_Type, 0)); |
404 ScopedPyObjectPtr obj(PyType_GenericAlloc( | |
405 reinterpret_cast<PyTypeObject *>(ScalarMapContainer_Type), 0)); | |
406 #else | |
407 ScopedPyObjectPtr obj(PyType_GenericAlloc(&ScalarMapContainer_Type, 0)); | |
408 #endif | |
409 if (obj.get() == NULL) { | 415 if (obj.get() == NULL) { |
410 return PyErr_Format(PyExc_RuntimeError, | 416 return PyErr_Format(PyExc_RuntimeError, |
411 "Could not allocate new container."); | 417 "Could not allocate new container."); |
412 } | 418 } |
413 | 419 |
414 MapContainer* self = GetMap(obj.get()); | 420 MapContainer* self = GetMap(obj.get()); |
415 | 421 |
416 self->message = parent->message; | 422 self->message = parent->message; |
417 self->parent = parent; | 423 self->parent = parent; |
418 self->parent_field_descriptor = parent_field_descriptor; | 424 self->parent_field_descriptor = parent_field_descriptor; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
520 Py_TYPE(_self)->tp_free(_self); | 526 Py_TYPE(_self)->tp_free(_self); |
521 } | 527 } |
522 | 528 |
523 static PyMethodDef ScalarMapMethods[] = { | 529 static PyMethodDef ScalarMapMethods[] = { |
524 { "__contains__", MapReflectionFriend::Contains, METH_O, | 530 { "__contains__", MapReflectionFriend::Contains, METH_O, |
525 "Tests whether a key is a member of the map." }, | 531 "Tests whether a key is a member of the map." }, |
526 { "clear", (PyCFunction)Clear, METH_NOARGS, | 532 { "clear", (PyCFunction)Clear, METH_NOARGS, |
527 "Removes all elements from the map." }, | 533 "Removes all elements from the map." }, |
528 { "get", ScalarMapGet, METH_VARARGS, | 534 { "get", ScalarMapGet, METH_VARARGS, |
529 "Gets the value for the given key if present, or otherwise a default" }, | 535 "Gets the value for the given key if present, or otherwise a default" }, |
| 536 { "GetEntryClass", (PyCFunction)GetEntryClass, METH_NOARGS, |
| 537 "Return the class used to build Entries of (key, value) pairs." }, |
530 /* | 538 /* |
531 { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS, | 539 { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS, |
532 "Makes a deep copy of the class." }, | 540 "Makes a deep copy of the class." }, |
533 { "__reduce__", (PyCFunction)Reduce, METH_NOARGS, | 541 { "__reduce__", (PyCFunction)Reduce, METH_NOARGS, |
534 "Outputs picklable representation of the repeated field." }, | 542 "Outputs picklable representation of the repeated field." }, |
535 */ | 543 */ |
536 {NULL, NULL}, | 544 {NULL, NULL}, |
537 }; | 545 }; |
538 | 546 |
| 547 PyTypeObject *ScalarMapContainer_Type; |
539 #if PY_MAJOR_VERSION >= 3 | 548 #if PY_MAJOR_VERSION >= 3 |
540 static PyType_Slot ScalarMapContainer_Type_slots[] = { | 549 static PyType_Slot ScalarMapContainer_Type_slots[] = { |
541 {Py_tp_dealloc, (void *)ScalarMapDealloc}, | 550 {Py_tp_dealloc, (void *)ScalarMapDealloc}, |
542 {Py_mp_length, (void *)MapReflectionFriend::Length}, | 551 {Py_mp_length, (void *)MapReflectionFriend::Length}, |
543 {Py_mp_subscript, (void *)MapReflectionFriend::ScalarMapGetItem}, | 552 {Py_mp_subscript, (void *)MapReflectionFriend::ScalarMapGetItem}, |
544 {Py_mp_ass_subscript, (void *)MapReflectionFriend::ScalarMapSetItem}, | 553 {Py_mp_ass_subscript, (void *)MapReflectionFriend::ScalarMapSetItem}, |
545 {Py_tp_methods, (void *)ScalarMapMethods}, | 554 {Py_tp_methods, (void *)ScalarMapMethods}, |
546 {Py_tp_iter, (void *)MapReflectionFriend::GetIterator}, | 555 {Py_tp_iter, (void *)MapReflectionFriend::GetIterator}, |
547 {0, 0}, | 556 {0, 0}, |
548 }; | 557 }; |
549 | 558 |
550 PyType_Spec ScalarMapContainer_Type_spec = { | 559 PyType_Spec ScalarMapContainer_Type_spec = { |
551 FULL_MODULE_NAME ".ScalarMapContainer", | 560 FULL_MODULE_NAME ".ScalarMapContainer", |
552 sizeof(MapContainer), | 561 sizeof(MapContainer), |
553 0, | 562 0, |
554 Py_TPFLAGS_DEFAULT, | 563 Py_TPFLAGS_DEFAULT, |
555 ScalarMapContainer_Type_slots | 564 ScalarMapContainer_Type_slots |
556 }; | 565 }; |
557 PyObject *ScalarMapContainer_Type; | |
558 #else | 566 #else |
559 static PyMappingMethods ScalarMapMappingMethods = { | 567 static PyMappingMethods ScalarMapMappingMethods = { |
560 MapReflectionFriend::Length, // mp_length | 568 MapReflectionFriend::Length, // mp_length |
561 MapReflectionFriend::ScalarMapGetItem, // mp_subscript | 569 MapReflectionFriend::ScalarMapGetItem, // mp_subscript |
562 MapReflectionFriend::ScalarMapSetItem, // mp_ass_subscript | 570 MapReflectionFriend::ScalarMapSetItem, // mp_ass_subscript |
563 }; | 571 }; |
564 | 572 |
565 PyTypeObject ScalarMapContainer_Type = { | 573 PyTypeObject _ScalarMapContainer_Type = { |
566 PyVarObject_HEAD_INIT(&PyType_Type, 0) | 574 PyVarObject_HEAD_INIT(&PyType_Type, 0) |
567 FULL_MODULE_NAME ".ScalarMapContainer", // tp_name | 575 FULL_MODULE_NAME ".ScalarMapContainer", // tp_name |
568 sizeof(MapContainer), // tp_basicsize | 576 sizeof(MapContainer), // tp_basicsize |
569 0, // tp_itemsize | 577 0, // tp_itemsize |
570 ScalarMapDealloc, // tp_dealloc | 578 ScalarMapDealloc, // tp_dealloc |
571 0, // tp_print | 579 0, // tp_print |
572 0, // tp_getattr | 580 0, // tp_getattr |
573 0, // tp_setattr | 581 0, // tp_setattr |
574 0, // tp_compare | 582 0, // tp_compare |
575 0, // tp_repr | 583 0, // tp_repr |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 return ret; | 644 return ret; |
637 } | 645 } |
638 | 646 |
639 PyObject* NewMessageMapContainer( | 647 PyObject* NewMessageMapContainer( |
640 CMessage* parent, const google::protobuf::FieldDescriptor* parent_field_desc
riptor, | 648 CMessage* parent, const google::protobuf::FieldDescriptor* parent_field_desc
riptor, |
641 CMessageClass* message_class) { | 649 CMessageClass* message_class) { |
642 if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) { | 650 if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) { |
643 return NULL; | 651 return NULL; |
644 } | 652 } |
645 | 653 |
646 #if PY_MAJOR_VERSION >= 3 | 654 PyObject* obj = PyType_GenericAlloc(MessageMapContainer_Type, 0); |
647 PyObject* obj = PyType_GenericAlloc( | |
648 reinterpret_cast<PyTypeObject *>(MessageMapContainer_Type), 0); | |
649 #else | |
650 PyObject* obj = PyType_GenericAlloc(&MessageMapContainer_Type, 0); | |
651 #endif | |
652 if (obj == NULL) { | 655 if (obj == NULL) { |
653 return PyErr_Format(PyExc_RuntimeError, | 656 return PyErr_Format(PyExc_RuntimeError, |
654 "Could not allocate new container."); | 657 "Could not allocate new container."); |
655 } | 658 } |
656 | 659 |
657 MessageMapContainer* self = GetMessageMap(obj); | 660 MessageMapContainer* self = GetMessageMap(obj); |
658 | 661 |
659 self->message = parent->message; | 662 self->message = parent->message; |
660 self->parent = parent; | 663 self->parent = parent; |
661 self->parent_field_descriptor = parent_field_descriptor; | 664 self->parent_field_descriptor = parent_field_descriptor; |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
773 | 776 |
774 static PyMethodDef MessageMapMethods[] = { | 777 static PyMethodDef MessageMapMethods[] = { |
775 { "__contains__", (PyCFunction)MapReflectionFriend::Contains, METH_O, | 778 { "__contains__", (PyCFunction)MapReflectionFriend::Contains, METH_O, |
776 "Tests whether the map contains this element."}, | 779 "Tests whether the map contains this element."}, |
777 { "clear", (PyCFunction)Clear, METH_NOARGS, | 780 { "clear", (PyCFunction)Clear, METH_NOARGS, |
778 "Removes all elements from the map."}, | 781 "Removes all elements from the map."}, |
779 { "get", MessageMapGet, METH_VARARGS, | 782 { "get", MessageMapGet, METH_VARARGS, |
780 "Gets the value for the given key if present, or otherwise a default" }, | 783 "Gets the value for the given key if present, or otherwise a default" }, |
781 { "get_or_create", MapReflectionFriend::MessageMapGetItem, METH_O, | 784 { "get_or_create", MapReflectionFriend::MessageMapGetItem, METH_O, |
782 "Alias for getitem, useful to make explicit that the map is mutated." }, | 785 "Alias for getitem, useful to make explicit that the map is mutated." }, |
| 786 { "GetEntryClass", (PyCFunction)GetEntryClass, METH_NOARGS, |
| 787 "Return the class used to build Entries of (key, value) pairs." }, |
783 /* | 788 /* |
784 { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS, | 789 { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS, |
785 "Makes a deep copy of the class." }, | 790 "Makes a deep copy of the class." }, |
786 { "__reduce__", (PyCFunction)Reduce, METH_NOARGS, | 791 { "__reduce__", (PyCFunction)Reduce, METH_NOARGS, |
787 "Outputs picklable representation of the repeated field." }, | 792 "Outputs picklable representation of the repeated field." }, |
788 */ | 793 */ |
789 {NULL, NULL}, | 794 {NULL, NULL}, |
790 }; | 795 }; |
791 | 796 |
| 797 PyTypeObject *MessageMapContainer_Type; |
792 #if PY_MAJOR_VERSION >= 3 | 798 #if PY_MAJOR_VERSION >= 3 |
793 static PyType_Slot MessageMapContainer_Type_slots[] = { | 799 static PyType_Slot MessageMapContainer_Type_slots[] = { |
794 {Py_tp_dealloc, (void *)MessageMapDealloc}, | 800 {Py_tp_dealloc, (void *)MessageMapDealloc}, |
795 {Py_mp_length, (void *)MapReflectionFriend::Length}, | 801 {Py_mp_length, (void *)MapReflectionFriend::Length}, |
796 {Py_mp_subscript, (void *)MapReflectionFriend::MessageMapGetItem}, | 802 {Py_mp_subscript, (void *)MapReflectionFriend::MessageMapGetItem}, |
797 {Py_mp_ass_subscript, (void *)MapReflectionFriend::MessageMapSetItem}, | 803 {Py_mp_ass_subscript, (void *)MapReflectionFriend::MessageMapSetItem}, |
798 {Py_tp_methods, (void *)MessageMapMethods}, | 804 {Py_tp_methods, (void *)MessageMapMethods}, |
799 {Py_tp_iter, (void *)MapReflectionFriend::GetIterator}, | 805 {Py_tp_iter, (void *)MapReflectionFriend::GetIterator}, |
800 {0, 0} | 806 {0, 0} |
801 }; | 807 }; |
802 | 808 |
803 PyType_Spec MessageMapContainer_Type_spec = { | 809 PyType_Spec MessageMapContainer_Type_spec = { |
804 FULL_MODULE_NAME ".MessageMapContainer", | 810 FULL_MODULE_NAME ".MessageMapContainer", |
805 sizeof(MessageMapContainer), | 811 sizeof(MessageMapContainer), |
806 0, | 812 0, |
807 Py_TPFLAGS_DEFAULT, | 813 Py_TPFLAGS_DEFAULT, |
808 MessageMapContainer_Type_slots | 814 MessageMapContainer_Type_slots |
809 }; | 815 }; |
810 | |
811 PyObject *MessageMapContainer_Type; | |
812 #else | 816 #else |
813 static PyMappingMethods MessageMapMappingMethods = { | 817 static PyMappingMethods MessageMapMappingMethods = { |
814 MapReflectionFriend::Length, // mp_length | 818 MapReflectionFriend::Length, // mp_length |
815 MapReflectionFriend::MessageMapGetItem, // mp_subscript | 819 MapReflectionFriend::MessageMapGetItem, // mp_subscript |
816 MapReflectionFriend::MessageMapSetItem, // mp_ass_subscript | 820 MapReflectionFriend::MessageMapSetItem, // mp_ass_subscript |
817 }; | 821 }; |
818 | 822 |
819 PyTypeObject MessageMapContainer_Type = { | 823 PyTypeObject _MessageMapContainer_Type = { |
820 PyVarObject_HEAD_INIT(&PyType_Type, 0) | 824 PyVarObject_HEAD_INIT(&PyType_Type, 0) |
821 FULL_MODULE_NAME ".MessageMapContainer", // tp_name | 825 FULL_MODULE_NAME ".MessageMapContainer", // tp_name |
822 sizeof(MessageMapContainer), // tp_basicsize | 826 sizeof(MessageMapContainer), // tp_basicsize |
823 0, // tp_itemsize | 827 0, // tp_itemsize |
824 MessageMapDealloc, // tp_dealloc | 828 MessageMapDealloc, // tp_dealloc |
825 0, // tp_print | 829 0, // tp_print |
826 0, // tp_getattr | 830 0, // tp_getattr |
827 0, // tp_setattr | 831 0, // tp_setattr |
828 0, // tp_compare | 832 0, // tp_compare |
829 0, // tp_repr | 833 0, // tp_repr |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
958 0, // tp_members | 962 0, // tp_members |
959 0, // tp_getset | 963 0, // tp_getset |
960 0, // tp_base | 964 0, // tp_base |
961 0, // tp_dict | 965 0, // tp_dict |
962 0, // tp_descr_get | 966 0, // tp_descr_get |
963 0, // tp_descr_set | 967 0, // tp_descr_set |
964 0, // tp_dictoffset | 968 0, // tp_dictoffset |
965 0, // tp_init | 969 0, // tp_init |
966 }; | 970 }; |
967 | 971 |
| 972 bool InitMapContainers() { |
| 973 // ScalarMapContainer_Type derives from our MutableMapping type. |
| 974 ScopedPyObjectPtr containers(PyImport_ImportModule( |
| 975 "google.protobuf.internal.containers")); |
| 976 if (containers == NULL) { |
| 977 return false; |
| 978 } |
| 979 |
| 980 ScopedPyObjectPtr mutable_mapping( |
| 981 PyObject_GetAttrString(containers.get(), "MutableMapping")); |
| 982 if (mutable_mapping == NULL) { |
| 983 return false; |
| 984 } |
| 985 |
| 986 if (!PyObject_TypeCheck(mutable_mapping.get(), &PyType_Type)) { |
| 987 return false; |
| 988 } |
| 989 |
| 990 Py_INCREF(mutable_mapping.get()); |
| 991 #if PY_MAJOR_VERSION >= 3 |
| 992 PyObject* bases = PyTuple_New(1); |
| 993 PyTuple_SET_ITEM(bases, 0, mutable_mapping.get()); |
| 994 |
| 995 ScalarMapContainer_Type = reinterpret_cast<PyTypeObject*>( |
| 996 PyType_FromSpecWithBases(&ScalarMapContainer_Type_spec, bases)); |
| 997 #else |
| 998 _ScalarMapContainer_Type.tp_base = |
| 999 reinterpret_cast<PyTypeObject*>(mutable_mapping.get()); |
| 1000 |
| 1001 if (PyType_Ready(&_ScalarMapContainer_Type) < 0) { |
| 1002 return false; |
| 1003 } |
| 1004 |
| 1005 ScalarMapContainer_Type = &_ScalarMapContainer_Type; |
| 1006 #endif |
| 1007 |
| 1008 if (PyType_Ready(&MapIterator_Type) < 0) { |
| 1009 return false; |
| 1010 } |
| 1011 |
| 1012 #if PY_MAJOR_VERSION >= 3 |
| 1013 MessageMapContainer_Type = reinterpret_cast<PyTypeObject*>( |
| 1014 PyType_FromSpecWithBases(&MessageMapContainer_Type_spec, bases)); |
| 1015 #else |
| 1016 Py_INCREF(mutable_mapping.get()); |
| 1017 _MessageMapContainer_Type.tp_base = |
| 1018 reinterpret_cast<PyTypeObject*>(mutable_mapping.get()); |
| 1019 |
| 1020 if (PyType_Ready(&_MessageMapContainer_Type) < 0) { |
| 1021 return false; |
| 1022 } |
| 1023 |
| 1024 MessageMapContainer_Type = &_MessageMapContainer_Type; |
| 1025 #endif |
| 1026 return true; |
| 1027 } |
| 1028 |
968 } // namespace python | 1029 } // namespace python |
969 } // namespace protobuf | 1030 } // namespace protobuf |
970 } // namespace google | 1031 } // namespace google |
OLD | NEW |