Str .__ getlice__ does not work as expected, with a negative stop

I tried to run the following code in python 2.7:

foo = "python is awesome"
print foo[10:16]
print foo.__getslice__(10,16)
print foo[10:-1]
print foo.__getslice__(10,-1)

all but the last is printed "awsome". but foo.__getslice__(10,-1)returns an empty string. Why is this so?

+4
source share
1 answer
Line

implemented in c so the answer is not so simple as to understand if you know little about c and python-c-api , but I try my best:

If you call __getslice__directly, you will use : string_slice

static PyObject *
string_slice(PyStringObject *a, Py_ssize_t i, Py_ssize_t j)
     /* j -- may be negative! */
{
    if (i < 0)
        i = 0;
    if (j < 0)
        j = 0; /* Avoid signed/unsigned bug in next line */
    if (j > Py_SIZE(a))
        j = Py_SIZE(a);
    if (i == 0 && j == Py_SIZE(a) && PyString_CheckExact(a)) {
        /* It the same as a */
        Py_INCREF(a);
        return (PyObject *)a;
    }
    if (j < i)
        j = i;
    return PyString_FromStringAndSize(a->ob_sval + i, j-i);
}

i - , j - -. , , 0 (if (j < 0) j = 0;), , , (if (j < i) j = i;). , start = 10 stop = 10, .

[], string_subscript ( )

static PyObject*
string_subscript(PyStringObject* self, PyObject* item)
{
    /* ... */
    if (PySlice_Check(item)) {
        Py_ssize_t start, stop, step, slicelength, cur, i;
        /* ... */

        if (_PySlice_Unpack(item, &start, &stop, &step) < 0) {
            return NULL;
        }
        slicelength = _PySlice_AdjustIndices(PyString_GET_SIZE(self), &start,
                                            &stop, step);

        /* ... */
        if (step == 1) {
            return PyString_FromStringAndSize(
                PyString_AS_STRING(self) + start,
                slicelength);
        }
        /* ... */
    }
    /* ... */
}

_PySlice_AdjustIndices ( PySlice_AdjustIndices). -1 len(string) - 1:

Py_ssize_t PySlice_AdjustIndices (Py_ssize_t length, Py_ssize_t * start, Py_ssize_t * stop, Py_ssize_t)

/ , . , .

, , . , .


__*__ . , Python ( , ).

__getslice__ - - .

+4

Source: https://habr.com/ru/post/1677240/


All Articles