descriptor_containers.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009-2021, Google LLC
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of Google LLC nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include "descriptor_containers.h"
29 
30 #include "descriptor.h"
31 #include "protobuf.h"
32 #include "upb/def.h"
33 
34 // -----------------------------------------------------------------------------
35 // DescriptorIterator
36 // -----------------------------------------------------------------------------
37 
38 typedef struct {
41  const void* parent; // upb_MessageDef*, upb_DefPool*, etc.
42  PyObject* parent_obj; // Python object that keeps parent alive, we own a ref.
43  int index; // Current iterator index.
45 
47  assert(Py_TYPE(obj) == PyUpb_ModuleState_Get()->descriptor_iterator_type);
49 }
50 
51 static void PyUpb_DescriptorIterator_Dealloc(PyObject* _self) {
53  Py_DECREF(self->parent_obj);
54  PyUpb_Dealloc(self);
55 }
56 
58  const void* parent,
59  PyObject* parent_obj) {
62  (void*)PyType_GenericAlloc(s->descriptor_iterator_type, 0);
63  iter->funcs = funcs;
64  iter->parent = parent;
65  iter->parent_obj = parent_obj;
66  iter->index = 0;
67  Py_INCREF(iter->parent_obj);
68  return &iter->ob_base;
69 }
70 
71 PyObject* PyUpb_DescriptorIterator_IterNext(PyObject* _self) {
73  int size = self->funcs->get_elem_count(self->parent);
74  if (self->index >= size) return NULL;
75  const void* elem = self->funcs->index(self->parent, self->index);
76  self->index++;
77  return self->funcs->get_elem_wrapper(elem);
78 }
79 
80 static PyType_Slot PyUpb_DescriptorIterator_Slots[] = {
81  {Py_tp_dealloc, PyUpb_DescriptorIterator_Dealloc},
82  {Py_tp_iter, PyObject_SelfIter},
83  {Py_tp_iternext, PyUpb_DescriptorIterator_IterNext},
84  {0, NULL}};
85 
86 static PyType_Spec PyUpb_DescriptorIterator_Spec = {
87  PYUPB_MODULE_NAME ".DescriptorIterator", // tp_name
88  sizeof(PyUpb_DescriptorIterator), // tp_basicsize
89  0, // tp_itemsize
90  Py_TPFLAGS_DEFAULT, // tp_flags
92 };
93 
94 // -----------------------------------------------------------------------------
95 // GenericSequence
96 // -----------------------------------------------------------------------------
97 
98 typedef struct {
101  const void* parent; // upb_MessageDef*, upb_DefPool*, etc.
102  PyObject* parent_obj; // Python object that keeps parent alive, we own a ref.
104 
106  assert(Py_TYPE(obj) == PyUpb_ModuleState_Get()->generic_sequence_type);
107  return (PyUpb_GenericSequence*)obj;
108 }
109 
110 static void PyUpb_GenericSequence_Dealloc(PyObject* _self) {
112  Py_CLEAR(self->parent_obj);
113  PyUpb_Dealloc(self);
114 }
115 
117  const void* parent, PyObject* parent_obj) {
119  PyUpb_GenericSequence* seq =
120  (PyUpb_GenericSequence*)PyType_GenericAlloc(s->generic_sequence_type, 0);
121  seq->funcs = funcs;
122  seq->parent = parent;
123  seq->parent_obj = parent_obj;
124  Py_INCREF(parent_obj);
125  return &seq->ob_base;
126 }
127 
128 static Py_ssize_t PyUpb_GenericSequence_Length(PyObject* _self) {
130  return self->funcs->get_elem_count(self->parent);
131 }
132 
133 static PyObject* PyUpb_GenericSequence_GetItem(PyObject* _self,
134  Py_ssize_t index) {
136  Py_ssize_t size = self->funcs->get_elem_count(self->parent);
137  if (index < 0 || index >= size) {
138  PyErr_Format(PyExc_IndexError, "list index (%zd) out of range", index);
139  return NULL;
140  }
141  const void* elem = self->funcs->index(self->parent, index);
142  return self->funcs->get_elem_wrapper(elem);
143 }
144 
145 // A sequence container can only be equal to another sequence container, or (for
146 // backward compatibility) to a list containing the same items.
147 // Returns 1 if equal, 0 if unequal, -1 on error.
149  PyObject* other) {
150  // Check the identity of C++ pointers.
151  if (PyObject_TypeCheck(other, Py_TYPE(self))) {
152  PyUpb_GenericSequence* other_seq = (void*)other;
153  return self->parent == other_seq->parent && self->funcs == other_seq->funcs;
154  }
155 
156  if (!PyList_Check(other)) return 0;
157 
158  // return list(self) == other
159  // We can clamp `i` to int because GenericSequence uses int for size (this
160  // is useful when we do int iteration below).
161  int n = PyUpb_GenericSequence_Length((PyObject*)self);
162  if ((Py_ssize_t)n != PyList_Size(other)) {
163  return false;
164  }
165 
166  PyObject* item1;
167  for (int i = 0; i < n; i++) {
168  item1 = PyUpb_GenericSequence_GetItem((PyObject*)self, i);
169  PyObject* item2 = PyList_GetItem(other, i);
170  if (!item1 || !item2) goto error;
171  int cmp = PyObject_RichCompareBool(item1, item2, Py_EQ);
172  Py_DECREF(item1);
173  if (cmp != 1) return cmp;
174  }
175  // All items were found and equal
176  return 1;
177 
178 error:
179  Py_XDECREF(item1);
180  return -1;
181 }
182 
183 static PyObject* PyUpb_GenericSequence_RichCompare(PyObject* _self,
184  PyObject* other, int opid) {
186  if (opid != Py_EQ && opid != Py_NE) {
187  Py_RETURN_NOTIMPLEMENTED;
188  }
189  bool ret = PyUpb_GenericSequence_IsEqual(self, other);
190  if (opid == Py_NE) ret = !ret;
191  return PyBool_FromLong(ret);
192 }
193 
194 // Linear search. Could optimize this in some cases (defs that have index),
195 // but not all (FileDescriptor.dependencies).
196 static int PyUpb_GenericSequence_Find(PyObject* _self, PyObject* item) {
198  const void* item_ptr = PyUpb_AnyDescriptor_GetDef(item);
199  int count = self->funcs->get_elem_count(self->parent);
200  for (int i = 0; i < count; i++) {
201  if (self->funcs->index(self->parent, i) == item_ptr) {
202  return i;
203  }
204  }
205  return -1;
206 }
207 
208 static PyObject* PyUpb_GenericSequence_Index(PyObject* self, PyObject* item) {
209  int position = PyUpb_GenericSequence_Find(self, item);
210  if (position < 0) {
211  PyErr_SetNone(PyExc_ValueError);
212  return NULL;
213  } else {
214  return PyLong_FromLong(position);
215  }
216 }
217 
218 static PyObject* PyUpb_GenericSequence_Count(PyObject* _self, PyObject* item) {
220  const void* item_ptr = PyUpb_AnyDescriptor_GetDef(item);
221  int n = self->funcs->get_elem_count(self->parent);
222  int count = 0;
223  for (int i = 0; i < n; i++) {
224  if (self->funcs->index(self->parent, i) == item_ptr) {
225  count++;
226  }
227  }
228  return PyLong_FromLong(count);
229 }
230 
231 static PyObject* PyUpb_GenericSequence_Append(PyObject* self, PyObject* args) {
232  PyErr_Format(PyExc_TypeError, "'%R' is not a mutable sequence", self);
233  return NULL;
234 }
235 
236 static PyMethodDef PyUpb_GenericSequence_Methods[] = {
237  {"index", PyUpb_GenericSequence_Index, METH_O},
238  {"count", PyUpb_GenericSequence_Count, METH_O},
239  {"append", PyUpb_GenericSequence_Append, METH_O},
240  // This was implemented for Python/C++ but so far has not been required.
241  //{ "__reversed__", (PyCFunction)Reversed, METH_NOARGS, },
242  {NULL}};
243 
244 static PyType_Slot PyUpb_GenericSequence_Slots[] = {
245  {Py_tp_dealloc, &PyUpb_GenericSequence_Dealloc},
246  {Py_tp_methods, &PyUpb_GenericSequence_Methods},
247  {Py_sq_length, PyUpb_GenericSequence_Length},
248  {Py_sq_item, PyUpb_GenericSequence_GetItem},
249  {Py_tp_richcompare, &PyUpb_GenericSequence_RichCompare},
250  // These were implemented for Python/C++ but so far have not been required.
251  // {Py_tp_repr, &PyUpb_GenericSequence_Repr},
252  // {Py_sq_contains, PyUpb_GenericSequence_Contains},
253  // {Py_mp_subscript, PyUpb_GenericSequence_Subscript},
254  // {Py_mp_ass_subscript, PyUpb_GenericSequence_AssignSubscript},
255  {0, NULL},
256 };
257 
258 static PyType_Spec PyUpb_GenericSequence_Spec = {
259  PYUPB_MODULE_NAME "._GenericSequence", // tp_name
260  sizeof(PyUpb_GenericSequence), // tp_basicsize
261  0, // tp_itemsize
262  Py_TPFLAGS_DEFAULT, // tp_flags
264 };
265 
266 // -----------------------------------------------------------------------------
267 // ByNameMap
268 // -----------------------------------------------------------------------------
269 
270 typedef struct {
273  const void* parent; // upb_MessageDef*, upb_DefPool*, etc.
274  PyObject* parent_obj; // Python object that keeps parent alive, we own a ref.
276 
278  assert(Py_TYPE(obj) == PyUpb_ModuleState_Get()->by_name_map_type);
279  return (PyUpb_ByNameMap*)obj;
280 }
281 
282 static void PyUpb_ByNameMap_Dealloc(PyObject* _self) {
283  PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
284  Py_DECREF(self->parent_obj);
285  PyUpb_Dealloc(self);
286 }
287 
289  const void* parent, PyObject* parent_obj) {
291  PyUpb_ByNameMap* map = (void*)PyType_GenericAlloc(s->by_name_map_type, 0);
292  map->funcs = funcs;
293  map->parent = parent;
294  map->parent_obj = parent_obj;
295  Py_INCREF(parent_obj);
296  return &map->ob_base;
297 }
298 
299 static Py_ssize_t PyUpb_ByNameMap_Length(PyObject* _self) {
300  PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
301  return self->funcs->base.get_elem_count(self->parent);
302 }
303 
304 static PyObject* PyUpb_ByNameMap_Subscript(PyObject* _self, PyObject* key) {
305  PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
306  const char* name = PyUpb_GetStrData(key);
307  const void* elem = name ? self->funcs->lookup(self->parent, name) : NULL;
308 
309  if (elem) {
310  return self->funcs->base.get_elem_wrapper(elem);
311  } else {
312  PyErr_SetObject(PyExc_KeyError, key);
313  return NULL;
314  }
315 }
316 
317 static int PyUpb_ByNameMap_AssignSubscript(PyObject* self, PyObject* key,
318  PyObject* value) {
319  PyErr_Format(PyExc_TypeError, PYUPB_MODULE_NAME
320  ".ByNameMap' object does not support item assignment");
321  return -1;
322 }
323 
324 static int PyUpb_ByNameMap_Contains(PyObject* _self, PyObject* key) {
325  PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
326  const char* name = PyUpb_GetStrData(key);
327  const void* elem = name ? self->funcs->lookup(self->parent, name) : NULL;
328  return elem ? 1 : 0;
329 }
330 
331 static PyObject* PyUpb_ByNameMap_Get(PyObject* _self, PyObject* args) {
332  PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
333  PyObject* key;
334  PyObject* default_value = Py_None;
335  if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &default_value)) {
336  return NULL;
337  }
338 
339  const char* name = PyUpb_GetStrData(key);
340  const void* elem = name ? self->funcs->lookup(self->parent, name) : NULL;
341 
342  if (elem) {
343  return self->funcs->base.get_elem_wrapper(elem);
344  } else {
345  Py_INCREF(default_value);
346  return default_value;
347  }
348 }
349 
350 static PyObject* PyUpb_ByNameMap_GetIter(PyObject* _self) {
351  PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
352  return PyUpb_DescriptorIterator_New(&self->funcs->base, self->parent,
353  self->parent_obj);
354 }
355 
356 static PyObject* PyUpb_ByNameMap_Keys(PyObject* _self, PyObject* args) {
357  PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
358  int n = self->funcs->base.get_elem_count(self->parent);
359  PyObject* ret = PyList_New(n);
360  if (!ret) return NULL;
361  for (int i = 0; i < n; i++) {
362  const void* elem = self->funcs->base.index(self->parent, i);
363  PyObject* key = PyUnicode_FromString(self->funcs->get_elem_name(elem));
364  if (!key) goto error;
365  PyList_SetItem(ret, i, key);
366  }
367  return ret;
368 
369 error:
370  Py_XDECREF(ret);
371  return NULL;
372 }
373 
374 static PyObject* PyUpb_ByNameMap_Values(PyObject* _self, PyObject* args) {
375  PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
376  int n = self->funcs->base.get_elem_count(self->parent);
377  PyObject* ret = PyList_New(n);
378  if (!ret) return NULL;
379  for (int i = 0; i < n; i++) {
380  const void* elem = self->funcs->base.index(self->parent, i);
381  PyObject* py_elem = self->funcs->base.get_elem_wrapper(elem);
382  if (!py_elem) goto error;
383  PyList_SetItem(ret, i, py_elem);
384  }
385  return ret;
386 
387 error:
388  Py_XDECREF(ret);
389  return NULL;
390 }
391 
392 static PyObject* PyUpb_ByNameMap_Items(PyObject* _self, PyObject* args) {
393  PyUpb_ByNameMap* self = (PyUpb_ByNameMap*)_self;
394  int n = self->funcs->base.get_elem_count(self->parent);
395  PyObject* ret = PyList_New(n);
396  PyObject* item;
397  PyObject* py_elem;
398  if (!ret) return NULL;
399  for (int i = 0; i < n; i++) {
400  const void* elem = self->funcs->base.index(self->parent, i);
401  item = PyTuple_New(2);
402  py_elem = self->funcs->base.get_elem_wrapper(elem);
403  if (!item || !py_elem) goto error;
404  PyTuple_SetItem(item, 0,
405  PyUnicode_FromString(self->funcs->get_elem_name(elem)));
406  PyTuple_SetItem(item, 1, py_elem);
407  PyList_SetItem(ret, i, item);
408  }
409  return ret;
410 
411 error:
412  Py_XDECREF(py_elem);
413  Py_XDECREF(item);
414  Py_XDECREF(ret);
415  return NULL;
416 }
417 
418 // A mapping container can only be equal to another mapping container, or (for
419 // backward compatibility) to a dict containing the same items.
420 // Returns 1 if equal, 0 if unequal, -1 on error.
421 static int PyUpb_ByNameMap_IsEqual(PyUpb_ByNameMap* self, PyObject* other) {
422  // Check the identity of C++ pointers.
423  if (PyObject_TypeCheck(other, Py_TYPE(self))) {
424  PyUpb_ByNameMap* other_map = (void*)other;
425  return self->parent == other_map->parent && self->funcs == other_map->funcs;
426  }
427 
428  if (!PyDict_Check(other)) return 0;
429 
430  PyObject* self_dict = PyDict_New();
431  PyDict_Merge(self_dict, (PyObject*)self, 0);
432  int eq = PyObject_RichCompareBool(self_dict, other, Py_EQ);
433  Py_DECREF(self_dict);
434  return eq;
435 }
436 
437 static PyObject* PyUpb_ByNameMap_RichCompare(PyObject* _self, PyObject* other,
438  int opid) {
439  PyUpb_ByNameMap* self = PyUpb_ByNameMap_Self(_self);
440  if (opid != Py_EQ && opid != Py_NE) {
441  Py_RETURN_NOTIMPLEMENTED;
442  }
443  bool ret = PyUpb_ByNameMap_IsEqual(self, other);
444  if (opid == Py_NE) ret = !ret;
445  return PyBool_FromLong(ret);
446 }
447 
448 static PyMethodDef PyUpb_ByNameMap_Methods[] = {
449  {"get", (PyCFunction)&PyUpb_ByNameMap_Get, METH_VARARGS},
450  {"keys", PyUpb_ByNameMap_Keys, METH_NOARGS},
451  {"values", PyUpb_ByNameMap_Values, METH_NOARGS},
452  {"items", PyUpb_ByNameMap_Items, METH_NOARGS},
453  {NULL}};
454 
455 static PyType_Slot PyUpb_ByNameMap_Slots[] = {
456  {Py_mp_ass_subscript, PyUpb_ByNameMap_AssignSubscript},
457  {Py_mp_length, PyUpb_ByNameMap_Length},
458  {Py_mp_subscript, PyUpb_ByNameMap_Subscript},
459  {Py_sq_contains, &PyUpb_ByNameMap_Contains},
460  {Py_tp_dealloc, &PyUpb_ByNameMap_Dealloc},
461  {Py_tp_iter, PyUpb_ByNameMap_GetIter},
462  {Py_tp_methods, &PyUpb_ByNameMap_Methods},
463  {Py_tp_richcompare, &PyUpb_ByNameMap_RichCompare},
464  {0, NULL},
465 };
466 
467 static PyType_Spec PyUpb_ByNameMap_Spec = {
468  PYUPB_MODULE_NAME "._ByNameMap", // tp_name
469  sizeof(PyUpb_ByNameMap), // tp_basicsize
470  0, // tp_itemsize
471  Py_TPFLAGS_DEFAULT, // tp_flags
473 };
474 
475 // -----------------------------------------------------------------------------
476 // ByNumberMap
477 // -----------------------------------------------------------------------------
478 
479 typedef struct {
482  const void* parent; // upb_MessageDef*, upb_DefPool*, etc.
483  PyObject* parent_obj; // Python object that keeps parent alive, we own a ref.
485 
487  assert(Py_TYPE(obj) == PyUpb_ModuleState_Get()->by_number_map_type);
488  return (PyUpb_ByNumberMap*)obj;
489 }
490 
492  const void* parent, PyObject* parent_obj) {
494  PyUpb_ByNumberMap* map = (void*)PyType_GenericAlloc(s->by_number_map_type, 0);
495  map->funcs = funcs;
496  map->parent = parent;
497  map->parent_obj = parent_obj;
498  Py_INCREF(parent_obj);
499  return &map->ob_base;
500 }
501 
502 static void PyUpb_ByNumberMap_Dealloc(PyObject* _self) {
504  Py_DECREF(self->parent_obj);
505  PyUpb_Dealloc(self);
506 }
507 
508 static Py_ssize_t PyUpb_ByNumberMap_Length(PyObject* _self) {
510  return self->funcs->base.get_elem_count(self->parent);
511 }
512 
514  PyObject* key) {
515  long num = PyLong_AsLong(key);
516  if (num == -1 && PyErr_Occurred()) {
517  PyErr_Clear();
518  return NULL;
519  } else {
520  return self->funcs->lookup(self->parent, num);
521  }
522 }
523 
524 static PyObject* PyUpb_ByNumberMap_Subscript(PyObject* _self, PyObject* key) {
526  const void* elem = PyUpb_ByNumberMap_LookupHelper(self, key);
527  if (elem) {
528  return self->funcs->base.get_elem_wrapper(elem);
529  } else {
530  PyErr_SetObject(PyExc_KeyError, key);
531  return NULL;
532  }
533 }
534 
535 static int PyUpb_ByNumberMap_AssignSubscript(PyObject* self, PyObject* key,
536  PyObject* value) {
537  PyErr_Format(PyExc_TypeError, PYUPB_MODULE_NAME
538  ".ByNumberMap' object does not support item assignment");
539  return -1;
540 }
541 
542 static PyObject* PyUpb_ByNumberMap_Get(PyObject* _self, PyObject* args) {
544  PyObject* key;
545  PyObject* default_value = Py_None;
546  if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &default_value)) {
547  return NULL;
548  }
549 
550  const void* elem = PyUpb_ByNumberMap_LookupHelper(self, key);
551  if (elem) {
552  return self->funcs->base.get_elem_wrapper(elem);
553  } else {
554  return PyUpb_NewRef(default_value);
555  }
556 }
557 
558 static PyObject* PyUpb_ByNumberMap_GetIter(PyObject* _self) {
560  return PyUpb_DescriptorIterator_New(&self->funcs->base, self->parent,
561  self->parent_obj);
562 }
563 
564 static PyObject* PyUpb_ByNumberMap_Keys(PyObject* _self, PyObject* args) {
566  int n = self->funcs->base.get_elem_count(self->parent);
567  PyObject* ret = PyList_New(n);
568  if (!ret) return NULL;
569  for (int i = 0; i < n; i++) {
570  const void* elem = self->funcs->base.index(self->parent, i);
571  PyObject* key = PyLong_FromLong(self->funcs->get_elem_num(elem));
572  if (!key) goto error;
573  PyList_SetItem(ret, i, key);
574  }
575  return ret;
576 
577 error:
578  Py_XDECREF(ret);
579  return NULL;
580 }
581 
582 static PyObject* PyUpb_ByNumberMap_Values(PyObject* _self, PyObject* args) {
584  int n = self->funcs->base.get_elem_count(self->parent);
585  PyObject* ret = PyList_New(n);
586  if (!ret) return NULL;
587  for (int i = 0; i < n; i++) {
588  const void* elem = self->funcs->base.index(self->parent, i);
589  PyObject* py_elem = self->funcs->base.get_elem_wrapper(elem);
590  if (!py_elem) goto error;
591  PyList_SetItem(ret, i, py_elem);
592  }
593  return ret;
594 
595 error:
596  Py_XDECREF(ret);
597  return NULL;
598 }
599 
600 static PyObject* PyUpb_ByNumberMap_Items(PyObject* _self, PyObject* args) {
602  int n = self->funcs->base.get_elem_count(self->parent);
603  PyObject* ret = PyList_New(n);
604  PyObject* item;
605  PyObject* py_elem;
606  if (!ret) return NULL;
607  for (int i = 0; i < n; i++) {
608  const void* elem = self->funcs->base.index(self->parent, i);
609  int number = self->funcs->get_elem_num(elem);
610  item = PyTuple_New(2);
611  py_elem = self->funcs->base.get_elem_wrapper(elem);
612  if (!item || !py_elem) goto error;
613  PyTuple_SetItem(item, 0, PyLong_FromLong(number));
614  PyTuple_SetItem(item, 1, py_elem);
615  PyList_SetItem(ret, i, item);
616  }
617  return ret;
618 
619 error:
620  Py_XDECREF(py_elem);
621  Py_XDECREF(item);
622  Py_XDECREF(ret);
623  return NULL;
624 }
625 
626 static int PyUpb_ByNumberMap_Contains(PyObject* _self, PyObject* key) {
628  const void* elem = PyUpb_ByNumberMap_LookupHelper(self, key);
629  return elem ? 1 : 0;
630 }
631 
632 // A mapping container can only be equal to another mapping container, or (for
633 // backward compatibility) to a dict containing the same items.
634 // Returns 1 if equal, 0 if unequal, -1 on error.
635 static int PyUpb_ByNumberMap_IsEqual(PyUpb_ByNumberMap* self, PyObject* other) {
636  // Check the identity of C++ pointers.
637  if (PyObject_TypeCheck(other, Py_TYPE(self))) {
638  PyUpb_ByNumberMap* other_map = (void*)other;
639  return self->parent == other_map->parent && self->funcs == other_map->funcs;
640  }
641 
642  if (!PyDict_Check(other)) return 0;
643 
644  PyObject* self_dict = PyDict_New();
645  PyDict_Merge(self_dict, (PyObject*)self, 0);
646  int eq = PyObject_RichCompareBool(self_dict, other, Py_EQ);
647  Py_DECREF(self_dict);
648  return eq;
649 }
650 
651 static PyObject* PyUpb_ByNumberMap_RichCompare(PyObject* _self, PyObject* other,
652  int opid) {
654  if (opid != Py_EQ && opid != Py_NE) {
655  Py_RETURN_NOTIMPLEMENTED;
656  }
657  bool ret = PyUpb_ByNumberMap_IsEqual(self, other);
658  if (opid == Py_NE) ret = !ret;
659  return PyBool_FromLong(ret);
660 }
661 
662 static PyMethodDef PyUpb_ByNumberMap_Methods[] = {
663  {"get", (PyCFunction)&PyUpb_ByNumberMap_Get, METH_VARARGS},
664  {"keys", PyUpb_ByNumberMap_Keys, METH_NOARGS},
665  {"values", PyUpb_ByNumberMap_Values, METH_NOARGS},
666  {"items", PyUpb_ByNumberMap_Items, METH_NOARGS},
667  {NULL}};
668 
669 static PyType_Slot PyUpb_ByNumberMap_Slots[] = {
670  {Py_mp_ass_subscript, PyUpb_ByNumberMap_AssignSubscript},
671  {Py_mp_length, PyUpb_ByNumberMap_Length},
672  {Py_mp_subscript, PyUpb_ByNumberMap_Subscript},
673  {Py_sq_contains, &PyUpb_ByNumberMap_Contains},
674  {Py_tp_dealloc, &PyUpb_ByNumberMap_Dealloc},
675  {Py_tp_iter, PyUpb_ByNumberMap_GetIter},
676  {Py_tp_methods, &PyUpb_ByNumberMap_Methods},
677  {Py_tp_richcompare, &PyUpb_ByNumberMap_RichCompare},
678  {0, NULL},
679 };
680 
681 static PyType_Spec PyUpb_ByNumberMap_Spec = {
682  PYUPB_MODULE_NAME "._ByNumberMap", // tp_name
683  sizeof(PyUpb_ByNumberMap), // tp_basicsize
684  0, // tp_itemsize
685  Py_TPFLAGS_DEFAULT, // tp_flags
687 };
688 
689 // -----------------------------------------------------------------------------
690 // Top Level
691 // -----------------------------------------------------------------------------
692 
695 
696  s->by_name_map_type = PyUpb_AddClass(m, &PyUpb_ByNameMap_Spec);
697  s->by_number_map_type = PyUpb_AddClass(m, &PyUpb_ByNumberMap_Spec);
698  s->descriptor_iterator_type =
700  s->generic_sequence_type = PyUpb_AddClass(m, &PyUpb_GenericSequence_Spec);
701 
702  return s->by_name_map_type && s->by_number_map_type &&
703  s->descriptor_iterator_type && s->generic_sequence_type;
704 }
PyUpb_GenericSequence_Dealloc
static void PyUpb_GenericSequence_Dealloc(PyObject *_self)
Definition: descriptor_containers.c:110
PyUpb_GenericSequence_Length
static Py_ssize_t PyUpb_GenericSequence_Length(PyObject *_self)
Definition: descriptor_containers.c:128
PyUpb_ByNumberMap_Subscript
static PyObject * PyUpb_ByNumberMap_Subscript(PyObject *_self, PyObject *key)
Definition: descriptor_containers.c:524
PyUpb_GetStrData
const char * PyUpb_GetStrData(PyObject *obj)
Definition: upb/python/protobuf.c:295
obj
OPENSSL_EXPORT const ASN1_OBJECT * obj
Definition: x509.h:1671
PyUpb_ByNameMap_Get
static PyObject * PyUpb_ByNameMap_Get(PyObject *_self, PyObject *args)
Definition: descriptor_containers.c:331
PyUpb_DescriptorIterator::index
int index
Definition: descriptor_containers.c:43
PyUpb_GenericSequence_Methods
static PyMethodDef PyUpb_GenericSequence_Methods[]
Definition: descriptor_containers.c:236
PyUpb_ByNumberMap::PyObject_HEAD
PyObject_HEAD
Definition: descriptor_containers.c:480
PyUpb_ByNameMap_Items
static PyObject * PyUpb_ByNameMap_Items(PyObject *_self, PyObject *args)
Definition: descriptor_containers.c:392
PyUpb_ByNumberMap_Methods
static PyMethodDef PyUpb_ByNumberMap_Methods[]
Definition: descriptor_containers.c:662
PyUpb_ByNumberMap_AssignSubscript
static int PyUpb_ByNumberMap_AssignSubscript(PyObject *self, PyObject *key, PyObject *value)
Definition: descriptor_containers.c:535
PyUpb_ByNameMap::PyObject_HEAD
PyObject_HEAD
Definition: descriptor_containers.c:271
PyUpb_ByNameMap_Self
PyUpb_ByNameMap * PyUpb_ByNameMap_Self(PyObject *obj)
Definition: descriptor_containers.c:277
position
intern position
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/array.c:487
PyUpb_GenericSequence::PyObject_HEAD
PyObject_HEAD
Definition: descriptor_containers.c:99
elem
Timer elem
Definition: event_engine/iomgr_event_engine/timer_heap_test.cc:109
error
grpc_error_handle error
Definition: retry_filter.cc:499
PyUpb_DescriptorIterator::parent
const void * parent
Definition: descriptor_containers.c:41
PyUpb_ByNumberMap_Contains
static int PyUpb_ByNumberMap_Contains(PyObject *_self, PyObject *key)
Definition: descriptor_containers.c:626
PyUpb_DescriptorIterator::funcs
const PyUpb_GenericSequence_Funcs * funcs
Definition: descriptor_containers.c:40
PyUpb_ByNumberMap_RichCompare
static PyObject * PyUpb_ByNumberMap_RichCompare(PyObject *_self, PyObject *other, int opid)
Definition: descriptor_containers.c:651
PyUpb_GenericSequence_Spec
static PyType_Spec PyUpb_GenericSequence_Spec
Definition: descriptor_containers.c:258
PyUpb_GenericSequence_Slots
static PyType_Slot PyUpb_GenericSequence_Slots[]
Definition: descriptor_containers.c:244
PyUpb_ModuleState_GetFromModule
PyUpb_ModuleState * PyUpb_ModuleState_GetFromModule(PyObject *module)
Definition: upb/python/protobuf.c:82
setup.name
name
Definition: setup.py:542
PyUpb_GenericSequence_New
PyObject * PyUpb_GenericSequence_New(const PyUpb_GenericSequence_Funcs *funcs, const void *parent, PyObject *parent_obj)
Definition: descriptor_containers.c:116
PyUpb_ByNameMap::funcs
const PyUpb_ByNameMap_Funcs * funcs
Definition: descriptor_containers.c:272
map
zval * map
Definition: php/ext/google/protobuf/encode_decode.c:480
PyUpb_ByNameMap_Values
static PyObject * PyUpb_ByNameMap_Values(PyObject *_self, PyObject *args)
Definition: descriptor_containers.c:374
PyUpb_GenericSequence
Definition: descriptor_containers.c:98
PyUpb_ByNumberMap_Self
PyUpb_ByNumberMap * PyUpb_ByNumberMap_Self(PyObject *obj)
Definition: descriptor_containers.c:486
PyUpb_GenericSequence_Find
static int PyUpb_GenericSequence_Find(PyObject *_self, PyObject *item)
Definition: descriptor_containers.c:196
PyUpb_GenericSequence_Self
PyUpb_GenericSequence * PyUpb_GenericSequence_Self(PyObject *obj)
Definition: descriptor_containers.c:105
PyUpb_ByNameMap_Keys
static PyObject * PyUpb_ByNameMap_Keys(PyObject *_self, PyObject *args)
Definition: descriptor_containers.c:356
PyUpb_GenericSequence_RichCompare
static PyObject * PyUpb_GenericSequence_RichCompare(PyObject *_self, PyObject *other, int opid)
Definition: descriptor_containers.c:183
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
PyUpb_InitDescriptorContainers
bool PyUpb_InitDescriptorContainers(PyObject *m)
Definition: descriptor_containers.c:693
PyUpb_Dealloc
static void PyUpb_Dealloc(void *self)
Definition: upb/python/protobuf.h:208
PyUpb_GenericSequence_GetItem
static PyObject * PyUpb_GenericSequence_GetItem(PyObject *_self, Py_ssize_t index)
Definition: descriptor_containers.c:133
PyUpb_GenericSequence_Append
static PyObject * PyUpb_GenericSequence_Append(PyObject *self, PyObject *args)
Definition: descriptor_containers.c:231
PyUpb_ByNameMap_RichCompare
static PyObject * PyUpb_ByNameMap_RichCompare(PyObject *_self, PyObject *other, int opid)
Definition: descriptor_containers.c:437
PyUpb_ByNameMap_Slots
static PyType_Slot PyUpb_ByNameMap_Slots[]
Definition: descriptor_containers.c:455
descriptor_containers.h
PyUpb_ByNumberMap_Funcs
Definition: upb/python/descriptor_containers.h:97
descriptor.h
PyUpb_ByNumberMap::parent_obj
PyObject * parent_obj
Definition: descriptor_containers.c:483
PyUpb_DescriptorIterator_Self
PyUpb_DescriptorIterator * PyUpb_DescriptorIterator_Self(PyObject *obj)
Definition: descriptor_containers.c:46
PyUpb_ByNumberMap
Definition: descriptor_containers.c:479
PyUpb_ByNameMap_Dealloc
static void PyUpb_ByNameMap_Dealloc(PyObject *_self)
Definition: descriptor_containers.c:282
number
int32_t number
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:850
PyUpb_AddClass
PyTypeObject * PyUpb_AddClass(PyObject *m, PyType_Spec *spec)
Definition: upb/python/protobuf.c:274
PyUpb_ByNumberMap_Keys
static PyObject * PyUpb_ByNumberMap_Keys(PyObject *_self, PyObject *args)
Definition: descriptor_containers.c:564
PyUpb_ByNumberMap_Spec
static PyType_Spec PyUpb_ByNumberMap_Spec
Definition: descriptor_containers.c:681
tests.google.protobuf.internal.message_test.cmp
cmp
Definition: bloaty/third_party/protobuf/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/message_test.py:61
PyUpb_ByNumberMap_GetIter
static PyObject * PyUpb_ByNumberMap_GetIter(PyObject *_self)
Definition: descriptor_containers.c:558
PyUpb_ByNameMap_Funcs
Definition: upb/python/descriptor_containers.h:76
protobuf.h
PyUpb_ByNameMap_New
PyObject * PyUpb_ByNameMap_New(const PyUpb_ByNameMap_Funcs *funcs, const void *parent, PyObject *parent_obj)
Definition: descriptor_containers.c:288
PyUpb_ByNumberMap_New
PyObject * PyUpb_ByNumberMap_New(const PyUpb_ByNumberMap_Funcs *funcs, const void *parent, PyObject *parent_obj)
Definition: descriptor_containers.c:491
PyUpb_ByNumberMap_Items
static PyObject * PyUpb_ByNumberMap_Items(PyObject *_self, PyObject *args)
Definition: descriptor_containers.c:600
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
PyUpb_ByNameMap_GetIter
static PyObject * PyUpb_ByNameMap_GetIter(PyObject *_self)
Definition: descriptor_containers.c:350
PyUpb_NewRef
static PyObject * PyUpb_NewRef(PyObject *obj)
Definition: upb/python/protobuf.h:219
PyUpb_GenericSequence::funcs
const PyUpb_GenericSequence_Funcs * funcs
Definition: descriptor_containers.c:100
value
const char * value
Definition: hpack_parser_table.cc:165
PyUpb_ModuleState_Get
PyUpb_ModuleState * PyUpb_ModuleState_Get(void)
Definition: upb/python/protobuf.c:89
PyUpb_GenericSequence_Index
static PyObject * PyUpb_GenericSequence_Index(PyObject *self, PyObject *item)
Definition: descriptor_containers.c:208
PyUpb_DescriptorIterator_Spec
static PyType_Spec PyUpb_DescriptorIterator_Spec
Definition: descriptor_containers.c:86
PyUpb_DescriptorIterator_IterNext
PyObject * PyUpb_DescriptorIterator_IterNext(PyObject *_self)
Definition: descriptor_containers.c:71
absl::compare_internal::eq
eq
Definition: abseil-cpp/absl/types/compare.h:72
PyUpb_ByNumberMap_Values
static PyObject * PyUpb_ByNumberMap_Values(PyObject *_self, PyObject *args)
Definition: descriptor_containers.c:582
PyUpb_ByNameMap::parent
const void * parent
Definition: descriptor_containers.c:273
key
const char * key
Definition: hpack_parser_table.cc:164
PYUPB_MODULE_NAME
#define PYUPB_MODULE_NAME
Definition: upb/python/protobuf.h:43
PyUpb_GenericSequence_Funcs
Definition: upb/python/descriptor_containers.h:54
PyUpb_ByNameMap_Methods
static PyMethodDef PyUpb_ByNameMap_Methods[]
Definition: descriptor_containers.c:448
PyUpb_DescriptorIterator_New
PyObject * PyUpb_DescriptorIterator_New(const PyUpb_GenericSequence_Funcs *funcs, const void *parent, PyObject *parent_obj)
Definition: descriptor_containers.c:57
def.h
count
int * count
Definition: bloaty/third_party/googletest/googlemock/test/gmock_stress_test.cc:96
PyUpb_GenericSequence::parent
const void * parent
Definition: descriptor_containers.c:101
PyUpb_ByNameMap_AssignSubscript
static int PyUpb_ByNameMap_AssignSubscript(PyObject *self, PyObject *key, PyObject *value)
Definition: descriptor_containers.c:317
PyUpb_ByNameMap_Spec
static PyType_Spec PyUpb_ByNameMap_Spec
Definition: descriptor_containers.c:467
PyUpb_ModuleState
Definition: upb/python/protobuf.h:66
index
int index
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:1184
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
PyUpb_DescriptorIterator_Slots
static PyType_Slot PyUpb_DescriptorIterator_Slots[]
Definition: descriptor_containers.c:80
PyUpb_ByNumberMap_Length
static Py_ssize_t PyUpb_ByNumberMap_Length(PyObject *_self)
Definition: descriptor_containers.c:508
PyUpb_GenericSequence_IsEqual
static int PyUpb_GenericSequence_IsEqual(PyUpb_GenericSequence *self, PyObject *other)
Definition: descriptor_containers.c:148
PyUpb_DescriptorIterator_Dealloc
static void PyUpb_DescriptorIterator_Dealloc(PyObject *_self)
Definition: descriptor_containers.c:51
PyUpb_ByNameMap::parent_obj
PyObject * parent_obj
Definition: descriptor_containers.c:274
PyUpb_ByNameMap_IsEqual
static int PyUpb_ByNameMap_IsEqual(PyUpb_ByNameMap *self, PyObject *other)
Definition: descriptor_containers.c:421
PyUpb_ByNameMap_Length
static Py_ssize_t PyUpb_ByNameMap_Length(PyObject *_self)
Definition: descriptor_containers.c:299
xds_manager.num
num
Definition: xds_manager.py:56
PyUpb_ByNumberMap::funcs
const PyUpb_ByNumberMap_Funcs * funcs
Definition: descriptor_containers.c:481
PyUpb_ByNumberMap::parent
const void * parent
Definition: descriptor_containers.c:482
PyUpb_ByNameMap_Subscript
static PyObject * PyUpb_ByNameMap_Subscript(PyObject *_self, PyObject *key)
Definition: descriptor_containers.c:304
PyUpb_AnyDescriptor_GetDef
const void * PyUpb_AnyDescriptor_GetDef(PyObject *desc)
Definition: descriptor.c:56
PyUpb_ByNumberMap_Get
static PyObject * PyUpb_ByNumberMap_Get(PyObject *_self, PyObject *args)
Definition: descriptor_containers.c:542
PyUpb_GenericSequence_Count
static PyObject * PyUpb_GenericSequence_Count(PyObject *_self, PyObject *item)
Definition: descriptor_containers.c:218
PyUpb_GenericSequence::parent_obj
PyObject * parent_obj
Definition: descriptor_containers.c:102
iter
Definition: test_winkernel.cpp:47
Py_TYPE
#define Py_TYPE(ob)
Definition: bloaty/third_party/protobuf/python/google/protobuf/pyext/descriptor.cc:164
PyUpb_ByNameMap
Definition: descriptor_containers.c:270
PyUpb_ByNumberMap_IsEqual
static int PyUpb_ByNumberMap_IsEqual(PyUpb_ByNumberMap *self, PyObject *other)
Definition: descriptor_containers.c:635
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
PyUpb_DescriptorIterator
Definition: descriptor_containers.c:38
PyUpb_ByNumberMap_Slots
static PyType_Slot PyUpb_ByNumberMap_Slots[]
Definition: descriptor_containers.c:669
self
PHP_PROTO_OBJECT_FREE_END PHP_PROTO_OBJECT_DTOR_END intern self
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/map.c:543
regress.m
m
Definition: regress/regress.py:25
PyUpb_ByNameMap_Contains
static int PyUpb_ByNameMap_Contains(PyObject *_self, PyObject *key)
Definition: descriptor_containers.c:324
PyUpb_ByNumberMap_LookupHelper
static const void * PyUpb_ByNumberMap_LookupHelper(PyUpb_ByNumberMap *self, PyObject *key)
Definition: descriptor_containers.c:513
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
PyUpb_DescriptorIterator::parent_obj
PyObject * parent_obj
Definition: descriptor_containers.c:42
PyUpb_DescriptorIterator::PyObject_HEAD
PyObject_HEAD
Definition: descriptor_containers.c:39
PyUpb_ByNumberMap_Dealloc
static void PyUpb_ByNumberMap_Dealloc(PyObject *_self)
Definition: descriptor_containers.c:502


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:14