Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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;
}