48 #if PY_MAJOR_VERSION >= 3
49 #define PyInt_FromLong PyLong_FromLong
50 #define PyInt_FromSize_t PyLong_FromSize_t
62 static PyObject*
Contains(PyObject* _self, PyObject*
key);
63 static Py_ssize_t
Length(PyObject* _self);
65 static PyObject*
IterNext(PyObject* _self);
66 static PyObject*
MergeFrom(PyObject* _self, PyObject* arg);
80 std::unique_ptr<::google::protobuf::MapIterator>
iter;
113 Py_ssize_t value_len;
118 if (PyBytes_AsStringAndSize(py_string, &
value, &value_len) < 0) {
119 Py_DECREF(py_string);
122 stl_string->assign(
value, value_len);
123 Py_DECREF(py_string);
131 switch (field_descriptor->
cpp_type()) {
167 PyExc_SystemError,
"Type %d cannot be a map key",
176 switch (field_descriptor->
cpp_type()) {
178 return PyInt_FromLong(
key.GetInt32Value());
180 return PyLong_FromLongLong(
key.GetInt64Value());
182 return PyInt_FromSize_t(
key.GetUInt32Value());
184 return PyLong_FromUnsignedLongLong(
key.GetUInt64Value());
186 return PyBool_FromLong(
key.GetBoolValue());
191 PyExc_SystemError,
"Couldn't convert type %d to value",
201 switch (field_descriptor->
cpp_type()) {
203 return PyInt_FromLong(
value.GetInt32Value());
205 return PyLong_FromLongLong(
value.GetInt64Value());
207 return PyInt_FromSize_t(
value.GetUInt32Value());
209 return PyLong_FromUnsignedLongLong(
value.GetUInt64Value());
211 return PyFloat_FromDouble(
value.GetFloatValue());
213 return PyFloat_FromDouble(
value.GetDoubleValue());
215 return PyBool_FromLong(
value.GetBoolValue());
219 return PyInt_FromLong(
value.GetEnumValue());
222 PyExc_SystemError,
"Couldn't convert type %d to value",
232 bool allow_unknown_enum_values,
234 switch (field_descriptor->
cpp_type()) {
280 if (allow_unknown_enum_values) {
287 if (enum_value !=
NULL) {
291 PyErr_Format(PyExc_ValueError,
"Unknown enum value: %d",
value);
299 PyExc_SystemError,
"Setting value to a field of unknown type %d",
315 self->parent_field_descriptor);
332 self->parent_field_descriptor->message_type());
348 self->parent_field_descriptor);
349 field->MergeFrom(*other_field);
383 PyErr_Format(PyExc_RuntimeError,
384 "Could not allocate new container.");
391 self->parent = parent;
395 self->key_field_descriptor =
397 self->value_field_descriptor =
400 if (
self->key_field_descriptor ==
NULL ||
401 self->value_field_descriptor ==
NULL) {
402 PyErr_Format(PyExc_KeyError,
403 "Map entry descriptor did not have key/value fields");
461 PyErr_Format(PyExc_KeyError,
"Key not present in map");
469 static char* kwlist[] = {
"key",
"default",
nullptr};
472 if (!PyArg_ParseTupleAndKeywords(
args, kwargs,
"O|O", kwlist, &
key,
478 if (is_present.
get() ==
NULL) {
482 if (PyObject_IsTrue(is_present.
get())) {
519 if (PyDict_SetItem(dict.
get(),
key.get(),
value.get()) < 0) {
523 return PyObject_Repr(dict.
get());
528 self->RemoveFromParentCache();
530 type->tp_free(_self);
531 if (
type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
539 "Tests whether a key is a member of the map."},
540 {
"clear", (PyCFunction)
Clear, METH_NOARGS,
541 "Removes all elements from the map."},
542 {
"get", (PyCFunction)
ScalarMapGet, METH_VARARGS | METH_KEYWORDS,
543 "Gets the value for the given key if present, or otherwise a default"},
545 "Return the class used to build Entries of (key, value) pairs."},
547 "Merges a map into the current map."},
558 #if PY_MAJOR_VERSION >= 3
559 static PyType_Slot ScalarMapContainer_Type_slots[] = {
570 PyType_Spec ScalarMapContainer_Type_spec = {
572 sizeof(MapContainer),
575 ScalarMapContainer_Type_slots
605 "A scalar map container",
634 ->BuildSubMessageFromPointer(
self->parent_field_descriptor,
message,
648 PyErr_SetString(PyExc_RuntimeError,
"Could not allocate new container.");
655 self->parent = parent;
659 self->key_field_descriptor =
661 self->value_field_descriptor =
667 if (
self->key_field_descriptor ==
NULL ||
668 self->value_field_descriptor ==
NULL) {
670 PyErr_SetString(PyExc_KeyError,
671 "Map entry descriptor did not have key/value fields");
681 PyErr_Format(PyExc_ValueError,
682 "Direct assignment of submessage not allowed");
711 self->parent->MaybeReleaseSubMessage(sub_message)) {
712 Message* msg = released->message;
713 released->message = msg->
New();
722 PyErr_Format(PyExc_KeyError,
"Key not present in map");
772 if (PyDict_SetItem(dict.
get(),
key.get(),
value.get()) < 0) {
776 return PyObject_Repr(dict.
get());
780 static char* kwlist[] = {
"key",
"default",
nullptr};
783 if (!PyArg_ParseTupleAndKeywords(
args, kwargs,
"O|O", kwlist, &
key,
789 if (is_present.
get() ==
NULL) {
793 if (PyObject_IsTrue(is_present.
get())) {
807 self->RemoveFromParentCache();
808 Py_DECREF(
self->message_class);
810 type->tp_free(_self);
811 if (
type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
819 "Tests whether the map contains this element."},
820 {
"clear", (PyCFunction)
Clear, METH_NOARGS,
821 "Removes all elements from the map."},
822 {
"get", (PyCFunction)
MessageMapGet, METH_VARARGS | METH_KEYWORDS,
823 "Gets the value for the given key if present, or otherwise a default"},
825 "Alias for getitem, useful to make explicit that the map is mutated."},
827 "Return the class used to build Entries of (key, value) pairs."},
829 "Merges a map into the current map."},
840 #if PY_MAJOR_VERSION >= 3
841 static PyType_Slot MessageMapContainer_Type_slots[] = {
852 PyType_Spec MessageMapContainer_Type_spec = {
854 sizeof(MessageMapContainer),
857 MessageMapContainer_Type_slots
887 "A map container for message",
917 return PyErr_Format(PyExc_KeyError,
"Could not allocate iterator");
925 Py_INCREF(
self->parent);
932 iter->
iter.reset(new ::google::protobuf::MapIterator(
936 return obj.release();
944 if (
self->version !=
self->container->version) {
945 return PyErr_Format(PyExc_RuntimeError,
946 "Map modified during iteration.");
948 if (
self->parent !=
self->container->parent) {
949 return PyErr_Format(PyExc_RuntimeError,
950 "Map cleared during iteration.");
966 self->iter->GetKey());
976 Py_CLEAR(
self->container);
977 Py_CLEAR(
self->parent);
978 Py_TYPE(_self)->tp_free(_self);
1002 "A scalar map iterator",
1023 "google.protobuf.internal.containers"));
1024 if (containers ==
NULL) {
1029 PyObject_GetAttrString(containers.
get(),
"MutableMapping"));
1030 if (mutable_mapping ==
NULL) {
1034 Py_INCREF(mutable_mapping.
get());
1035 #if PY_MAJOR_VERSION >= 3
1037 if (bases ==
NULL) {
1042 PyType_FromSpecWithBases(&ScalarMapContainer_Type_spec, bases.
get()));
1045 reinterpret_cast<PyTypeObject*
>(mutable_mapping.
get());
1058 #if PY_MAJOR_VERSION >= 3
1060 PyType_FromSpecWithBases(&MessageMapContainer_Type_spec, bases.
get()));
1062 Py_INCREF(mutable_mapping.
get());
1064 reinterpret_cast<PyTypeObject*
>(mutable_mapping.
get());