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> |
42 #include <google/protobuf/map_field.h> | 43 #include <google/protobuf/map_field.h> |
43 #include <google/protobuf/map.h> | 44 #include <google/protobuf/map.h> |
44 #include <google/protobuf/message.h> | 45 #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> | |
48 #include <google/protobuf/pyext/scoped_pyobject_ptr.h> | 47 #include <google/protobuf/pyext/scoped_pyobject_ptr.h> |
49 | 48 |
50 #if PY_MAJOR_VERSION >= 3 | 49 #if PY_MAJOR_VERSION >= 3 |
51 #define PyInt_FromLong PyLong_FromLong | 50 #define PyInt_FromLong PyLong_FromLong |
52 #define PyInt_FromSize_t PyLong_FromSize_t | 51 #define PyInt_FromSize_t PyLong_FromSize_t |
53 #endif | 52 #endif |
54 | 53 |
55 namespace google { | 54 namespace google { |
56 namespace protobuf { | 55 namespace protobuf { |
57 namespace python { | 56 namespace python { |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 PyObject* Clear(PyObject* _self) { | 322 PyObject* Clear(PyObject* _self) { |
324 MapContainer* self = GetMap(_self); | 323 MapContainer* self = GetMap(_self); |
325 Message* message = self->GetMutableMessage(); | 324 Message* message = self->GetMutableMessage(); |
326 const Reflection* reflection = message->GetReflection(); | 325 const Reflection* reflection = message->GetReflection(); |
327 | 326 |
328 reflection->ClearField(message, self->parent_field_descriptor); | 327 reflection->ClearField(message, self->parent_field_descriptor); |
329 | 328 |
330 Py_RETURN_NONE; | 329 Py_RETURN_NONE; |
331 } | 330 } |
332 | 331 |
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 | |
342 PyObject* MapReflectionFriend::Contains(PyObject* _self, PyObject* key) { | 332 PyObject* MapReflectionFriend::Contains(PyObject* _self, PyObject* key) { |
343 MapContainer* self = GetMap(_self); | 333 MapContainer* self = GetMap(_self); |
344 | 334 |
345 const Message* message = self->message; | 335 const Message* message = self->message; |
346 const Reflection* reflection = message->GetReflection(); | 336 const Reflection* reflection = message->GetReflection(); |
347 MapKey map_key; | 337 MapKey map_key; |
348 | 338 |
349 if (!PythonToMapKey(key, self->key_field_descriptor, &map_key)) { | 339 if (!PythonToMapKey(key, self->key_field_descriptor, &map_key)) { |
350 return NULL; | 340 return NULL; |
351 } | 341 } |
352 | 342 |
353 if (reflection->ContainsMapKey(*message, self->parent_field_descriptor, | 343 if (reflection->ContainsMapKey(*message, self->parent_field_descriptor, |
354 map_key)) { | 344 map_key)) { |
355 Py_RETURN_TRUE; | 345 Py_RETURN_TRUE; |
356 } else { | 346 } else { |
357 Py_RETURN_FALSE; | 347 Py_RETURN_FALSE; |
358 } | 348 } |
359 } | 349 } |
360 | 350 |
361 // Initializes the underlying Message object of "to" so it becomes a new parent | 351 // Initializes the underlying Message object of "to" so it becomes a new parent |
362 // map container, and copies all the values from "from" to it. A child map | 352 // repeated scalar, and copies all the values from "from" to it. A child scalar |
363 // container can be released by passing it as both from and to (e.g. making it | 353 // container can be released by passing it as both from and to (e.g. making it |
364 // the recipient of the new parent message and copying the values from itself). | 354 // 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. | |
366 static int InitializeAndCopyToParentContainer(MapContainer* from, | 355 static int InitializeAndCopyToParentContainer(MapContainer* from, |
367 MapContainer* to) { | 356 MapContainer* to) { |
368 // For now we require from == to, re-evaluate if we want to support deep copy | 357 // For now we require from == to, re-evaluate if we want to support deep copy |
369 // as in repeated_scalar_container.cc. | 358 // as in repeated_scalar_container.cc. |
370 GOOGLE_DCHECK(from == to); | 359 GOOGLE_DCHECK(from == to); |
371 Message* new_message = from->message->New(); | 360 Message* new_message = from->message->New(); |
372 | 361 |
373 if (MapReflectionFriend::Length(reinterpret_cast<PyObject*>(from)) > 0) { | 362 if (MapReflectionFriend::Length(reinterpret_cast<PyObject*>(from)) > 0) { |
374 // A somewhat roundabout way of copying just one field from old_message to | 363 // A somewhat roundabout way of copying just one field from old_message to |
375 // new_message. This is the best we can do with what Reflection gives us. | 364 // new_message. This is the best we can do with what Reflection gives us. |
376 Message* mutable_old = from->GetMutableMessage(); | 365 Message* mutable_old = from->GetMutableMessage(); |
377 std::vector<const FieldDescriptor*> fields; | 366 vector<const FieldDescriptor*> fields; |
378 fields.push_back(from->parent_field_descriptor); | 367 fields.push_back(from->parent_field_descriptor); |
379 | 368 |
380 // Move the map field into the new message. | 369 // Move the map field into the new message. |
381 mutable_old->GetReflection()->SwapFields(mutable_old, new_message, fields); | 370 mutable_old->GetReflection()->SwapFields(mutable_old, new_message, fields); |
382 | 371 |
383 // If/when we support from != to, this will be required also to copy the | 372 // If/when we support from != to, this will be required also to copy the |
384 // map field back into the existing message: | 373 // map field back into the existing message: |
385 // mutable_old->MergeFrom(*new_message); | 374 // mutable_old->MergeFrom(*new_message); |
386 } | 375 } |
387 | 376 |
(...skipping 16 matching lines...) Expand all Loading... |
404 | 393 |
405 | 394 |
406 // ScalarMap /////////////////////////////////////////////////////////////////// | 395 // ScalarMap /////////////////////////////////////////////////////////////////// |
407 | 396 |
408 PyObject *NewScalarMapContainer( | 397 PyObject *NewScalarMapContainer( |
409 CMessage* parent, const google::protobuf::FieldDescriptor* parent_field_desc
riptor) { | 398 CMessage* parent, const google::protobuf::FieldDescriptor* parent_field_desc
riptor) { |
410 if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) { | 399 if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) { |
411 return NULL; | 400 return NULL; |
412 } | 401 } |
413 | 402 |
414 ScopedPyObjectPtr obj(PyType_GenericAlloc(ScalarMapContainer_Type, 0)); | 403 #if PY_MAJOR_VERSION >= 3 |
| 404 ScopedPyObjectPtr obj(PyType_GenericAlloc( |
| 405 reinterpret_cast<PyTypeObject *>(ScalarMapContainer_Type), 0)); |
| 406 #else |
| 407 ScopedPyObjectPtr obj(PyType_GenericAlloc(&ScalarMapContainer_Type, 0)); |
| 408 #endif |
415 if (obj.get() == NULL) { | 409 if (obj.get() == NULL) { |
416 return PyErr_Format(PyExc_RuntimeError, | 410 return PyErr_Format(PyExc_RuntimeError, |
417 "Could not allocate new container."); | 411 "Could not allocate new container."); |
418 } | 412 } |
419 | 413 |
420 MapContainer* self = GetMap(obj.get()); | 414 MapContainer* self = GetMap(obj.get()); |
421 | 415 |
422 self->message = parent->message; | 416 self->message = parent->message; |
423 self->parent = parent; | 417 self->parent = parent; |
424 self->parent_field_descriptor = parent_field_descriptor; | 418 self->parent_field_descriptor = parent_field_descriptor; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 Py_TYPE(_self)->tp_free(_self); | 520 Py_TYPE(_self)->tp_free(_self); |
527 } | 521 } |
528 | 522 |
529 static PyMethodDef ScalarMapMethods[] = { | 523 static PyMethodDef ScalarMapMethods[] = { |
530 { "__contains__", MapReflectionFriend::Contains, METH_O, | 524 { "__contains__", MapReflectionFriend::Contains, METH_O, |
531 "Tests whether a key is a member of the map." }, | 525 "Tests whether a key is a member of the map." }, |
532 { "clear", (PyCFunction)Clear, METH_NOARGS, | 526 { "clear", (PyCFunction)Clear, METH_NOARGS, |
533 "Removes all elements from the map." }, | 527 "Removes all elements from the map." }, |
534 { "get", ScalarMapGet, METH_VARARGS, | 528 { "get", ScalarMapGet, METH_VARARGS, |
535 "Gets the value for the given key if present, or otherwise a default" }, | 529 "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." }, | |
538 /* | 530 /* |
539 { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS, | 531 { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS, |
540 "Makes a deep copy of the class." }, | 532 "Makes a deep copy of the class." }, |
541 { "__reduce__", (PyCFunction)Reduce, METH_NOARGS, | 533 { "__reduce__", (PyCFunction)Reduce, METH_NOARGS, |
542 "Outputs picklable representation of the repeated field." }, | 534 "Outputs picklable representation of the repeated field." }, |
543 */ | 535 */ |
544 {NULL, NULL}, | 536 {NULL, NULL}, |
545 }; | 537 }; |
546 | 538 |
547 PyTypeObject *ScalarMapContainer_Type; | |
548 #if PY_MAJOR_VERSION >= 3 | 539 #if PY_MAJOR_VERSION >= 3 |
549 static PyType_Slot ScalarMapContainer_Type_slots[] = { | 540 static PyType_Slot ScalarMapContainer_Type_slots[] = { |
550 {Py_tp_dealloc, (void *)ScalarMapDealloc}, | 541 {Py_tp_dealloc, (void *)ScalarMapDealloc}, |
551 {Py_mp_length, (void *)MapReflectionFriend::Length}, | 542 {Py_mp_length, (void *)MapReflectionFriend::Length}, |
552 {Py_mp_subscript, (void *)MapReflectionFriend::ScalarMapGetItem}, | 543 {Py_mp_subscript, (void *)MapReflectionFriend::ScalarMapGetItem}, |
553 {Py_mp_ass_subscript, (void *)MapReflectionFriend::ScalarMapSetItem}, | 544 {Py_mp_ass_subscript, (void *)MapReflectionFriend::ScalarMapSetItem}, |
554 {Py_tp_methods, (void *)ScalarMapMethods}, | 545 {Py_tp_methods, (void *)ScalarMapMethods}, |
555 {Py_tp_iter, (void *)MapReflectionFriend::GetIterator}, | 546 {Py_tp_iter, (void *)MapReflectionFriend::GetIterator}, |
556 {0, 0}, | 547 {0, 0}, |
557 }; | 548 }; |
558 | 549 |
559 PyType_Spec ScalarMapContainer_Type_spec = { | 550 PyType_Spec ScalarMapContainer_Type_spec = { |
560 FULL_MODULE_NAME ".ScalarMapContainer", | 551 FULL_MODULE_NAME ".ScalarMapContainer", |
561 sizeof(MapContainer), | 552 sizeof(MapContainer), |
562 0, | 553 0, |
563 Py_TPFLAGS_DEFAULT, | 554 Py_TPFLAGS_DEFAULT, |
564 ScalarMapContainer_Type_slots | 555 ScalarMapContainer_Type_slots |
565 }; | 556 }; |
| 557 PyObject *ScalarMapContainer_Type; |
566 #else | 558 #else |
567 static PyMappingMethods ScalarMapMappingMethods = { | 559 static PyMappingMethods ScalarMapMappingMethods = { |
568 MapReflectionFriend::Length, // mp_length | 560 MapReflectionFriend::Length, // mp_length |
569 MapReflectionFriend::ScalarMapGetItem, // mp_subscript | 561 MapReflectionFriend::ScalarMapGetItem, // mp_subscript |
570 MapReflectionFriend::ScalarMapSetItem, // mp_ass_subscript | 562 MapReflectionFriend::ScalarMapSetItem, // mp_ass_subscript |
571 }; | 563 }; |
572 | 564 |
573 PyTypeObject _ScalarMapContainer_Type = { | 565 PyTypeObject ScalarMapContainer_Type = { |
574 PyVarObject_HEAD_INIT(&PyType_Type, 0) | 566 PyVarObject_HEAD_INIT(&PyType_Type, 0) |
575 FULL_MODULE_NAME ".ScalarMapContainer", // tp_name | 567 FULL_MODULE_NAME ".ScalarMapContainer", // tp_name |
576 sizeof(MapContainer), // tp_basicsize | 568 sizeof(MapContainer), // tp_basicsize |
577 0, // tp_itemsize | 569 0, // tp_itemsize |
578 ScalarMapDealloc, // tp_dealloc | 570 ScalarMapDealloc, // tp_dealloc |
579 0, // tp_print | 571 0, // tp_print |
580 0, // tp_getattr | 572 0, // tp_getattr |
581 0, // tp_setattr | 573 0, // tp_setattr |
582 0, // tp_compare | 574 0, // tp_compare |
583 0, // tp_repr | 575 0, // tp_repr |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
644 return ret; | 636 return ret; |
645 } | 637 } |
646 | 638 |
647 PyObject* NewMessageMapContainer( | 639 PyObject* NewMessageMapContainer( |
648 CMessage* parent, const google::protobuf::FieldDescriptor* parent_field_desc
riptor, | 640 CMessage* parent, const google::protobuf::FieldDescriptor* parent_field_desc
riptor, |
649 CMessageClass* message_class) { | 641 CMessageClass* message_class) { |
650 if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) { | 642 if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) { |
651 return NULL; | 643 return NULL; |
652 } | 644 } |
653 | 645 |
654 PyObject* obj = PyType_GenericAlloc(MessageMapContainer_Type, 0); | 646 #if PY_MAJOR_VERSION >= 3 |
| 647 PyObject* obj = PyType_GenericAlloc( |
| 648 reinterpret_cast<PyTypeObject *>(MessageMapContainer_Type), 0); |
| 649 #else |
| 650 PyObject* obj = PyType_GenericAlloc(&MessageMapContainer_Type, 0); |
| 651 #endif |
655 if (obj == NULL) { | 652 if (obj == NULL) { |
656 return PyErr_Format(PyExc_RuntimeError, | 653 return PyErr_Format(PyExc_RuntimeError, |
657 "Could not allocate new container."); | 654 "Could not allocate new container."); |
658 } | 655 } |
659 | 656 |
660 MessageMapContainer* self = GetMessageMap(obj); | 657 MessageMapContainer* self = GetMessageMap(obj); |
661 | 658 |
662 self->message = parent->message; | 659 self->message = parent->message; |
663 self->parent = parent; | 660 self->parent = parent; |
664 self->parent_field_descriptor = parent_field_descriptor; | 661 self->parent_field_descriptor = parent_field_descriptor; |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
776 | 773 |
777 static PyMethodDef MessageMapMethods[] = { | 774 static PyMethodDef MessageMapMethods[] = { |
778 { "__contains__", (PyCFunction)MapReflectionFriend::Contains, METH_O, | 775 { "__contains__", (PyCFunction)MapReflectionFriend::Contains, METH_O, |
779 "Tests whether the map contains this element."}, | 776 "Tests whether the map contains this element."}, |
780 { "clear", (PyCFunction)Clear, METH_NOARGS, | 777 { "clear", (PyCFunction)Clear, METH_NOARGS, |
781 "Removes all elements from the map."}, | 778 "Removes all elements from the map."}, |
782 { "get", MessageMapGet, METH_VARARGS, | 779 { "get", MessageMapGet, METH_VARARGS, |
783 "Gets the value for the given key if present, or otherwise a default" }, | 780 "Gets the value for the given key if present, or otherwise a default" }, |
784 { "get_or_create", MapReflectionFriend::MessageMapGetItem, METH_O, | 781 { "get_or_create", MapReflectionFriend::MessageMapGetItem, METH_O, |
785 "Alias for getitem, useful to make explicit that the map is mutated." }, | 782 "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." }, | |
788 /* | 783 /* |
789 { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS, | 784 { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS, |
790 "Makes a deep copy of the class." }, | 785 "Makes a deep copy of the class." }, |
791 { "__reduce__", (PyCFunction)Reduce, METH_NOARGS, | 786 { "__reduce__", (PyCFunction)Reduce, METH_NOARGS, |
792 "Outputs picklable representation of the repeated field." }, | 787 "Outputs picklable representation of the repeated field." }, |
793 */ | 788 */ |
794 {NULL, NULL}, | 789 {NULL, NULL}, |
795 }; | 790 }; |
796 | 791 |
797 PyTypeObject *MessageMapContainer_Type; | |
798 #if PY_MAJOR_VERSION >= 3 | 792 #if PY_MAJOR_VERSION >= 3 |
799 static PyType_Slot MessageMapContainer_Type_slots[] = { | 793 static PyType_Slot MessageMapContainer_Type_slots[] = { |
800 {Py_tp_dealloc, (void *)MessageMapDealloc}, | 794 {Py_tp_dealloc, (void *)MessageMapDealloc}, |
801 {Py_mp_length, (void *)MapReflectionFriend::Length}, | 795 {Py_mp_length, (void *)MapReflectionFriend::Length}, |
802 {Py_mp_subscript, (void *)MapReflectionFriend::MessageMapGetItem}, | 796 {Py_mp_subscript, (void *)MapReflectionFriend::MessageMapGetItem}, |
803 {Py_mp_ass_subscript, (void *)MapReflectionFriend::MessageMapSetItem}, | 797 {Py_mp_ass_subscript, (void *)MapReflectionFriend::MessageMapSetItem}, |
804 {Py_tp_methods, (void *)MessageMapMethods}, | 798 {Py_tp_methods, (void *)MessageMapMethods}, |
805 {Py_tp_iter, (void *)MapReflectionFriend::GetIterator}, | 799 {Py_tp_iter, (void *)MapReflectionFriend::GetIterator}, |
806 {0, 0} | 800 {0, 0} |
807 }; | 801 }; |
808 | 802 |
809 PyType_Spec MessageMapContainer_Type_spec = { | 803 PyType_Spec MessageMapContainer_Type_spec = { |
810 FULL_MODULE_NAME ".MessageMapContainer", | 804 FULL_MODULE_NAME ".MessageMapContainer", |
811 sizeof(MessageMapContainer), | 805 sizeof(MessageMapContainer), |
812 0, | 806 0, |
813 Py_TPFLAGS_DEFAULT, | 807 Py_TPFLAGS_DEFAULT, |
814 MessageMapContainer_Type_slots | 808 MessageMapContainer_Type_slots |
815 }; | 809 }; |
| 810 |
| 811 PyObject *MessageMapContainer_Type; |
816 #else | 812 #else |
817 static PyMappingMethods MessageMapMappingMethods = { | 813 static PyMappingMethods MessageMapMappingMethods = { |
818 MapReflectionFriend::Length, // mp_length | 814 MapReflectionFriend::Length, // mp_length |
819 MapReflectionFriend::MessageMapGetItem, // mp_subscript | 815 MapReflectionFriend::MessageMapGetItem, // mp_subscript |
820 MapReflectionFriend::MessageMapSetItem, // mp_ass_subscript | 816 MapReflectionFriend::MessageMapSetItem, // mp_ass_subscript |
821 }; | 817 }; |
822 | 818 |
823 PyTypeObject _MessageMapContainer_Type = { | 819 PyTypeObject MessageMapContainer_Type = { |
824 PyVarObject_HEAD_INIT(&PyType_Type, 0) | 820 PyVarObject_HEAD_INIT(&PyType_Type, 0) |
825 FULL_MODULE_NAME ".MessageMapContainer", // tp_name | 821 FULL_MODULE_NAME ".MessageMapContainer", // tp_name |
826 sizeof(MessageMapContainer), // tp_basicsize | 822 sizeof(MessageMapContainer), // tp_basicsize |
827 0, // tp_itemsize | 823 0, // tp_itemsize |
828 MessageMapDealloc, // tp_dealloc | 824 MessageMapDealloc, // tp_dealloc |
829 0, // tp_print | 825 0, // tp_print |
830 0, // tp_getattr | 826 0, // tp_getattr |
831 0, // tp_setattr | 827 0, // tp_setattr |
832 0, // tp_compare | 828 0, // tp_compare |
833 0, // tp_repr | 829 0, // tp_repr |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
962 0, // tp_members | 958 0, // tp_members |
963 0, // tp_getset | 959 0, // tp_getset |
964 0, // tp_base | 960 0, // tp_base |
965 0, // tp_dict | 961 0, // tp_dict |
966 0, // tp_descr_get | 962 0, // tp_descr_get |
967 0, // tp_descr_set | 963 0, // tp_descr_set |
968 0, // tp_dictoffset | 964 0, // tp_dictoffset |
969 0, // tp_init | 965 0, // tp_init |
970 }; | 966 }; |
971 | 967 |
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 | |
1029 } // namespace python | 968 } // namespace python |
1030 } // namespace protobuf | 969 } // namespace protobuf |
1031 } // namespace google | 970 } // namespace google |
OLD | NEW |