int UniqueList_Extend(UniqueList *self, PyObject *b) { PyObject *iter = NULL, *newitem, *ret; if (b != NULL) iter = PyObject_GetIter(b); if (iter != NULL) { for (newitem = PyIter_Next(iter); newitem != NULL; newitem = PyIter_Next(iter)) { if (PyDict_Check(newitem) || PyList_Check(newitem) || PyTuple_Check(newitem)) { PyErr_SetString(PyExc_ValueError, "This type of list can not contain instances of Python tuple, list or dict."); return -1; } if (UniqueList_Contains(self, newitem) == 1){ PyErr_SetString(PyExc_TypeError, "List is containing non-unique values."); return -1; } Py_DECREF(newitem); } Py_DECREF(iter); } ret = _PyList_Extend((PyListObject *)self, b); if (ret != Py_None) return -1; return 0; }
static PyObject *m_build_unpack_pair(PyObject *mod, PyObject *seqs) { // checked Py_ssize_t count = seqs? PyTuple_GET_SIZE(seqs): 0; Py_ssize_t index = 0; PyObject *tmp; if (! count) { Py_INCREF(SibNil); return SibNil; } PyObject *coll = PyList_New(0); while (index < count) { PyObject *item = PyTuple_GET_ITEM(seqs, index++); PyObject *work; if (SibNil_Check(item)) { // skip nil continue; } else if (SibPair_CheckExact(item)) { work = pair_unpack(item, NULL); } else { // todo: check for lists and tuples explicitly, and see if // they're zero-length. If so, avoid creating an iterator, just // continue to the next item. work = PyObject_GetIter(item); } if (! work) { Py_DECREF(coll); return NULL; } // why the everloving f**k isn't this a regular call? tmp will be // NULL for exception, or a new PyNone reference if successful. tmp = _PyList_Extend((PyListObject *) coll, work); Py_CLEAR(work); if (! tmp) { Py_DECREF(coll); return NULL; } else { Py_CLEAR(tmp); } } if (! PyList_GET_SIZE(coll)) { // The collection didn't net any actual elements, so let's skip // out early and just return nil Py_DECREF(coll); Py_INCREF(SibNil); return SibNil; } // I wonder if there isn't a better way to do this. We end up // traversing the last cons pair twice, which means allocating a set // in order to avoid recursion. Is that too expensive? tmp = PyTuple_GET_ITEM(seqs, count - 1); if (SibPair_IsProper(tmp)) { if(PyList_Append(coll, SibNil)) { Py_DECREF(coll); return NULL; } } PyObject *result = SibPair_Cons(coll, 0); Py_DECREF(coll); return result; }