コード例 #1
0
ファイル: pyjlist.c プロジェクト: mrj0/jep
static int pyjlist_set_subscript(PyObject* self, PyObject* item,
                                 PyObject* value)
{
    if (PyInt_Check(item)) {
        long i = (long) PyInt_AS_LONG(item);
        if (i < 0) {
            i += (long) PyObject_Size(self);
        }
        return pyjlist_setitem(self, (Py_ssize_t) i, value);
    } else if (PyLong_Check(item)) {
        long i = PyLong_AsLong(item);
        if (i == -1 && PyErr_Occurred()) {
            return -1;
        }
        if (i < 0) {
            i += (long) PyObject_Size(self);
        }
        return pyjlist_setitem(self, (Py_ssize_t) i, value);
    } else if (PySlice_Check(item)) {
        Py_ssize_t start, stop, step, slicelength;

#if PY_MAJOR_VERSION >= 3
        if (PySlice_GetIndicesEx(item, PyObject_Size(self), &start, &stop, &step,
                                 &slicelength) < 0) {
            // error will already be set
            return -1;
        }
#else
        /*
         * This silences a compile warning on PySlice_GetIndicesEx by casting
         * item.  Python fixed the method signature in 3.2 to take item as a
         * PyObject*
         */
        if (PySlice_GetIndicesEx((PySliceObject *) item, PyObject_Size(self), &start,
                                 &stop, &step, &slicelength) < 0) {
            // error will already be set
            return -1;
        }
#endif

        if (slicelength <= 0) {
            return 0;
        } else if (step != 1) {
            PyErr_SetString(PyExc_TypeError, "pyjlist slices must have step of 1");
            return -1;
        } else {
            return pyjlist_setslice(self, start, stop, value);
        }
    } else {
        PyErr_SetString(PyExc_TypeError,
                        "list indices must be integers, longs, or slices");
        return -1;
    }

}
コード例 #2
0
ファイル: pyjlist.c プロジェクト: mrj0/jep
/*
 * Method for setting slices with the [int:int] operator on pyjlist.  For
 * example, o[i1:i2] = v where v is a sequence.
 */
static int pyjlist_setslice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2,
                            PyObject *v)
{
    Py_ssize_t oSize;
    Py_ssize_t vSize;
    Py_ssize_t diff;
    Py_ssize_t i, vi;

    if (!PySequence_Check(v)) {
        PyErr_Format(PyExc_TypeError,
                     "PyJList can only slice assign a sequence");
        return -1;
    }

    oSize = PySequence_Size(o);
    vSize = PySequence_Size(v);
    if (i1 < 0) {
        i1 = 0;
    }
    if (i2 > oSize) {
        i2 = oSize;
    }
    if (i1 >= i2) {
        PyErr_Format(PyExc_IndexError, "invalid slice indices: %i:%i",
                     (int) i1, (int) i2);
        return -1;
    }
    diff = i2 - i1;
    if (diff != vSize) {
        /*
         * TODO: Python lists support slice assignment of a different length,
         * but that gets complicated, so not planning on supporting it until
         * requested.  For inspiration look at python's listobject.c's
         * list_ass_slice().
         */
        PyErr_Format(PyExc_IndexError,
                     "PyJList only supports assigning a sequence of the same size as the slice, slice = [%i:%i], value size=%i",
                     (int) i1, (int) i2, (int) vSize);
        return -1;
    }

    vi = 0;
    for (i = i1; i < i2; i++) {
        PyObject *vVal = PySequence_GetItem(v, vi);
        if (pyjlist_setitem(o, i, vVal) == -1) {
            /*
             * TODO This is not transactional if it fails partially through.
             * Not sure how to make that safe short of making a copy of o
             * and then replacing o's underlying jobject on success.  That
             * would slow it down though....
             */
            Py_DECREF(vVal);
            return -1;
        }
        Py_DECREF(vVal);
        vi++;
    }

    return 0;
}
コード例 #3
0
ファイル: pyjlist.c プロジェクト: behdad84/jep
static int pyjlist_set_subscript(PyObject* self, PyObject* item, PyObject* value) {
    if(PyInt_Check(item)) {
        long i = PyInt_AS_LONG(item);
        if (i < 0)
            i += (long) PyObject_Size(self);
        return pyjlist_setitem(self, (Py_ssize_t) i, value);
    }
    else if(PyLong_Check(item)) {
        long i = PyLong_AsLong(item);
        if (i == -1 && PyErr_Occurred())
            return -1;
        if (i < 0)
            i += (long) PyObject_Size(self);
        return pyjlist_setitem(self, (Py_ssize_t) i, value);
    } else if(PySlice_Check(item)) {
        Py_ssize_t start, stop, step, slicelength;
        /*
         * ignore compile warning on the next line, they fixed the
         * method signature in python 3.2
         */
        if(PySlice_GetIndicesEx(item, PyObject_Size(self), &start, &stop, &step, &slicelength) < 0) {
            // error will already be set
            return -1;
        }

        if(slicelength <= 0) {
            return 0;
        } else if(step != 1) {
            PyErr_SetString(PyExc_TypeError, "pyjlist slices must have step of 1");
            return -1;
        } else {
            return pyjlist_setslice(self, start, stop, value);
        }
    } else {
        PyErr_SetString(PyExc_TypeError, "list indices must be integers, longs, or slices");
        return -1;
    }

}