Box* setAnd(BoxedSet* lhs, BoxedSet* rhs) { RELEASE_ASSERT(PyAnySet_Check(lhs), ""); if (!PyAnySet_Check(rhs)) return incref(NotImplemented); return setIntersection2(lhs, rhs); }
Box* setGe(BoxedSet* self, BoxedSet* rhs) { RELEASE_ASSERT(PyAnySet_Check(self), ""); if (!PyAnySet_Check(rhs)) raiseExcHelper(TypeError, "can only compare to a set"); return setIssuperset(self, rhs); }
Box* setIXor(BoxedSet* lhs, BoxedSet* rhs) { RELEASE_ASSERT(PyAnySet_Check(lhs), ""); if (!PyAnySet_Check(rhs)) return incref(NotImplemented); _setSymmetricDifferenceUpdate(lhs, rhs); return incref(lhs); }
Box* setIAnd(BoxedSet* lhs, BoxedSet* rhs) { RELEASE_ASSERT(PyAnySet_Check(lhs), ""); if (!PyAnySet_Check(rhs)) return incref(NotImplemented); auto r = setIntersectionUpdate2(lhs, rhs); Py_DECREF(r); return incref(lhs); }
Box* setXor(BoxedSet* lhs, BoxedSet* rhs) { RELEASE_ASSERT(PyAnySet_Check(lhs), ""); if (!PyAnySet_Check(rhs)) return incref(NotImplemented); BoxedSet* rtn = makeNewSet(lhs->cls, lhs); AUTO_DECREF(rtn); return setIXor(rtn, rhs); }
Box* setEq(BoxedSet* self, BoxedSet* rhs) { RELEASE_ASSERT(PyAnySet_Check(self), ""); if (!PyAnySet_Check(rhs)) Py_RETURN_FALSE; if (self->s.size() != rhs->s.size()) Py_RETURN_FALSE; return setIssubset(self, rhs); }
Box* setGt(BoxedSet* self, BoxedSet* rhs) { RELEASE_ASSERT(PyAnySet_Check(self), ""); if (!PyAnySet_Check(rhs)) raiseExcHelper(TypeError, "can only compare to a set"); if (self->s.size() <= rhs->s.size()) Py_RETURN_FALSE; return setIssuperset(self, rhs); }
Box* setISub(BoxedSet* lhs, BoxedSet* rhs) { RELEASE_ASSERT(PyAnySet_Check(lhs), ""); if (!PyAnySet_Check(rhs)) return incref(NotImplemented); // TODO: write and call setDifferenceUpdate2 for (auto&& elt : rhs->s) { _setRemove(lhs, elt); } return incref(lhs); }
Box* setIOr(BoxedSet* lhs, BoxedSet* rhs) { RELEASE_ASSERT(PyAnySet_Check(lhs), ""); if (!PyAnySet_Check(rhs)) return incref(NotImplemented); // TODO just [write and] call setUnionUpdate2 for (auto&& elt : rhs->s) { _setAdd(lhs, elt); } return incref(lhs); }
static Box* setIssuperset(BoxedSet* self, Box* container) { RELEASE_ASSERT(PyAnySet_Check(self), ""); if (!PyAnySet_Check(container)) { container = makeNewSet(set_cls, container); } else { Py_INCREF(container); } AUTO_DECREF(container); assert(PyAnySet_Check(container)); return setIssubset((BoxedSet*)container, self); }
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); }
void type_check(PyObject* p)noexcept(!PY11_ENFORCE) { if(PY11_ENFORCE && p){ if(!PyAnySet_Check(p)) throw type_err("creating set failed"); } }
Box* frozensetCopy(BoxedSet* self) { RELEASE_ASSERT(PyAnySet_Check(self), ""); if (self->cls == frozenset_cls) { return incref(self); } return setCopy(self); }
Box* setCopy(BoxedSet* self) { RELEASE_ASSERT(PyAnySet_Check(self), ""); BoxedSet* rtn = new BoxedSet(); for (auto&& p : self->s) Py_INCREF(p.value); rtn->s = self->s; return rtn; }
static Box* setIsdisjoint(BoxedSet* self, Box* container) { RELEASE_ASSERT(PyAnySet_Check(self), ""); for (auto e : container->pyElements()) { AUTO_DECREF(e); if (self->s.find(e) != self->s.end()) Py_RETURN_FALSE; } Py_RETURN_TRUE; }
Box* setSymmetricDifference(BoxedSet* self, Box* other) { if (!PyAnySet_Check(self)) raiseExcHelper(TypeError, "descriptor 'symmetric_difference' requires a 'set' object but received a '%s'", getTypeName(self)); BoxedSet* rtn = makeNewSet(self->cls, self); AUTO_DECREF(rtn); _setSymmetricDifferenceUpdate(rtn, other); return incref(rtn); }
static Box* setIssubset(BoxedSet* self, Box* container) { RELEASE_ASSERT(PyAnySet_Check(self), ""); if (!PyAnySet_Check(container)) { container = makeNewSet(set_cls, container); } else { Py_INCREF(container); } AUTO_DECREF(container); assert(PyAnySet_Check(container)); BoxedSet* rhs = static_cast<BoxedSet*>(container); if (self->s.size() > rhs->s.size()) Py_RETURN_FALSE; for (auto e : self->s) { if (rhs->s.find(e) == rhs->s.end()) Py_RETURN_FALSE; } Py_RETURN_TRUE; }
static void setClearInternal(BoxedSet* self) { ASSERT(PyAnySet_Check(self), ""); if (self->s.size()) { BoxedSet::Set tmp; std::swap(tmp, self->s); for (auto p : tmp) { Py_DECREF(p.value); } self->s.clear(); } }
static BoxedSet* setIntersection2(BoxedSet* self, Box* container) { RELEASE_ASSERT(PyAnySet_Check(self), ""); BoxedSet* rtn = makeNewSet(self->cls, NULL); AUTO_DECREF(rtn); for (auto elt : container->pyElements()) { AUTO_DECREF(elt); BoxAndHash elt_hashed(elt); // this can throw! if (self->s.count(elt_hashed)) _setAdd(rtn, elt_hashed); } return incref(rtn); }
static Box* setRepr(BoxedSet* self) { RELEASE_ASSERT(PyAnySet_Check(self), ""); std::vector<char> chars; int status = Py_ReprEnter((PyObject*)self); if (status != 0) { if (status < 0) throwCAPIException(); std::string ty = std::string(self->cls->tp_name); chars.insert(chars.end(), ty.begin(), ty.end()); chars.push_back('('); chars.push_back('.'); chars.push_back('.'); chars.push_back('.'); chars.push_back(')'); return boxString(llvm::StringRef(&chars[0], chars.size())); } try { std::string ty = std::string(self->cls->tp_name); chars.insert(chars.end(), ty.begin(), ty.end()); chars.push_back('('); chars.push_back('['); bool first = true; for (auto&& elt : self->s) { if (!first) { chars.push_back(','); chars.push_back(' '); } BoxedString* str = static_cast<BoxedString*>(repr(elt.value)); AUTO_DECREF(str); chars.insert(chars.end(), str->s().begin(), str->s().end()); first = false; } chars.push_back(']'); chars.push_back(')'); } catch (ExcInfo e) { Py_ReprLeave((PyObject*)self); throw e; } Py_ReprLeave((PyObject*)self); return boxString(llvm::StringRef(&chars[0], chars.size())); }
// Note: PySet_Add is allowed to apply to frozenset objects, though CPython has // an check to make sure the refcount is 1. // for example, the marshal library uses this to construct frozenset objects. extern "C" int PySet_Add(PyObject* set, PyObject* key) noexcept { if (!PyAnySet_Check(set)) { PyErr_BadInternalCall(); return -1; } try { _setAdd(static_cast<BoxedSet*>(set), key); return 0; } catch (ExcInfo e) { setCAPIException(e); return -1; } }
static Box* setIntersection(BoxedSet* self, BoxedTuple* args) { if (!PyAnySet_Check(self)) raiseExcHelper(TypeError, "descriptor 'intersection' requires a 'set' object but received a '%s'", getTypeName(self)); if (args->size() == 0) return makeNewSet(self->cls, self); BoxedSet* rtn = incref(self); for (auto container : *args) { AUTO_DECREF(rtn); rtn = setIntersection2(rtn, container); } return rtn; }
Box* setUnion(BoxedSet* self, BoxedTuple* args) { if (!PyAnySet_Check(self)) raiseExcHelper(TypeError, "descriptor 'union' requires a 'set' object but received a '%s'", getTypeName(self)); BoxedSet* rtn = makeNewSet(self->cls, self); AUTO_DECREF(rtn); for (auto&& p : self->s) _setAdd(rtn, p); for (auto container : args->pyElements()) { AUTO_DECREF(container); for (auto elt : container->pyElements()) { _setAddStolen(rtn, elt); } } return incref(rtn); }
static void _setSymmetricDifferenceUpdate(BoxedSet* self, Box* other) { if (!PyAnySet_Check(other)) { other = makeNewSet(self->cls, other); } else { Py_INCREF(other); } AUTO_DECREF(other); BoxedSet* other_set = static_cast<BoxedSet*>(other); for (auto elt : other_set->s) { auto&& p = self->s.insert(elt); if (!p.second /* already exists */) { _setRemove(self, elt); } else { Py_INCREF(elt.value); } } }
static void _setDifferenceUpdate(BoxedSet* self, BoxedTuple* args) { for (auto container : args->pyElements()) { AUTO_DECREF(container); if (PyAnySet_Check(container)) { for (auto&& elt : ((BoxedSet*)container)->s) { _setRemove(self, elt); } } else if (PyDict_CheckExact(container)) { for (auto&& elt : ((BoxedDict*)container)->d) { _setRemove(self, elt.first); } } else { for (auto elt : container->pyElements()) { AUTO_DECREF(elt); _setRemove(self, elt); } } } }
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()); }
static CYTHON_INLINE int __Pyx_PySet_Update(PyObject* set, PyObject* it) { PyObject *retval; #if CYTHON_COMPILING_IN_CPYTHON if (PyAnySet_Check(it)) { if (PySet_GET_SIZE(it) == 0) return 0; // fast and safe case: CPython will update our result set and return it retval = PySet_Type.tp_as_number->nb_inplace_or(set, it); if (likely(retval == set)) { Py_DECREF(retval); return 0; } if (unlikely(!retval)) return -1; // unusual result, fall through to set.update() call below Py_DECREF(retval); } #endif retval = CALL_UNBOUND_METHOD(PySet_Type, "update", set, it); if (unlikely(!retval)) return -1; Py_DECREF(retval); return 0; }
// Creates a set of type 'cls' from 'container' (NULL to get an empty set). // Works for frozenset and normal set types. BoxedSet* makeNewSet(BoxedClass* cls, Box* container) { assert(isSubclass(cls, frozenset_cls) || isSubclass(cls, set_cls)); BoxedSet* rtn = new (cls) BoxedSet(); if (container) { AUTO_DECREF(rtn); if (PyAnySet_Check(container)) { for (auto&& elt : ((BoxedSet*)container)->s) { rtn->s.insert(incref(elt)); } } else if (PyDict_CheckExact(container)) { for (auto&& elt : ((BoxedDict*)container)->d) { rtn->s.insert(incref(elt.first)); } } else { for (auto elt : container->pyElements()) { _setAddStolen(rtn, elt); } } return incref(rtn); } return rtn; }
void Object_beginTypeContext (JSOBJ _obj, JSONTypeContext *tc) { PyObject *obj, *exc, *toDictFunc; TypeContext *pc; PRINTMARK(); if (!_obj) { tc->type = JT_INVALID; return; } obj = (PyObject*) _obj; tc->prv = PyObject_Malloc(sizeof(TypeContext)); pc = (TypeContext *) tc->prv; if (!pc) { tc->type = JT_INVALID; PyErr_NoMemory(); return; } pc->newObj = NULL; pc->dictObj = NULL; pc->itemValue = NULL; pc->itemName = NULL; pc->attrList = NULL; pc->index = 0; pc->size = 0; pc->longValue = 0; if (PyIter_Check(obj)) { PRINTMARK(); goto ISITERABLE; } if (PyBool_Check(obj)) { PRINTMARK(); tc->type = (obj == Py_True) ? JT_TRUE : JT_FALSE; return; } else if (PyLong_Check(obj)) { PRINTMARK(); pc->PyTypeToJSON = PyLongToINT64; tc->type = JT_LONG; GET_TC(tc)->longValue = PyLong_AsLongLong(obj); exc = PyErr_Occurred(); if (exc && PyErr_ExceptionMatches(PyExc_OverflowError)) { #if HAS_JSON_HANDLE_BIGINTS PyErr_Clear(); pc->PyTypeToJSON = PyBigIntToSTR; tc->type = JT_BIGINT; GET_TC(tc)->longValue = 0; return; #endif PRINTMARK(); goto INVALID; } return; } else if (PyInt_Check(obj)) { PRINTMARK(); #ifdef _LP64 pc->PyTypeToJSON = PyIntToINT64; tc->type = JT_LONG; #else pc->PyTypeToJSON = PyIntToINT32; tc->type = JT_INT; #endif return; } else if (PyString_Check(obj)) { PRINTMARK(); pc->PyTypeToJSON = PyStringToUTF8; tc->type = JT_UTF8; return; } else if (PyUnicode_Check(obj)) { PRINTMARK(); pc->PyTypeToJSON = PyUnicodeToUTF8; tc->type = JT_UTF8; return; } else if (PyFloat_Check(obj) || (type_decimal && PyObject_IsInstance(obj, type_decimal))) { PRINTMARK(); pc->PyTypeToJSON = PyFloatToDOUBLE; tc->type = JT_DOUBLE; return; } else if (PyDateTime_Check(obj)) { PRINTMARK(); pc->PyTypeToJSON = PyDateTimeToINT64; tc->type = JT_LONG; return; } else if (PyDate_Check(obj)) { PRINTMARK(); pc->PyTypeToJSON = PyDateToINT64; tc->type = JT_LONG; return; } else if (obj == Py_None) { PRINTMARK(); tc->type = JT_NULL; return; } ISITERABLE: if (PyDict_Check(obj)) { PRINTMARK(); tc->type = JT_OBJECT; pc->iterBegin = Dict_iterBegin; pc->iterEnd = Dict_iterEnd; pc->iterNext = Dict_iterNext; pc->iterGetValue = Dict_iterGetValue; pc->iterGetName = Dict_iterGetName; pc->dictObj = obj; Py_INCREF(obj); return; } else if (PyList_Check(obj)) { PRINTMARK(); tc->type = JT_ARRAY; pc->iterBegin = List_iterBegin; pc->iterEnd = List_iterEnd; pc->iterNext = List_iterNext; pc->iterGetValue = List_iterGetValue; pc->iterGetName = List_iterGetName; return; } else if (PyTuple_Check(obj)) { PRINTMARK(); tc->type = JT_ARRAY; pc->iterBegin = Tuple_iterBegin; pc->iterEnd = Tuple_iterEnd; pc->iterNext = Tuple_iterNext; pc->iterGetValue = Tuple_iterGetValue; pc->iterGetName = Tuple_iterGetName; return; } else if (PyAnySet_Check(obj)) { PRINTMARK(); tc->type = JT_ARRAY; pc->iterBegin = Iter_iterBegin; pc->iterEnd = Iter_iterEnd; pc->iterNext = Iter_iterNext; pc->iterGetValue = Iter_iterGetValue; pc->iterGetName = Iter_iterGetName; return; } toDictFunc = PyObject_GetAttrString(obj, "toDict"); if (toDictFunc) { PyObject* tuple = PyTuple_New(0); PyObject* toDictResult = PyObject_Call(toDictFunc, tuple, NULL); Py_DECREF(tuple); Py_DECREF(toDictFunc); if (toDictResult == NULL) { PyErr_Clear(); tc->type = JT_NULL; return; } if (!PyDict_Check(toDictResult)) { Py_DECREF(toDictResult); tc->type = JT_NULL; return; } PRINTMARK(); tc->type = JT_OBJECT; pc->iterBegin = Dict_iterBegin; pc->iterEnd = Dict_iterEnd; pc->iterNext = Dict_iterNext; pc->iterGetValue = Dict_iterGetValue; pc->iterGetName = Dict_iterGetName; pc->dictObj = toDictResult; return; } PyErr_Clear(); PRINTMARK(); // Falling to INVALID case as this type of object(class instance, module, // class, function, etc..) can't be serialized. PyErr_Format (PyExc_TypeError, "%s", "Object is not JSON serializable"); INVALID: tc->type = JT_INVALID; PyObject_Free(tc->prv); tc->prv = NULL; return; }
Box* setNonzero(BoxedSet* self) { RELEASE_ASSERT(PyAnySet_Check(self), ""); return boxBool(self->s.size()); }