Box* setInit(Box* _self, Box* container, BoxedDict* kwargs) { RELEASE_ASSERT(PySet_Check(_self), ""); if (PySet_Check(_self) && !_PyArg_NoKeywords("set()", kwargs)) { throwCAPIException(); } if (!container) return incref(None); BoxedSet* self = static_cast<BoxedSet*>(_self); setClearInternal(self); if (PyAnySet_Check(container)) { for (auto&& elt : ((BoxedSet*)container)->s) { self->s.insert(incref(elt)); } } else if (PyDict_CheckExact(container)) { for (auto&& elt : ((BoxedDict*)container)->d) { self->s.insert(incref(elt.first)); } } else { for (auto elt : container->pyElements()) { _setAddStolen(self, elt); } } return incref(None); }
Box* setRemove(BoxedSet* self, Box* key) { RELEASE_ASSERT(isSubclass(self->cls, set_cls), ""); if (PySet_Check(key)) { try { bool existed = _setRemove(self, key); if (existed) return incref(None); } catch (ExcInfo e) { if (!e.matches(TypeError)) throw e; e.clear(); BoxedSet* tmpKey = makeNewSet(frozenset_cls, key); AUTO_DECREF(tmpKey); bool existed = _setRemove(self, tmpKey); if (existed) return incref(None); } raiseExcHelper(KeyError, key); } bool existed = _setRemove(self, key); if (existed) return incref(None); raiseExcHelper(KeyError, key); }
Box* setDifferenceUpdate(BoxedSet* self, BoxedTuple* args) { if (!PySet_Check(self)) raiseExcHelper(TypeError, "descriptor 'difference_update' requires a 'set' object but received a '%s'", getTypeName(self)); _setDifferenceUpdate(self, args); return incref(None); }
extern "C" int PySet_Clear(PyObject* set) noexcept { if (!PySet_Check(set)) { PyErr_BadInternalCall(); return -1; } setClearInternal(static_cast<BoxedSet*>(set)); return 0; }
Box* setSymmetricDifferenceUpdate(BoxedSet* self, Box* other) { if (!PySet_Check(self)) raiseExcHelper(TypeError, "descriptor 'symmetric_difference_update' requires a 'set' object but received a '%s'", getTypeName(self)); _setSymmetricDifferenceUpdate(self, other); return incref(None); }
bool from_python<types::set<T>>::is_convertible(PyObject *obj) { if (PySet_Check(obj)) { PyObject *iterator = PyObject_GetIter(obj); if (PyObject *item = PyIter_Next(iterator)) { bool res = ::is_convertible<T>(item); Py_DECREF(item); Py_DECREF(iterator); return res; } else { Py_DECREF(iterator); return true; } } return false; }
Box* setContains(BoxedSet* self, Box* key) { RELEASE_ASSERT(PyAnySet_Check(self), ""); if (PySet_Check(key)) { try { BoxAndHash k_hash(key); return boxBool(self->s.find(k_hash) != self->s.end()); } catch (ExcInfo e) { if (!e.matches(TypeError)) throw e; e.clear(); BoxedSet* tmpKey = makeNewSet(frozenset_cls, key); AUTO_DECREF(tmpKey); return boxBool(self->s.find(tmpKey) != self->s.end()); } } return boxBool(self->s.find(key) != self->s.end()); }
Box* setDiscard(BoxedSet* self, Box* key) { RELEASE_ASSERT(isSubclass(self->cls, set_cls), ""); if (PySet_Check(key)) { try { _setRemove(self, key); } catch (ExcInfo e) { if (!e.matches(TypeError)) throw e; e.clear(); BoxedSet* tmpKey = makeNewSet(frozenset_cls, key); AUTO_DECREF(tmpKey); _setRemove(self, tmpKey); } return incref(None); } _setRemove(self, key); return incref(None); }
static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, int *defvalue, const short is_enum_flag) { EnumPropertyItem *items; PyObject *item; const Py_ssize_t seq_len= PySequence_Fast_GET_SIZE(seq_fast); Py_ssize_t totbuf= 0; int i; short def_used= 0; const char *def_cmp= NULL; if(is_enum_flag) { if(seq_len > RNA_ENUM_BITFLAG_SIZE) { PyErr_SetString(PyExc_TypeError, "EnumProperty(...): maximum " STRINGIFY(RNA_ENUM_BITFLAG_SIZE) " members for a ENUM_FLAG type property"); return NULL; } if(def && !PySet_Check(def)) { PyErr_Format(PyExc_TypeError, "EnumProperty(...): default option must be a 'set' " "type when ENUM_FLAG is enabled, not a '%.200s'", Py_TYPE(def)->tp_name); return NULL; } } else { if(def) { def_cmp= _PyUnicode_AsString(def); if(def_cmp==NULL) { PyErr_Format(PyExc_TypeError, "EnumProperty(...): default option must be a 'str' " "type when ENUM_FLAG is disabled, not a '%.200s'", Py_TYPE(def)->tp_name); return NULL; } } } /* blank value */ *defvalue= 0; items= MEM_callocN(sizeof(EnumPropertyItem) * (seq_len + 1), "enum_items_from_py1"); for(i=0; i<seq_len; i++) { EnumPropertyItem tmp= {0, "", 0, "", ""}; Py_ssize_t id_str_size; Py_ssize_t name_str_size; Py_ssize_t desc_str_size; item= PySequence_Fast_GET_ITEM(seq_fast, i); if( (PyTuple_CheckExact(item)) && (PyTuple_GET_SIZE(item) == 3) && (tmp.identifier= _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 0), &id_str_size)) && (tmp.name= _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 1), &name_str_size)) && (tmp.description= _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 2), &desc_str_size)) ) { if(is_enum_flag) { tmp.value= 1<<i; if(def && PySet_Contains(def, PyTuple_GET_ITEM(item, 0))) { *defvalue |= tmp.value; def_used++; } } else { tmp.value= i; if(def && def_used == 0 && strcmp(def_cmp, tmp.identifier)==0) { *defvalue= tmp.value; def_used++; /* only ever 1 */ } } items[i]= tmp; /* calculate combine string length */ totbuf += id_str_size + name_str_size + desc_str_size + 3; /* 3 is for '\0's */ } else { MEM_freeN(items); PyErr_SetString(PyExc_TypeError, "EnumProperty(...): expected an tuple containing (identifier, name description)"); return NULL; } } if(is_enum_flag) { /* strict check that all set members were used */ if(def && def_used != PySet_GET_SIZE(def)) { MEM_freeN(items); PyErr_Format(PyExc_TypeError, "EnumProperty(..., default={...}): set has %d unused member(s)", PySet_GET_SIZE(def) - def_used); return NULL; } } else { if(def && def_used == 0) { MEM_freeN(items); PyErr_Format(PyExc_TypeError, "EnumProperty(..., default=\'%s\'): not found in enum members", def); return NULL; } } /* disabled duplicating strings because the array can still be freed and * the strings from it referenced, for now we can't support dynamically * created strings from python. */ #if 0 /* this would all work perfectly _but_ the python strings may be freed * immediately after use, so we need to duplicate them, ugh. * annoying because it works most of the time without this. */ { EnumPropertyItem *items_dup= MEM_mallocN((sizeof(EnumPropertyItem) * (seq_len + 1)) + (sizeof(char) * totbuf), "enum_items_from_py2"); EnumPropertyItem *items_ptr= items_dup; char *buf= ((char *)items_dup) + (sizeof(EnumPropertyItem) * (seq_len + 1)); memcpy(items_dup, items, sizeof(EnumPropertyItem) * (seq_len + 1)); for(i=0; i<seq_len; i++, items_ptr++) { buf += strswapbufcpy(buf, &items_ptr->identifier); buf += strswapbufcpy(buf, &items_ptr->name); buf += strswapbufcpy(buf, &items_ptr->description); } MEM_freeN(items); items=items_dup; } /* end string duplication */ #endif return items; }
static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, int *defvalue, const short is_enum_flag) { EnumPropertyItem *items= NULL; PyObject *item; int seq_len, i, totitem= 0; short def_used= 0; const char *def_cmp= NULL; seq_len= PySequence_Fast_GET_SIZE(seq_fast); if(is_enum_flag) { if(seq_len > RNA_ENUM_BITFLAG_SIZE) { PyErr_SetString(PyExc_TypeError, "EnumProperty(...): maximum " STRINGIFY(RNA_ENUM_BITFLAG_SIZE) " members for a ENUM_FLAG type property"); return NULL; } if(def && !PySet_Check(def)) { PyErr_Format(PyExc_TypeError, "EnumProperty(...): default option must be a 'set' type when ENUM_FLAG is enabled, not a '%.200s'", Py_TYPE(def)->tp_name); return NULL; } } else { if(def) { def_cmp= _PyUnicode_AsString(def); if(def_cmp==NULL) { PyErr_Format(PyExc_TypeError, "EnumProperty(...): default option must be a 'str' type when ENUM_FLAG is disabled, not a '%.200s'", Py_TYPE(def)->tp_name); return NULL; } } } /* blank value */ *defvalue= 0; for(i=0; i<seq_len; i++) { EnumPropertyItem tmp= {0, "", 0, "", ""}; item= PySequence_Fast_GET_ITEM(seq_fast, i); if(PyTuple_Check(item)==0) { PyErr_SetString(PyExc_TypeError, "EnumProperty(...): expected a sequence of tuples for the enum items"); if(items) MEM_freeN(items); return NULL; } if(!PyArg_ParseTuple(item, "sss", &tmp.identifier, &tmp.name, &tmp.description)) { PyErr_SetString(PyExc_TypeError, "EnumProperty(...): expected an identifier, name and description in the tuple"); return NULL; } if(is_enum_flag) { tmp.value= 1<<i; if(def && PySet_Contains(def, PyTuple_GET_ITEM(item, 0))) { *defvalue |= tmp.value; def_used++; } } else { tmp.value= i; if(def && def_used == 0 && strcmp(def_cmp, tmp.identifier)==0) { *defvalue= tmp.value; def_used++; /* only ever 1 */ } } RNA_enum_item_add(&items, &totitem, &tmp); } RNA_enum_item_end(&items, &totitem); if(is_enum_flag) { /* strict check that all set members were used */ if(def && def_used != PySet_GET_SIZE(def)) { MEM_freeN(items); PyErr_Format(PyExc_TypeError, "EnumProperty(..., default={...}): set has %d unused member(s)", PySet_GET_SIZE(def) - def_used); return NULL; } } else { if(def && def_used == 0) { MEM_freeN(items); PyErr_Format(PyExc_TypeError, "EnumProperty(..., default=\'%s\'): not found in enum members", def); return NULL; } } return items; }