11 #if PY_VERSION_HEX >= 0x03040000 12 #define _COLLECTIONS_ABC "_collections_abc" 13 #elif PY_VERSION_HEX >= 0x03030000 14 #define _COLLECTIONS_ABC "collections.abc" 16 #define _COLLECTIONS_ABC "_abcoll" 19 static void _register_collection(PyTypeObject *type,
const char *abc) {
20 PyObject *sys_modules = PyImport_GetModuleDict();
21 if (sys_modules !=
nullptr) {
22 PyObject *module = PyDict_GetItemString(sys_modules, _COLLECTIONS_ABC);
23 if (module !=
nullptr) {
24 PyObject *dict = PyModule_GetDict(module);
25 if (module !=
nullptr) {
26 #if PY_MAJOR_VERSION >= 3 27 static PyObject *register_str = PyUnicode_InternFromString(
"register");
29 static PyObject *register_str = PyString_InternFromString(
"register");
31 PyObject *sequence = PyDict_GetItemString(dict, abc);
32 if (sequence !=
nullptr) {
33 if (PyObject_CallMethodObjArgs(sequence, register_str, (PyObject *)type,
nullptr) ==
nullptr) {
46 static void Dtool_WrapperBase_dealloc(PyObject *
self) {
47 Dtool_WrapperBase *wrap = (Dtool_WrapperBase *)
self;
49 Py_XDECREF(wrap->_self);
52 static PyObject *Dtool_WrapperBase_repr(PyObject *
self) {
53 Dtool_WrapperBase *wrap = (Dtool_WrapperBase *)
self;
54 nassertr(wrap,
nullptr);
56 PyObject *repr = PyObject_Repr(wrap->_self);
58 #if PY_MAJOR_VERSION >= 3 59 result = PyUnicode_FromFormat(
"<%s[] of %s>", wrap->_name, PyUnicode_AsUTF8(repr));
61 result = PyString_FromFormat(
"<%s[] of %s>", wrap->_name, PyString_AS_STRING(repr));
67 static PyObject *Dtool_SequenceWrapper_repr(PyObject *
self) {
68 Dtool_SequenceWrapper *wrap = (Dtool_SequenceWrapper *)
self;
69 nassertr(wrap,
nullptr);
72 if (wrap->_len_func !=
nullptr) {
73 len = wrap->_len_func(wrap->_base._self);
77 PyErr_Restore(
nullptr,
nullptr,
nullptr);
78 return Dtool_WrapperBase_repr(
self);
81 PyObject *repr = PyObject_Repr(wrap->_base._self);
83 #if PY_MAJOR_VERSION >= 3 84 result = PyUnicode_FromFormat(
"<%s[%zd] of %s>", wrap->_base._name, len, PyUnicode_AsUTF8(repr));
86 result = PyString_FromFormat(
"<%s[%zd] of %s>", wrap->_base._name, len, PyString_AS_STRING(repr));
92 static Py_ssize_t Dtool_SequenceWrapper_length(PyObject *
self) {
93 Dtool_SequenceWrapper *wrap = (Dtool_SequenceWrapper *)
self;
95 if (wrap->_len_func !=
nullptr) {
96 return wrap->_len_func(wrap->_base._self);
98 Dtool_Raise_TypeError(
"property does not support len()");
103 static PyObject *Dtool_SequenceWrapper_getitem(PyObject *
self, Py_ssize_t index) {
104 Dtool_SequenceWrapper *wrap = (Dtool_SequenceWrapper *)
self;
105 nassertr(wrap,
nullptr);
106 nassertr(wrap->_getitem_func,
nullptr);
107 return wrap->_getitem_func(wrap->_base._self, index);
113 static int Dtool_SequenceWrapper_contains(PyObject *
self, PyObject *value) {
114 Dtool_SequenceWrapper *wrap = (Dtool_SequenceWrapper *)
self;
116 nassertr(wrap->_len_func, -1);
117 nassertr(wrap->_getitem_func, -1);
119 Py_ssize_t length = wrap->_len_func(wrap->_base._self);
123 for (Py_ssize_t index = 0; index < length; ++index) {
124 PyObject *item = wrap->_getitem_func(wrap->_base._self, index);
125 if (item !=
nullptr) {
126 int cmp = PyObject_RichCompareBool(item, value, Py_EQ);
144 static PyObject *Dtool_SequenceWrapper_index(PyObject *
self, PyObject *value) {
145 Dtool_SequenceWrapper *wrap = (Dtool_SequenceWrapper *)
self;
146 nassertr(wrap,
nullptr);
147 nassertr(wrap->_len_func,
nullptr);
148 nassertr(wrap->_getitem_func,
nullptr);
150 Py_ssize_t length = wrap->_len_func(wrap->_base._self);
154 for (Py_ssize_t index = 0; index < length; ++index) {
155 PyObject *item = wrap->_getitem_func(wrap->_base._self, index);
156 if (item !=
nullptr) {
157 int cmp = PyObject_RichCompareBool(item, value, Py_EQ);
169 return PyErr_Format(PyExc_ValueError,
"%s.index() did not find value", wrap->_base._name);
176 static PyObject *Dtool_SequenceWrapper_count(PyObject *
self, PyObject *value) {
177 Dtool_SequenceWrapper *wrap = (Dtool_SequenceWrapper *)
self;
178 nassertr(wrap,
nullptr);
179 Py_ssize_t index = 0;
180 if (wrap->_len_func !=
nullptr) {
181 index = wrap->_len_func(wrap->_base._self);
183 return Dtool_Raise_TypeError(
"property does not support count()");
187 nassertr(wrap->_getitem_func,
nullptr);
190 PyObject *item = wrap->_getitem_func(wrap->_base._self, index);
191 if (item ==
nullptr) {
194 int cmp = PyObject_RichCompareBool(item, value, Py_EQ);
202 #if PY_MAJOR_VERSION >= 3 203 return PyLong_FromLong(count);
205 return PyInt_FromLong(count);
212 static int Dtool_MutableSequenceWrapper_setitem(PyObject *
self, Py_ssize_t index, PyObject *value) {
213 Dtool_MutableSequenceWrapper *wrap = (Dtool_MutableSequenceWrapper *)
self;
215 if (wrap->_setitem_func !=
nullptr) {
216 return wrap->_setitem_func(wrap->_base._self, index, value);
218 Dtool_Raise_TypeError(
"property does not support item assignment");
227 static PyObject *Dtool_MutableSequenceWrapper_clear(PyObject *
self, PyObject *) {
228 Dtool_MutableSequenceWrapper *wrap = (Dtool_MutableSequenceWrapper *)
self;
229 nassertr(wrap,
nullptr);
230 Py_ssize_t index = 0;
231 if (wrap->_len_func !=
nullptr && wrap->_setitem_func !=
nullptr) {
232 index = wrap->_len_func(wrap->_base._self);
234 return Dtool_Raise_TypeError(
"property does not support clear()");
241 if (wrap->_setitem_func(wrap->_base._self, index,
nullptr) != 0) {
253 static PyObject *Dtool_MutableSequenceWrapper_remove(PyObject *
self, PyObject *value) {
254 Dtool_MutableSequenceWrapper *wrap = (Dtool_MutableSequenceWrapper *)
self;
255 nassertr(wrap,
nullptr);
256 Py_ssize_t length = 0;
257 if (wrap->_len_func !=
nullptr && wrap->_setitem_func !=
nullptr) {
258 length = wrap->_len_func(wrap->_base._self);
260 return Dtool_Raise_TypeError(
"property does not support remove()");
265 nassertr(wrap->_getitem_func,
nullptr);
266 for (Py_ssize_t index = 0; index < length; ++index) {
267 PyObject *item = wrap->_getitem_func(wrap->_base._self, index);
268 if (item !=
nullptr) {
269 int cmp = PyObject_RichCompareBool(item, value, Py_EQ);
271 if (wrap->_setitem_func(wrap->_base._self, index,
nullptr) == 0) {
286 return PyErr_Format(PyExc_ValueError,
"%s.remove() did not find value", wrap->_base._name);
294 static PyObject *Dtool_MutableSequenceWrapper_pop(PyObject *
self, PyObject *args) {
295 Dtool_MutableSequenceWrapper *wrap = (Dtool_MutableSequenceWrapper *)
self;
296 nassertr(wrap,
nullptr);
297 if (wrap->_getitem_func ==
nullptr || wrap->_setitem_func ==
nullptr ||
298 wrap->_len_func ==
nullptr) {
299 return Dtool_Raise_TypeError(
"property does not support pop()");
302 Py_ssize_t length = wrap->_len_func(wrap->_base._self);
304 switch (PyTuple_GET_SIZE(args)) {
309 index = PyNumber_AsSsize_t(PyTuple_GET_ITEM(args, 0), PyExc_IndexError);
310 if (index == -1 && _PyErr_OCCURRED()) {
318 return Dtool_Raise_TypeError(
"pop([i=-1]) takes 0 or 1 arguments");
322 return PyErr_Format(PyExc_IndexError,
"%s.pop() from empty sequence", wrap->_base._name);
326 PyObject *value = wrap->_getitem_func(wrap->_base._self, index);
327 if (value !=
nullptr) {
328 if (wrap->_setitem_func(wrap->_base._self, index,
nullptr) != 0) {
340 static PyObject *Dtool_MutableSequenceWrapper_append(PyObject *
self, PyObject *arg) {
341 Dtool_MutableSequenceWrapper *wrap = (Dtool_MutableSequenceWrapper *)
self;
342 nassertr(wrap,
nullptr);
343 if (wrap->_insert_func ==
nullptr) {
344 return Dtool_Raise_TypeError(
"property does not support append()");
346 return wrap->_insert_func(wrap->_base._self, (
size_t)-1, arg);
353 static PyObject *Dtool_MutableSequenceWrapper_insert(PyObject *
self, PyObject *args) {
354 Dtool_MutableSequenceWrapper *wrap = (Dtool_MutableSequenceWrapper *)
self;
355 nassertr(wrap,
nullptr);
356 if (wrap->_insert_func ==
nullptr) {
357 return Dtool_Raise_TypeError(
"property does not support insert()");
359 if (PyTuple_GET_SIZE(args) != 2) {
360 return Dtool_Raise_TypeError(
"insert() takes exactly 2 arguments");
362 Py_ssize_t index = PyNumber_AsSsize_t(PyTuple_GET_ITEM(args, 0), PyExc_IndexError);
363 if (index == -1 && _PyErr_OCCURRED()) {
367 if (wrap->_len_func !=
nullptr) {
368 index += wrap->_len_func(wrap->_base._self);
370 return PyErr_Format(PyExc_TypeError,
"%s.insert() does not support negative indices", wrap->_base._name);
373 return wrap->_insert_func(wrap->_base._self, (ssize_t)std::max(index, (Py_ssize_t)0), PyTuple_GET_ITEM(args, 1));
383 static PyObject *Dtool_MutableSequenceWrapper_extend(PyObject *
self, PyObject *arg) {
384 Dtool_MutableSequenceWrapper *wrap = (Dtool_MutableSequenceWrapper *)
self;
385 nassertr(wrap,
nullptr);
386 if (wrap->_insert_func ==
nullptr) {
387 return Dtool_Raise_TypeError(
"property does not support extend()");
389 PyObject *iter = PyObject_GetIter(arg);
390 if (iter ==
nullptr) {
393 PyObject *next = PyIter_Next(iter);
394 PyObject *retval =
nullptr;
395 while (next !=
nullptr) {
396 retval = wrap->_insert_func(wrap->_base._self, (
size_t)-1, next);
398 if (retval ==
nullptr) {
403 next = PyIter_Next(iter);
414 static int Dtool_MappingWrapper_contains(PyObject *
self, PyObject *key) {
415 Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)
self;
417 nassertr(wrap->_getitem_func, -1);
418 PyObject *value = wrap->_getitem_func(wrap->_base._self, key);
419 if (value !=
nullptr) {
422 }
else if (_PyErr_OCCURRED() == PyExc_KeyError ||
423 _PyErr_OCCURRED() == PyExc_TypeError) {
424 PyErr_Restore(
nullptr,
nullptr,
nullptr);
431 static PyObject *Dtool_MappingWrapper_getitem(PyObject *
self, PyObject *key) {
432 Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)
self;
433 nassertr(wrap,
nullptr);
434 nassertr(wrap->_getitem_func,
nullptr);
435 return wrap->_getitem_func(wrap->_base._self, key);
442 static PyObject *Dtool_MappingWrapper_iter(PyObject *
self) {
443 Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)
self;
444 nassertr(wrap,
nullptr);
446 if (wrap->_keys._len_func ==
nullptr || wrap->_keys._getitem_func ==
nullptr) {
447 return PyErr_Format(PyExc_TypeError,
"%s is not iterable", wrap->_base._name);
450 Dtool_SequenceWrapper *keys = Dtool_NewSequenceWrapper(wrap->_base._self, wrap->_base._name);
451 if (keys !=
nullptr) {
452 keys->_len_func = wrap->_keys._len_func;
453 keys->_getitem_func = wrap->_keys._getitem_func;
454 return PySeqIter_New((PyObject *)keys);
465 static PyObject *Dtool_MappingWrapper_get(PyObject *
self, PyObject *args) {
466 Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)
self;
467 nassertr(wrap,
nullptr);
468 nassertr(wrap->_getitem_func,
nullptr);
469 Py_ssize_t size = PyTuple_GET_SIZE(args);
470 if (size != 1 && size != 2) {
471 return PyErr_Format(PyExc_TypeError,
"%s.get() takes 1 or 2 arguments", wrap->_base._name);
473 PyObject *defvalue = Py_None;
475 defvalue = PyTuple_GET_ITEM(args, 1);
477 PyObject *key = PyTuple_GET_ITEM(args, 0);
478 PyObject *value = wrap->_getitem_func(wrap->_base._self, key);
479 if (value !=
nullptr) {
481 }
else if (_PyErr_OCCURRED() == PyExc_KeyError) {
482 PyErr_Restore(
nullptr,
nullptr,
nullptr);
493 static PyObject *Dtool_MappingWrapper_Keys_repr(PyObject *
self) {
494 Dtool_WrapperBase *wrap = (Dtool_WrapperBase *)
self;
495 nassertr(wrap,
nullptr);
497 PyObject *repr = PyObject_Repr(wrap->_self);
499 #if PY_MAJOR_VERSION >= 3 500 result = PyUnicode_FromFormat(
"<%s.keys() of %s>", wrap->_name, PyUnicode_AsUTF8(repr));
502 result = PyString_FromFormat(
"<%s.keys() of %s>", wrap->_name, PyString_AS_STRING(repr));
511 static PyObject *Dtool_MappingWrapper_keys(PyObject *
self, PyObject *) {
512 Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)
self;
513 nassertr(wrap,
nullptr);
515 if (wrap->_keys._len_func ==
nullptr || wrap->_keys._getitem_func ==
nullptr) {
516 return Dtool_Raise_TypeError(
"property does not support keys()");
519 Dtool_MappingWrapper *keys = (Dtool_MappingWrapper *)PyObject_MALLOC(
sizeof(Dtool_MappingWrapper));
520 if (keys ==
nullptr) {
521 return PyErr_NoMemory();
524 static PySequenceMethods seq_methods = {
525 Dtool_SequenceWrapper_length,
528 Dtool_SequenceWrapper_getitem,
532 Dtool_SequenceWrapper_contains,
537 static PyTypeObject wrapper_type = {
538 PyVarObject_HEAD_INIT(
nullptr, 0)
540 sizeof(Dtool_SequenceWrapper),
542 Dtool_WrapperBase_dealloc,
547 Dtool_MappingWrapper_Keys_repr,
554 PyObject_GenericGetAttr,
555 PyObject_GenericSetAttr,
557 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES,
586 static bool registered =
false;
590 if (PyType_Ready(&wrapper_type) < 0) {
595 _register_collection((PyTypeObject *)&wrapper_type,
"MappingView");
598 (void)PyObject_INIT(keys, &wrapper_type);
599 Py_XINCREF(wrap->_base._self);
600 keys->_base._self = wrap->_base._self;
601 keys->_base._name = wrap->_base._name;
602 keys->_keys._len_func = wrap->_keys._len_func;
603 keys->_keys._getitem_func = wrap->_keys._getitem_func;
604 keys->_getitem_func = wrap->_getitem_func;
605 keys->_setitem_func =
nullptr;
606 return (PyObject *)keys;
612 static PyObject *Dtool_MappingWrapper_Values_repr(PyObject *
self) {
613 Dtool_WrapperBase *wrap = (Dtool_WrapperBase *)
self;
614 nassertr(wrap,
nullptr);
616 PyObject *repr = PyObject_Repr(wrap->_self);
618 #if PY_MAJOR_VERSION >= 3 619 result = PyUnicode_FromFormat(
"<%s.values() of %s>", wrap->_name, PyUnicode_AsUTF8(repr));
621 result = PyString_FromFormat(
"<%s.values() of %s>", wrap->_name, PyString_AS_STRING(repr));
627 static PyObject *Dtool_MappingWrapper_Values_getitem(PyObject *
self, Py_ssize_t index) {
628 Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)
self;
629 nassertr(wrap,
nullptr);
630 nassertr(wrap->_keys._getitem_func,
nullptr);
632 PyObject *key = wrap->_keys._getitem_func(wrap->_base._self, index);
633 if (key !=
nullptr) {
634 PyObject *value = wrap->_getitem_func(wrap->_base._self, key);
644 static PyObject *Dtool_MappingWrapper_values(PyObject *
self, PyObject *) {
645 Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)
self;
646 nassertr(wrap,
nullptr);
647 nassertr(wrap->_getitem_func,
nullptr);
649 if (wrap->_keys._len_func ==
nullptr || wrap->_keys._getitem_func ==
nullptr) {
650 return Dtool_Raise_TypeError(
"property does not support values()");
653 Dtool_MappingWrapper *values = (Dtool_MappingWrapper *)PyObject_MALLOC(
sizeof(Dtool_MappingWrapper));
654 if (values ==
nullptr) {
655 return PyErr_NoMemory();
658 static PySequenceMethods seq_methods = {
659 Dtool_SequenceWrapper_length,
662 Dtool_MappingWrapper_Values_getitem,
666 Dtool_MappingWrapper_contains,
671 static PyTypeObject wrapper_type = {
672 PyVarObject_HEAD_INIT(
nullptr, 0)
674 sizeof(Dtool_MappingWrapper),
676 Dtool_WrapperBase_dealloc,
681 Dtool_MappingWrapper_Values_repr,
688 PyObject_GenericGetAttr,
689 PyObject_GenericSetAttr,
691 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES,
720 static bool registered =
false;
724 if (PyType_Ready(&wrapper_type) < 0) {
729 _register_collection((PyTypeObject *)&wrapper_type,
"ValuesView");
732 (void)PyObject_INIT(values, &wrapper_type);
733 Py_XINCREF(wrap->_base._self);
734 values->_base._self = wrap->_base._self;
735 values->_base._name = wrap->_base._name;
736 values->_keys._len_func = wrap->_keys._len_func;
737 values->_keys._getitem_func = wrap->_keys._getitem_func;
738 values->_getitem_func = wrap->_getitem_func;
739 values->_setitem_func =
nullptr;
740 return (PyObject *)values;
746 static PyObject *Dtool_MappingWrapper_Items_repr(PyObject *
self) {
747 Dtool_WrapperBase *wrap = (Dtool_WrapperBase *)
self;
748 nassertr(wrap,
nullptr);
750 PyObject *repr = PyObject_Repr(wrap->_self);
752 #if PY_MAJOR_VERSION >= 3 753 result = PyUnicode_FromFormat(
"<%s.items() of %s>", wrap->_name, PyUnicode_AsUTF8(repr));
755 result = PyString_FromFormat(
"<%s.items() of %s>", wrap->_name, PyString_AS_STRING(repr));
761 static PyObject *Dtool_MappingWrapper_Items_getitem(PyObject *
self, Py_ssize_t index) {
762 Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)
self;
763 nassertr(wrap,
nullptr);
764 nassertr(wrap->_keys._getitem_func,
nullptr);
766 PyObject *key = wrap->_keys._getitem_func(wrap->_base._self, index);
767 if (key !=
nullptr) {
768 PyObject *value = wrap->_getitem_func(wrap->_base._self, key);
769 if (value !=
nullptr) {
771 PyObject *item = PyTuple_New(2);
772 PyTuple_SET_ITEM(item, 0, key);
773 PyTuple_SET_ITEM(item, 1, value);
786 static PyObject *Dtool_MappingWrapper_items(PyObject *
self, PyObject *) {
787 Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)
self;
788 nassertr(wrap,
nullptr);
789 nassertr(wrap->_getitem_func,
nullptr);
791 if (wrap->_keys._len_func ==
nullptr || wrap->_keys._getitem_func ==
nullptr) {
792 return Dtool_Raise_TypeError(
"property does not support items()");
795 Dtool_MappingWrapper *items = (Dtool_MappingWrapper *)PyObject_MALLOC(
sizeof(Dtool_MappingWrapper));
796 if (items ==
nullptr) {
797 return PyErr_NoMemory();
800 static PySequenceMethods seq_methods = {
801 Dtool_SequenceWrapper_length,
804 Dtool_MappingWrapper_Items_getitem,
808 Dtool_MappingWrapper_contains,
813 static PyTypeObject wrapper_type = {
814 PyVarObject_HEAD_INIT(
nullptr, 0)
816 sizeof(Dtool_MappingWrapper),
818 Dtool_WrapperBase_dealloc,
823 Dtool_MappingWrapper_Items_repr,
830 PyObject_GenericGetAttr,
831 PyObject_GenericSetAttr,
833 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES,
862 static bool registered =
false;
866 if (PyType_Ready(&wrapper_type) < 0) {
871 _register_collection((PyTypeObject *)&wrapper_type,
"MappingView");
874 (void)PyObject_INIT(items, &wrapper_type);
875 Py_XINCREF(wrap->_base._self);
876 items->_base._self = wrap->_base._self;
877 items->_base._name = wrap->_base._name;
878 items->_keys._len_func = wrap->_keys._len_func;
879 items->_keys._getitem_func = wrap->_keys._getitem_func;
880 items->_getitem_func = wrap->_getitem_func;
881 items->_setitem_func =
nullptr;
882 return (PyObject *)items;
888 static int Dtool_MutableMappingWrapper_setitem(PyObject *
self, PyObject *key, PyObject *value) {
889 Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)
self;
890 nassertr(wrap->_setitem_func !=
nullptr, -1);
891 return wrap->_setitem_func(wrap->_base._self, key, value);
898 static PyObject *Dtool_MutableMappingWrapper_pop(PyObject *
self, PyObject *args) {
899 Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)
self;
900 nassertr(wrap,
nullptr);
901 if (wrap->_getitem_func ==
nullptr || wrap->_setitem_func ==
nullptr) {
902 return Dtool_Raise_TypeError(
"property does not support pop()");
905 Py_ssize_t size = PyTuple_GET_SIZE(args);
906 if (size != 1 && size != 2) {
907 return PyErr_Format(PyExc_TypeError,
"%s.pop() takes 1 or 2 arguments", wrap->_base._name);
909 PyObject *defvalue = Py_None;
911 defvalue = PyTuple_GET_ITEM(args, 1);
914 PyObject *key = PyTuple_GET_ITEM(args, 0);
915 PyObject *value = wrap->_getitem_func(wrap->_base._self, key);
916 if (value !=
nullptr) {
918 if (wrap->_setitem_func(wrap->_base._self, key,
nullptr) == 0) {
924 }
else if (_PyErr_OCCURRED() == PyExc_KeyError) {
925 PyErr_Restore(
nullptr,
nullptr,
nullptr);
937 static PyObject *Dtool_MutableMappingWrapper_popitem(PyObject *
self, PyObject *) {
938 Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)
self;
939 nassertr(wrap,
nullptr);
940 if (wrap->_getitem_func ==
nullptr || wrap->_setitem_func ==
nullptr ||
941 wrap->_keys._len_func ==
nullptr || wrap->_keys._getitem_func ==
nullptr) {
942 return Dtool_Raise_TypeError(
"property does not support popitem()");
945 Py_ssize_t length = wrap->_keys._len_func(wrap->_base._self);
947 return PyErr_Format(PyExc_KeyError,
"%s is empty", wrap->_base._name);
950 PyObject *key = wrap->_keys._getitem_func(wrap->_base._self, length - 1);
951 if (key !=
nullptr) {
952 PyObject *value = wrap->_getitem_func(wrap->_base._self, key);
953 if (value !=
nullptr) {
955 if (wrap->_setitem_func(wrap->_base._self, key,
nullptr) == 0) {
956 PyObject *item = PyTuple_New(2);
957 PyTuple_SET_ITEM(item, 0, key);
958 PyTuple_SET_ITEM(item, 1, value);
971 static PyObject *Dtool_MutableMappingWrapper_clear(PyObject *
self, PyObject *) {
972 Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)
self;
973 nassertr(wrap,
nullptr);
974 Py_ssize_t index = 0;
975 if (wrap->_keys._len_func !=
nullptr && wrap->_keys._getitem_func !=
nullptr &&
976 wrap->_setitem_func !=
nullptr) {
977 index = wrap->_keys._len_func(wrap->_base._self);
979 return Dtool_Raise_TypeError(
"property does not support clear()");
986 PyObject *key = wrap->_keys._getitem_func(wrap->_base._self, index);
987 if (key !=
nullptr) {
988 int result = wrap->_setitem_func(wrap->_base._self, key,
nullptr);
1004 static PyObject *Dtool_MutableMappingWrapper_setdefault(PyObject *
self, PyObject *args) {
1005 Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)
self;
1006 nassertr(wrap,
nullptr);
1008 if (wrap->_getitem_func ==
nullptr || wrap->_setitem_func ==
nullptr) {
1009 return Dtool_Raise_TypeError(
"property does not support setdefault()");
1012 Py_ssize_t size = PyTuple_GET_SIZE(args);
1013 if (size != 1 && size != 2) {
1014 return PyErr_Format(PyExc_TypeError,
"%s.setdefault() takes 1 or 2 arguments", wrap->_base._name);
1016 PyObject *defvalue = Py_None;
1018 defvalue = PyTuple_GET_ITEM(args, 1);
1020 PyObject *key = PyTuple_GET_ITEM(args, 0);
1021 PyObject *value = wrap->_getitem_func(wrap->_base._self, key);
1022 if (value !=
nullptr) {
1024 }
else if (_PyErr_OCCURRED() == PyExc_KeyError) {
1025 PyErr_Restore(
nullptr,
nullptr,
nullptr);
1026 if (wrap->_setitem_func(wrap->_base._self, key, defvalue) == 0) {
1027 Py_INCREF(defvalue);
1038 static PyObject *Dtool_MutableMappingWrapper_update(PyObject *
self, PyObject *args, PyObject *kwargs) {
1039 Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)
self;
1040 nassertr(wrap,
nullptr);
1042 if (wrap->_getitem_func ==
nullptr || wrap->_setitem_func ==
nullptr) {
1043 return Dtool_Raise_TypeError(
"property does not support update()");
1048 switch (PyTuple_GET_SIZE(args)) {
1050 if (kwargs ==
nullptr) {
1058 if (PyDict_Check(PyTuple_GET_ITEM(args, 0)) && (kwargs ==
nullptr || Py_SIZE(kwargs) == 0)) {
1059 dict = PyTuple_GET_ITEM(args, 0);
1064 return PyErr_Format(PyExc_TypeError,
"%s.update() takes either a dict argument or keyword arguments", wrap->_base._name);
1067 PyObject *key, *value;
1069 while (PyDict_Next(dict, &pos, &key, &value)) {
1070 if (wrap->_setitem_func(wrap->_base._self, key, value) != 0) {
1081 static PyObject *Dtool_GeneratorWrapper_iternext(PyObject *
self) {
1082 Dtool_GeneratorWrapper *wrap = (Dtool_GeneratorWrapper *)
self;
1083 nassertr(wrap,
nullptr);
1084 nassertr(wrap->_iternext_func,
nullptr);
1085 return wrap->_iternext_func(wrap->_base._self);
1093 Dtool_StaticProperty_dealloc(PyDescrObject *descr) {
1094 _PyObject_GC_UNTRACK(descr);
1095 Py_XDECREF(descr->d_type);
1096 Py_XDECREF(descr->d_name);
1100 PyObject_GC_Del(descr);
1104 Dtool_StaticProperty_repr(PyDescrObject *descr,
const char *format) {
1105 #if PY_MAJOR_VERSION >= 3 1106 return PyUnicode_FromFormat(
"<attribute '%s' of '%s'>",
1107 PyUnicode_AsUTF8(descr->d_name),
1108 descr->d_type->tp_name);
1110 return PyString_FromFormat(
"<attribute '%s' of '%s'>",
1111 PyString_AS_STRING(descr->d_name),
1112 descr->d_type->tp_name);
1117 Dtool_StaticProperty_traverse(PyObject *
self, visitproc visit,
void *arg) {
1118 PyDescrObject *descr = (PyDescrObject *)
self;
1119 Py_VISIT(descr->d_type);
1124 Dtool_StaticProperty_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type) {
1125 if (descr->d_getset->get !=
nullptr) {
1126 return descr->d_getset->get(obj, descr->d_getset->closure);
1128 return PyErr_Format(PyExc_AttributeError,
1129 "attribute '%s' of type '%.100s' is not readable",
1130 #
if PY_MAJOR_VERSION >= 3
1131 PyUnicode_AsUTF8(((PyDescrObject *)descr)->d_name),
1133 PyString_AS_STRING(((PyDescrObject *)descr)->d_name),
1135 ((PyDescrObject *)descr)->d_type->tp_name);
1140 Dtool_StaticProperty_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) {
1141 if (descr->d_getset->set !=
nullptr) {
1142 return descr->d_getset->set(obj, value, descr->d_getset->closure);
1144 PyErr_Format(PyExc_AttributeError,
1145 "attribute '%s' of type '%.100s' is not writable",
1146 #
if PY_MAJOR_VERSION >= 3
1147 PyUnicode_AsUTF8(((PyDescrObject *)descr)->d_name),
1149 PyString_AS_STRING(((PyDescrObject *)descr)->d_name),
1151 ((PyDescrObject *)descr)->d_type->tp_name);
1159 Dtool_SequenceWrapper *Dtool_NewSequenceWrapper(PyObject *
self,
const char *name) {
1160 Dtool_SequenceWrapper *wrap = (Dtool_SequenceWrapper *)PyObject_MALLOC(
sizeof(Dtool_SequenceWrapper));
1161 if (wrap ==
nullptr) {
1162 return (Dtool_SequenceWrapper *)PyErr_NoMemory();
1165 static PySequenceMethods seq_methods = {
1166 Dtool_SequenceWrapper_length,
1169 Dtool_SequenceWrapper_getitem,
1173 Dtool_SequenceWrapper_contains,
1178 static PyMethodDef methods[] = {
1179 {
"index", &Dtool_SequenceWrapper_index, METH_O,
nullptr},
1180 {
"count", &Dtool_SequenceWrapper_count, METH_O,
nullptr},
1181 {
nullptr,
nullptr, 0,
nullptr}
1184 static PyTypeObject wrapper_type = {
1185 PyVarObject_HEAD_INIT(
nullptr, 0)
1187 sizeof(Dtool_SequenceWrapper),
1189 Dtool_WrapperBase_dealloc,
1194 Dtool_SequenceWrapper_repr,
1201 PyObject_GenericGetAttr,
1202 PyObject_GenericSetAttr,
1204 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES,
1221 PyType_GenericAlloc,
1233 static bool registered =
false;
1237 if (PyType_Ready(&wrapper_type) < 0) {
1242 _register_collection((PyTypeObject *)&wrapper_type,
"Sequence");
1245 (void)PyObject_INIT(wrap, &wrapper_type);
1247 wrap->_base._self =
self;
1248 wrap->_base._name = name;
1249 wrap->_len_func =
nullptr;
1250 wrap->_getitem_func =
nullptr;
1257 Dtool_MutableSequenceWrapper *Dtool_NewMutableSequenceWrapper(PyObject *
self,
const char *name) {
1258 Dtool_MutableSequenceWrapper *wrap = (Dtool_MutableSequenceWrapper *)PyObject_MALLOC(
sizeof(Dtool_MutableSequenceWrapper));
1259 if (wrap ==
nullptr) {
1260 return (Dtool_MutableSequenceWrapper *)PyErr_NoMemory();
1263 static PySequenceMethods seq_methods = {
1264 Dtool_SequenceWrapper_length,
1267 Dtool_SequenceWrapper_getitem,
1269 Dtool_MutableSequenceWrapper_setitem,
1271 Dtool_SequenceWrapper_contains,
1272 Dtool_MutableSequenceWrapper_extend,
1276 static PyMethodDef methods[] = {
1277 {
"index", &Dtool_SequenceWrapper_index, METH_O,
nullptr},
1278 {
"count", &Dtool_SequenceWrapper_count, METH_O,
nullptr},
1279 {
"clear", &Dtool_MutableSequenceWrapper_clear, METH_NOARGS,
nullptr},
1280 {
"pop", &Dtool_MutableSequenceWrapper_pop, METH_VARARGS,
nullptr},
1281 {
"remove", &Dtool_MutableSequenceWrapper_remove, METH_O,
nullptr},
1282 {
"append", &Dtool_MutableSequenceWrapper_append, METH_O,
nullptr},
1283 {
"insert", &Dtool_MutableSequenceWrapper_insert, METH_VARARGS,
nullptr},
1284 {
"extend", &Dtool_MutableSequenceWrapper_extend, METH_O,
nullptr},
1285 {
nullptr,
nullptr, 0,
nullptr}
1288 static PyTypeObject wrapper_type = {
1289 PyVarObject_HEAD_INIT(
nullptr, 0)
1291 sizeof(Dtool_MutableSequenceWrapper),
1293 Dtool_WrapperBase_dealloc,
1298 Dtool_SequenceWrapper_repr,
1305 PyObject_GenericGetAttr,
1306 PyObject_GenericSetAttr,
1308 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES,
1325 PyType_GenericAlloc,
1337 static bool registered =
false;
1341 if (PyType_Ready(&wrapper_type) < 0) {
1346 _register_collection((PyTypeObject *)&wrapper_type,
"MutableSequence");
1349 (void)PyObject_INIT(wrap, &wrapper_type);
1351 wrap->_base._self =
self;
1352 wrap->_base._name = name;
1353 wrap->_len_func =
nullptr;
1354 wrap->_getitem_func =
nullptr;
1355 wrap->_setitem_func =
nullptr;
1356 wrap->_insert_func =
nullptr;
1363 Dtool_MappingWrapper *Dtool_NewMappingWrapper(PyObject *
self,
const char *name) {
1364 Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)PyObject_MALLOC(
sizeof(Dtool_MappingWrapper));
1365 if (wrap ==
nullptr) {
1366 return (Dtool_MappingWrapper *)PyErr_NoMemory();
1369 static PySequenceMethods seq_methods = {
1370 Dtool_SequenceWrapper_length,
1377 Dtool_MappingWrapper_contains,
1382 static PyMappingMethods map_methods = {
1383 Dtool_SequenceWrapper_length,
1384 Dtool_MappingWrapper_getitem,
1388 static PyMethodDef methods[] = {
1389 {
"get", &Dtool_MappingWrapper_get, METH_VARARGS,
nullptr},
1390 {
"keys", &Dtool_MappingWrapper_keys, METH_NOARGS,
nullptr},
1391 {
"values", &Dtool_MappingWrapper_values, METH_NOARGS,
nullptr},
1392 {
"items", &Dtool_MappingWrapper_items, METH_NOARGS,
nullptr},
1393 {
nullptr,
nullptr, 0,
nullptr}
1396 static PyTypeObject wrapper_type = {
1397 PyVarObject_HEAD_INIT(
nullptr, 0)
1399 sizeof(Dtool_MappingWrapper),
1401 Dtool_WrapperBase_dealloc,
1406 Dtool_WrapperBase_repr,
1413 PyObject_GenericGetAttr,
1414 PyObject_GenericSetAttr,
1416 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES,
1422 Dtool_MappingWrapper_iter,
1433 PyType_GenericAlloc,
1445 static bool registered =
false;
1449 if (PyType_Ready(&wrapper_type) < 0) {
1454 _register_collection((PyTypeObject *)&wrapper_type,
"Mapping");
1457 (void)PyObject_INIT(wrap, &wrapper_type);
1459 wrap->_base._self =
self;
1460 wrap->_base._name = name;
1461 wrap->_keys._len_func =
nullptr;
1462 wrap->_keys._getitem_func =
nullptr;
1463 wrap->_getitem_func =
nullptr;
1464 wrap->_setitem_func =
nullptr;
1471 Dtool_MappingWrapper *Dtool_NewMutableMappingWrapper(PyObject *
self,
const char *name) {
1472 Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)PyObject_MALLOC(
sizeof(Dtool_MappingWrapper));
1473 if (wrap ==
nullptr) {
1474 return (Dtool_MappingWrapper *)PyErr_NoMemory();
1477 static PySequenceMethods seq_methods = {
1478 Dtool_SequenceWrapper_length,
1485 Dtool_MappingWrapper_contains,
1490 static PyMappingMethods map_methods = {
1491 Dtool_SequenceWrapper_length,
1492 Dtool_MappingWrapper_getitem,
1493 Dtool_MutableMappingWrapper_setitem,
1496 static PyMethodDef methods[] = {
1497 {
"get", &Dtool_MappingWrapper_get, METH_VARARGS,
nullptr},
1498 {
"pop", &Dtool_MutableMappingWrapper_pop, METH_VARARGS,
nullptr},
1499 {
"popitem", &Dtool_MutableMappingWrapper_popitem, METH_NOARGS,
nullptr},
1500 {
"clear", &Dtool_MutableMappingWrapper_clear, METH_VARARGS,
nullptr},
1501 {
"setdefault", &Dtool_MutableMappingWrapper_setdefault, METH_VARARGS,
nullptr},
1502 {
"update", (PyCFunction) &Dtool_MutableMappingWrapper_update, METH_VARARGS | METH_KEYWORDS,
nullptr},
1503 {
"keys", &Dtool_MappingWrapper_keys, METH_NOARGS,
nullptr},
1504 {
"values", &Dtool_MappingWrapper_values, METH_NOARGS,
nullptr},
1505 {
"items", &Dtool_MappingWrapper_items, METH_NOARGS,
nullptr},
1506 {
nullptr,
nullptr, 0,
nullptr}
1509 static PyTypeObject wrapper_type = {
1510 PyVarObject_HEAD_INIT(
nullptr, 0)
1512 sizeof(Dtool_MappingWrapper),
1514 Dtool_WrapperBase_dealloc,
1519 Dtool_WrapperBase_repr,
1526 PyObject_GenericGetAttr,
1527 PyObject_GenericSetAttr,
1529 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES,
1535 Dtool_MappingWrapper_iter,
1546 PyType_GenericAlloc,
1558 static bool registered =
false;
1562 if (PyType_Ready(&wrapper_type) < 0) {
1567 _register_collection((PyTypeObject *)&wrapper_type,
"MutableMapping");
1570 (void)PyObject_INIT(wrap, &wrapper_type);
1572 wrap->_base._self =
self;
1573 wrap->_base._name = name;
1574 wrap->_keys._len_func =
nullptr;
1575 wrap->_keys._getitem_func =
nullptr;
1576 wrap->_getitem_func =
nullptr;
1577 wrap->_setitem_func =
nullptr;
1585 Dtool_NewGenerator(PyObject *
self, iternextfunc gen_next) {
1586 static PyTypeObject wrapper_type = {
1587 PyVarObject_HEAD_INIT(
nullptr, 0)
1588 "generator wrapper",
1589 sizeof(Dtool_GeneratorWrapper),
1591 Dtool_WrapperBase_dealloc,
1603 PyObject_GenericGetAttr,
1604 PyObject_GenericSetAttr,
1606 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES,
1613 Dtool_GeneratorWrapper_iternext,
1623 PyType_GenericAlloc,
1635 if (PyType_Ready(&wrapper_type) < 0) {
1639 Dtool_GeneratorWrapper *gen;
1640 gen = (Dtool_GeneratorWrapper *)PyType_GenericAlloc(&wrapper_type, 0);
1641 if (gen !=
nullptr) {
1643 gen->_base._self =
self;
1644 gen->_iternext_func = gen_next;
1646 return (PyObject *)gen;
1654 Dtool_NewStaticProperty(PyTypeObject *type,
const PyGetSetDef *getset) {
1655 static PyTypeObject wrapper_type = {
1656 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1657 "getset_descriptor",
1658 sizeof(PyGetSetDescrObject),
1660 (destructor)Dtool_StaticProperty_dealloc,
1665 (reprfunc)Dtool_StaticProperty_repr,
1672 PyObject_GenericGetAttr,
1677 Dtool_StaticProperty_traverse,
1688 (descrgetfunc)Dtool_StaticProperty_get,
1689 (descrsetfunc)Dtool_StaticProperty_set,
1704 if (PyType_Ready(&wrapper_type) < 0) {
1708 PyGetSetDescrObject *descr;
1709 descr = (PyGetSetDescrObject *)PyType_GenericAlloc(&wrapper_type, 0);
1710 if (descr !=
nullptr) {
1712 descr->d_getset = (PyGetSetDef *)getset;
1713 #if PY_MAJOR_VERSION >= 3 1714 descr->d_common.d_type = type;
1715 descr->d_common.d_name = PyUnicode_InternFromString(getset->name);
1716 #if PY_VERSION_HEX >= 0x03030000 1717 descr->d_common.d_qualname =
nullptr;
1720 descr->d_type = type;
1721 descr->d_name = PyString_InternFromString(getset->name);
1724 return (PyObject *)descr;
1727 #endif // HAVE_PYTHON
PyObject * Dtool_WrapValue(int value)
The following functions wrap an arbitrary C++ value into a PyObject.