diff options
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_collectionsmodule.c | 354 | ||||
-rw-r--r-- | Modules/_datetimemodule.c | 80 | ||||
-rw-r--r-- | Modules/_heapqmodule.c | 6 | ||||
-rw-r--r-- | Modules/_io/_iomodule.c | 19 | ||||
-rw-r--r-- | Modules/_sre.c | 3 | ||||
-rw-r--r-- | Modules/_testcapimodule.c | 5 | ||||
-rw-r--r-- | Modules/clinic/posixmodule.c.h | 10 | ||||
-rw-r--r-- | Modules/itertoolsmodule.c | 371 | ||||
-rw-r--r-- | Modules/nismodule.c | 6 | ||||
-rw-r--r-- | Modules/posixmodule.c | 29 | ||||
-rw-r--r-- | Modules/readline.c | 2 | ||||
-rw-r--r-- | Modules/sre_lib.h | 53 |
12 files changed, 476 insertions, 462 deletions
diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index 5dea8cb..5db7aed 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -121,7 +121,7 @@ static PyTypeObject deque_type; added at about the same rate as old blocks are being freed. */ -#define MAXFREEBLOCKS 10 +#define MAXFREEBLOCKS 16 static Py_ssize_t numfreeblocks = 0; static block *freeblocks[MAXFREEBLOCKS]; @@ -209,7 +209,7 @@ deque_pop(dequeobject *deque, PyObject *unused) Py_SIZE(deque)--; deque->state++; - if (deque->rightindex == -1) { + if (deque->rightindex < 0) { if (Py_SIZE(deque)) { prevblock = deque->rightblock->leftlink; assert(deque->leftblock != deque->rightblock); @@ -315,8 +315,8 @@ deque_append(dequeobject *deque, PyObject *item) MARK_END(b->rightlink); deque->rightindex = -1; } - Py_INCREF(item); Py_SIZE(deque)++; + Py_INCREF(item); deque->rightindex++; deque->rightblock->data[deque->rightindex] = item; deque_trim_left(deque); @@ -340,8 +340,8 @@ deque_appendleft(dequeobject *deque, PyObject *item) MARK_END(b->leftlink); deque->leftindex = BLOCKLEN; } - Py_INCREF(item); Py_SIZE(deque)++; + Py_INCREF(item); deque->leftindex--; deque->leftblock->data[deque->leftindex] = item; deque_trim_right(deque); @@ -371,6 +371,8 @@ static PyObject * deque_extend(dequeobject *deque, PyObject *iterable) { PyObject *it, *item; + PyObject *(*iternext)(PyObject *); + int trim = (deque->maxlen != -1); /* Handle case where id(deque) == id(iterable) */ if ((PyObject *)deque == iterable) { @@ -398,7 +400,8 @@ deque_extend(dequeobject *deque, PyObject *iterable) if (deque->maxlen == 0) return consume_iterator(it); - while ((item = PyIter_Next(it)) != NULL) { + iternext = *Py_TYPE(it)->tp_iternext; + while ((item = iternext(it)) != NULL) { deque->state++; if (deque->rightindex == BLOCKLEN - 1) { block *b = newblock(Py_SIZE(deque)); @@ -417,11 +420,16 @@ deque_extend(dequeobject *deque, PyObject *iterable) Py_SIZE(deque)++; deque->rightindex++; deque->rightblock->data[deque->rightindex] = item; - deque_trim_left(deque); + if (trim) + deque_trim_left(deque); } if (PyErr_Occurred()) { - Py_DECREF(it); - return NULL; + if (PyErr_ExceptionMatches(PyExc_StopIteration)) + PyErr_Clear(); + else { + Py_DECREF(it); + return NULL; + } } Py_DECREF(it); Py_RETURN_NONE; @@ -434,6 +442,8 @@ static PyObject * deque_extendleft(dequeobject *deque, PyObject *iterable) { PyObject *it, *item; + PyObject *(*iternext)(PyObject *); + int trim = (deque->maxlen != -1); /* Handle case where id(deque) == id(iterable) */ if ((PyObject *)deque == iterable) { @@ -461,7 +471,8 @@ deque_extendleft(dequeobject *deque, PyObject *iterable) if (deque->maxlen == 0) return consume_iterator(it); - while ((item = PyIter_Next(it)) != NULL) { + iternext = *Py_TYPE(it)->tp_iternext; + while ((item = iternext(it)) != NULL) { deque->state++; if (deque->leftindex == 0) { block *b = newblock(Py_SIZE(deque)); @@ -480,11 +491,16 @@ deque_extendleft(dequeobject *deque, PyObject *iterable) Py_SIZE(deque)++; deque->leftindex--; deque->leftblock->data[deque->leftindex] = item; - deque_trim_right(deque); + if (trim) + deque_trim_right(deque); } if (PyErr_Occurred()) { - Py_DECREF(it); - return NULL; + if (PyErr_ExceptionMatches(PyExc_StopIteration)) + PyErr_Clear(); + else { + Py_DECREF(it); + return NULL; + } } Py_DECREF(it); Py_RETURN_NONE; @@ -506,7 +522,40 @@ deque_inplace_concat(dequeobject *deque, PyObject *other) return (PyObject *)deque; } -static PyObject *deque_copy(PyObject *deque); +static PyObject * +deque_copy(PyObject *deque) +{ + dequeobject *old_deque = (dequeobject *)deque; + if (Py_TYPE(deque) == &deque_type) { + dequeobject *new_deque; + PyObject *rv; + + new_deque = (dequeobject *)deque_new(&deque_type, (PyObject *)NULL, (PyObject *)NULL); + if (new_deque == NULL) + return NULL; + new_deque->maxlen = old_deque->maxlen; + /* Fast path for the deque_repeat() common case where len(deque) == 1 */ + if (Py_SIZE(deque) == 1 && new_deque->maxlen != 0) { + PyObject *item = old_deque->leftblock->data[old_deque->leftindex]; + rv = deque_append(new_deque, item); + } else { + rv = deque_extend(new_deque, deque); + } + if (rv != NULL) { + Py_DECREF(rv); + return (PyObject *)new_deque; + } + Py_DECREF(new_deque); + return NULL; + } + if (old_deque->maxlen < 0) + return PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "O", deque, NULL); + else + return PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "Oi", + deque, old_deque->maxlen, NULL); +} + +PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque."); static PyObject * deque_concat(dequeobject *deque, PyObject *other) @@ -536,38 +585,90 @@ deque_concat(dequeobject *deque, PyObject *other) return new_deque; } -static void deque_clear(dequeobject *deque); - -static PyObject * -deque_repeat(dequeobject *deque, Py_ssize_t n) +static void +deque_clear(dequeobject *deque) { - dequeobject *new_deque; - PyObject *result; + block *b; + block *prevblock; + block *leftblock; + Py_ssize_t leftindex; + Py_ssize_t n; + PyObject *item; - /* XXX add a special case for when maxlen is defined */ - if (n < 0) - n = 0; - else if (n > 0 && Py_SIZE(deque) > MAX_DEQUE_LEN / n) - return PyErr_NoMemory(); + /* During the process of clearing a deque, decrefs can cause the + deque to mutate. To avoid fatal confusion, we have to make the + deque empty before clearing the blocks and never refer to + anything via deque->ref while clearing. (This is the same + technique used for clearing lists, sets, and dicts.) - new_deque = (dequeobject *)deque_new(&deque_type, (PyObject *)NULL, (PyObject *)NULL); - new_deque->maxlen = deque->maxlen; + Making the deque empty requires allocating a new empty block. In + the unlikely event that memory is full, we fall back to an + alternate method that doesn't require a new block. Repeating + pops in a while-loop is slower, possibly re-entrant (and a clever + adversary could cause it to never terminate). + */ - for ( ; n ; n--) { - result = deque_extend(new_deque, (PyObject *)deque); - if (result == NULL) { - Py_DECREF(new_deque); - return NULL; + b = newblock(0); + if (b == NULL) { + PyErr_Clear(); + goto alternate_method; + } + + /* Remember the old size, leftblock, and leftindex */ + leftblock = deque->leftblock; + leftindex = deque->leftindex; + n = Py_SIZE(deque); + + /* Set the deque to be empty using the newly allocated block */ + MARK_END(b->leftlink); + MARK_END(b->rightlink); + Py_SIZE(deque) = 0; + deque->leftblock = b; + deque->rightblock = b; + deque->leftindex = CENTER + 1; + deque->rightindex = CENTER; + deque->state++; + + /* Now the old size, leftblock, and leftindex are disconnected from + the empty deque and we can use them to decref the pointers. + */ + while (n--) { + item = leftblock->data[leftindex]; + Py_DECREF(item); + leftindex++; + if (leftindex == BLOCKLEN && n) { + CHECK_NOT_END(leftblock->rightlink); + prevblock = leftblock; + leftblock = leftblock->rightlink; + leftindex = 0; + freeblock(prevblock); } - Py_DECREF(result); } - return (PyObject *)new_deque; + CHECK_END(leftblock->rightlink); + freeblock(leftblock); + return; + + alternate_method: + while (Py_SIZE(deque)) { + item = deque_pop(deque, NULL); + assert (item != NULL); + Py_DECREF(item); + } } static PyObject * +deque_clearmethod(dequeobject *deque) +{ + deque_clear(deque); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(clear_doc, "Remove all elements from the deque."); + +static PyObject * deque_inplace_repeat(dequeobject *deque, Py_ssize_t n) { - Py_ssize_t i, size; + Py_ssize_t i, m, size; PyObject *seq; PyObject *rv; @@ -583,10 +684,6 @@ deque_inplace_repeat(dequeobject *deque, Py_ssize_t n) return (PyObject *)deque; } - if (size > MAX_DEQUE_LEN / n) { - return PyErr_NoMemory(); - } - if (size == 1) { /* common case, repeating a single element */ PyObject *item = deque->leftblock->data[deque->leftindex]; @@ -594,16 +691,43 @@ deque_inplace_repeat(dequeobject *deque, Py_ssize_t n) if (deque->maxlen != -1 && n > deque->maxlen) n = deque->maxlen; - for (i = 0 ; i < n-1 ; i++) { - rv = deque_append(deque, item); - if (rv == NULL) - return NULL; - Py_DECREF(rv); + if (n > MAX_DEQUE_LEN) + return PyErr_NoMemory(); + + deque->state++; + for (i = 0 ; i < n-1 ; ) { + if (deque->rightindex == BLOCKLEN - 1) { + block *b = newblock(Py_SIZE(deque) + i); + if (b == NULL) { + Py_SIZE(deque) += i; + return NULL; + } + b->leftlink = deque->rightblock; + CHECK_END(deque->rightblock->rightlink); + deque->rightblock->rightlink = b; + deque->rightblock = b; + MARK_END(b->rightlink); + deque->rightindex = -1; + } + m = n - 1 - i; + if (m > BLOCKLEN - 1 - deque->rightindex) + m = BLOCKLEN - 1 - deque->rightindex; + i += m; + while (m--) { + deque->rightindex++; + Py_INCREF(item); + deque->rightblock->data[deque->rightindex] = item; + } } + Py_SIZE(deque) += i; Py_INCREF(deque); return (PyObject *)deque; } + if ((size_t)size > MAX_DEQUE_LEN / (size_t)n) { + return PyErr_NoMemory(); + } + seq = PySequence_List((PyObject *)deque); if (seq == NULL) return seq; @@ -621,6 +745,20 @@ deque_inplace_repeat(dequeobject *deque, Py_ssize_t n) return (PyObject *)deque; } +static PyObject * +deque_repeat(dequeobject *deque, Py_ssize_t n) +{ + dequeobject *new_deque; + PyObject *rv; + + new_deque = (dequeobject *)deque_copy((PyObject *) deque); + if (new_deque == NULL) + return NULL; + rv = deque_inplace_repeat(new_deque, n); + Py_DECREF(new_deque); + return rv; +} + /* The rotate() method is part of the public API and is used internally as a primitive for other methods. @@ -704,7 +842,7 @@ _deque_rotate(dequeobject *deque, Py_ssize_t n) *(dest++) = *(src++); } while (--m); } - if (rightindex == -1) { + if (rightindex < 0) { assert(leftblock != rightblock); assert(b == NULL); b = rightblock; @@ -792,11 +930,10 @@ deque_reverse(dequeobject *deque, PyObject *unused) block *rightblock = deque->rightblock; Py_ssize_t leftindex = deque->leftindex; Py_ssize_t rightindex = deque->rightindex; - Py_ssize_t n = Py_SIZE(deque) / 2; - Py_ssize_t i; + Py_ssize_t n = Py_SIZE(deque) >> 1; PyObject *tmp; - for (i=0 ; i<n ; i++) { + while (n-- > 0) { /* Validate that pointers haven't met in the middle */ assert(leftblock != rightblock || leftindex < rightindex); CHECK_NOT_END(leftblock); @@ -816,7 +953,7 @@ deque_reverse(dequeobject *deque, PyObject *unused) /* Step backwards with the right block/index pair */ rightindex--; - if (rightindex == -1) { + if (rightindex < 0) { rightblock = rightblock->leftlink; rightindex = BLOCKLEN - 1; } @@ -833,20 +970,18 @@ deque_count(dequeobject *deque, PyObject *v) block *b = deque->leftblock; Py_ssize_t index = deque->leftindex; Py_ssize_t n = Py_SIZE(deque); - Py_ssize_t i; Py_ssize_t count = 0; size_t start_state = deque->state; PyObject *item; int cmp; - for (i=0 ; i<n ; i++) { + while (n--) { CHECK_NOT_END(b); item = b->data[index]; cmp = PyObject_RichCompareBool(item, v, Py_EQ); - if (cmp > 0) - count++; - else if (cmp < 0) + if (cmp < 0) return NULL; + count += cmp; if (start_state != deque->state) { PyErr_SetString(PyExc_RuntimeError, @@ -873,12 +1008,11 @@ deque_contains(dequeobject *deque, PyObject *v) block *b = deque->leftblock; Py_ssize_t index = deque->leftindex; Py_ssize_t n = Py_SIZE(deque); - Py_ssize_t i; size_t start_state = deque->state; PyObject *item; int cmp; - for (i=0 ; i<n ; i++) { + while (n--) { CHECK_NOT_END(b); item = b->data[index]; cmp = PyObject_RichCompareBool(item, v, Py_EQ); @@ -1035,81 +1169,10 @@ deque_remove(dequeobject *deque, PyObject *value) PyDoc_STRVAR(remove_doc, "D.remove(value) -- remove first occurrence of value."); -static void -deque_clear(dequeobject *deque) -{ - block *b; - block *prevblock; - block *leftblock; - Py_ssize_t leftindex; - Py_ssize_t n; - PyObject *item; - - /* During the process of clearing a deque, decrefs can cause the - deque to mutate. To avoid fatal confusion, we have to make the - deque empty before clearing the blocks and never refer to - anything via deque->ref while clearing. (This is the same - technique used for clearing lists, sets, and dicts.) - - Making the deque empty requires allocating a new empty block. In - the unlikely event that memory is full, we fall back to an - alternate method that doesn't require a new block. Repeating - pops in a while-loop is slower, possibly re-entrant (and a clever - adversary could cause it to never terminate). - */ - - b = newblock(0); - if (b == NULL) { - PyErr_Clear(); - goto alternate_method; - } - - /* Remember the old size, leftblock, and leftindex */ - leftblock = deque->leftblock; - leftindex = deque->leftindex; - n = Py_SIZE(deque); - - /* Set the deque to be empty using the newly allocated block */ - MARK_END(b->leftlink); - MARK_END(b->rightlink); - Py_SIZE(deque) = 0; - deque->leftblock = b; - deque->rightblock = b; - deque->leftindex = CENTER + 1; - deque->rightindex = CENTER; - deque->state++; - - /* Now the old size, leftblock, and leftindex are disconnected from - the empty deque and we can use them to decref the pointers. - */ - while (n--) { - item = leftblock->data[leftindex]; - Py_DECREF(item); - leftindex++; - if (leftindex == BLOCKLEN && n) { - CHECK_NOT_END(leftblock->rightlink); - prevblock = leftblock; - leftblock = leftblock->rightlink; - leftindex = 0; - freeblock(prevblock); - } - } - CHECK_END(leftblock->rightlink); - freeblock(leftblock); - return; - - alternate_method: - while (Py_SIZE(deque)) { - item = deque_pop(deque, NULL); - assert (item != NULL); - Py_DECREF(item); - } -} - static int valid_index(Py_ssize_t i, Py_ssize_t limit) { - /* The cast to size_t let us use just a single comparison + /* The cast to size_t lets us use just a single comparison to check whether i is in the range: 0 <= i < limit */ return (size_t) i < (size_t) limit; } @@ -1206,15 +1269,6 @@ deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v) return 0; } -static PyObject * -deque_clearmethod(dequeobject *deque) -{ - deque_clear(deque); - Py_RETURN_NONE; -} - -PyDoc_STRVAR(clear_doc, "Remove all elements from the deque."); - static void deque_dealloc(dequeobject *deque) { @@ -1254,18 +1308,6 @@ deque_traverse(dequeobject *deque, visitproc visit, void *arg) } static PyObject * -deque_copy(PyObject *deque) -{ - if (((dequeobject *)deque)->maxlen == -1) - return PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "O", deque, NULL); - else - return PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "Oi", - deque, ((dequeobject *)deque)->maxlen, NULL); -} - -PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque."); - -static PyObject * deque_reduce(dequeobject *deque) { PyObject *dict, *result, *aslist; @@ -1280,12 +1322,12 @@ deque_reduce(dequeobject *deque) return NULL; } if (dict == NULL) { - if (deque->maxlen == -1) + if (deque->maxlen < 0) result = Py_BuildValue("O(O)", Py_TYPE(deque), aslist); else result = Py_BuildValue("O(On)", Py_TYPE(deque), aslist, deque->maxlen); } else { - if (deque->maxlen == -1) + if (deque->maxlen < 0) result = Py_BuildValue("O(OO)O", Py_TYPE(deque), aslist, Py_None, dict); else result = Py_BuildValue("O(On)O", Py_TYPE(deque), aslist, deque->maxlen, dict); @@ -1376,7 +1418,7 @@ deque_richcompare(PyObject *v, PyObject *w, int op) } Py_DECREF(x); Py_DECREF(y); - if (b == -1) + if (b < 0) goto done; } /* We reached the end of one deque or both */ @@ -1459,7 +1501,7 @@ deque_bool(dequeobject *deque) static PyObject * deque_get_maxlen(dequeobject *deque) { - if (deque->maxlen == -1) + if (deque->maxlen < 0) Py_RETURN_NONE; return PyLong_FromSsize_t(deque->maxlen); } @@ -1800,7 +1842,7 @@ dequereviter_next(dequeiterobject *it) item = it->b->data[it->index]; it->index--; it->counter--; - if (it->index == -1 && it->counter > 0) { + if (it->index < 0 && it->counter > 0) { CHECK_NOT_END(it->b->leftlink); it->b = it->b->leftlink; it->index = BLOCKLEN - 1; @@ -2229,13 +2271,13 @@ _count_elements(PyObject *self, PyObject *args) oldval = _PyDict_GetItem_KnownHash(mapping, key, hash); if (oldval == NULL) { - if (_PyDict_SetItem_KnownHash(mapping, key, one, hash) == -1) + if (_PyDict_SetItem_KnownHash(mapping, key, one, hash) < 0) goto done; } else { newval = PyNumber_Add(oldval, one); if (newval == NULL) goto done; - if (_PyDict_SetItem_KnownHash(mapping, key, newval, hash) == -1) + if (_PyDict_SetItem_KnownHash(mapping, key, newval, hash) < 0) goto done; Py_CLEAR(newval); } @@ -2261,7 +2303,7 @@ _count_elements(PyObject *self, PyObject *args) Py_DECREF(oldval); if (newval == NULL) break; - if (PyObject_SetItem(mapping, key, newval) == -1) + if (PyObject_SetItem(mapping, key, newval) < 0) break; Py_CLEAR(newval); Py_DECREF(key); diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 1d583a5..5289222 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -3287,6 +3287,11 @@ timezone_str(PyDateTime_TimeZone *self) Py_INCREF(self->name); return self->name; } + if ((PyObject *)self == PyDateTime_TimeZone_UTC || + (GET_TD_DAYS(self->offset) == 0 && + GET_TD_SECONDS(self->offset) == 0 && + GET_TD_MICROSECONDS(self->offset) == 0)) + return PyUnicode_FromString("UTC"); /* Offset is normalized, so it is negative if days < 0 */ if (GET_TD_DAYS(self->offset) < 0) { sign = '-'; @@ -4083,44 +4088,6 @@ datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us, tzinfo); } -static time_t -_PyTime_DoubleToTimet(double x) -{ - time_t result; - double diff; - - result = (time_t)x; - /* How much info did we lose? time_t may be an integral or - * floating type, and we don't know which. If it's integral, - * we don't know whether C truncates, rounds, returns the floor, - * etc. If we lost a second or more, the C rounding is - * unreasonable, or the input just doesn't fit in a time_t; - * call it an error regardless. Note that the original cast to - * time_t can cause a C error too, but nothing we can do to - * worm around that. - */ - diff = x - (double)result; - if (diff <= -1.0 || diff >= 1.0) { - PyErr_SetString(PyExc_OverflowError, - "timestamp out of range for platform time_t"); - result = (time_t)-1; - } - return result; -} - -/* Round a double to the nearest long. |x| must be small enough to fit - * in a C long; this is not checked. - */ -static double -_PyTime_RoundHalfEven(double x) -{ - double rounded = round(x); - if (fabs(x-rounded) == 0.5) - /* halfway case: round to even */ - rounded = 2.0*round(x/2.0); - return rounded; -} - /* Internal helper. * Build datetime from a Python timestamp. Pass localtime or gmtime for f, * to control the interpretation of the timestamp. Since a double doesn't @@ -4129,32 +4096,17 @@ _PyTime_RoundHalfEven(double x) * to get that much precision (e.g., C time() isn't good enough). */ static PyObject * -datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp, +datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp, PyObject *tzinfo) { time_t timet; - double fraction; - int us; + long us; - timet = _PyTime_DoubleToTimet(timestamp); - if (timet == (time_t)-1 && PyErr_Occurred()) + if (_PyTime_ObjectToTimeval(timestamp, + &timet, &us, _PyTime_ROUND_HALF_EVEN) == -1) return NULL; - fraction = timestamp - (double)timet; - us = (int)_PyTime_RoundHalfEven(fraction * 1e6); - if (us < 0) { - /* Truncation towards zero is not what we wanted - for negative numbers (Python's mod semantics) */ - timet -= 1; - us += 1000000; - } - /* If timestamp is less than one microsecond smaller than a - * full second, round up. Otherwise, ValueErrors are raised - * for some floats. */ - if (us == 1000000) { - timet += 1; - us = 0; - } - return datetime_from_timet_and_us(cls, f, timet, us, tzinfo); + + return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo); } /* Internal helper. @@ -4227,11 +4179,11 @@ static PyObject * datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw) { PyObject *self; - double timestamp; + PyObject *timestamp; PyObject *tzinfo = Py_None; static char *keywords[] = {"timestamp", "tz", NULL}; - if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp", + if (! PyArg_ParseTupleAndKeywords(args, kw, "O|O:fromtimestamp", keywords, ×tamp, &tzinfo)) return NULL; if (check_tzinfo_subclass(tzinfo) < 0) @@ -4255,10 +4207,10 @@ datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw) static PyObject * datetime_utcfromtimestamp(PyObject *cls, PyObject *args) { - double timestamp; + PyObject *timestamp; PyObject *result = NULL; - if (PyArg_ParseTuple(args, "d:utcfromtimestamp", ×tamp)) + if (PyArg_ParseTuple(args, "O:utcfromtimestamp", ×tamp)) result = datetime_from_timestamp(cls, gmtime, timestamp, Py_None); return result; @@ -4761,7 +4713,7 @@ local_timezone(PyDateTime_DateTime *utc_time) if (seconds == NULL) goto error; Py_DECREF(delta); - timestamp = PyLong_AsLong(seconds); + timestamp = _PyLong_AsTime_t(seconds); Py_DECREF(seconds); if (timestamp == -1 && PyErr_Occurred()) return NULL; diff --git a/Modules/_heapqmodule.c b/Modules/_heapqmodule.c index c343862..28604af 100644 --- a/Modules/_heapqmodule.c +++ b/Modules/_heapqmodule.c @@ -66,7 +66,7 @@ siftup(PyListObject *heap, Py_ssize_t pos) /* Bubble up the smaller child until hitting a leaf. */ arr = _PyList_ITEMS(heap); - limit = endpos / 2; /* smallest pos that has no child */ + limit = endpos >> 1; /* smallest pos that has no child */ while (pos < limit) { /* Set childpos to index of smaller child. */ childpos = 2*pos + 1; /* leftmost child position */ @@ -347,7 +347,7 @@ heapify_internal(PyObject *heap, int siftup_func(PyListObject *, Py_ssize_t)) n is odd = 2*j+1, this is (2*j+1-1)/2 = j so j-1 is the largest, and that's again n//2-1. */ - for (i = n/2 - 1 ; i >= 0 ; i--) + for (i = (n >> 1) - 1 ; i >= 0 ; i--) if (siftup_func((PyListObject *)heap, i)) return NULL; Py_RETURN_NONE; @@ -420,7 +420,7 @@ siftup_max(PyListObject *heap, Py_ssize_t pos) /* Bubble up the smaller child until hitting a leaf. */ arr = _PyList_ITEMS(heap); - limit = endpos / 2; /* smallest pos that has no child */ + limit = endpos >> 1; /* smallest pos that has no child */ while (pos < limit) { /* Set childpos to index of smaller child. */ childpos = 2*pos + 1; /* leftmost child position */ diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index 528bcd4..7428aed 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -238,7 +238,8 @@ _io_open_impl(PyModuleDef *module, PyObject *file, const char *mode, int text = 0, binary = 0, universal = 0; char rawmode[6], *m; - int line_buffering, isatty; + int line_buffering; + long isatty; PyObject *raw, *modeobj = NULL, *buffer, *wrapper, *result = NULL; @@ -248,8 +249,8 @@ _io_open_impl(PyModuleDef *module, PyObject *file, const char *mode, _Py_IDENTIFIER(close); if (!PyUnicode_Check(file) && - !PyBytes_Check(file) && - !PyNumber_Check(file)) { + !PyBytes_Check(file) && + !PyNumber_Check(file)) { PyErr_Format(PyExc_TypeError, "invalid file: %R", file); return NULL; } @@ -307,9 +308,9 @@ _io_open_impl(PyModuleDef *module, PyObject *file, const char *mode, /* Parameters validation */ if (universal) { - if (writing || appending) { + if (creating || writing || appending || updating) { PyErr_SetString(PyExc_ValueError, - "can't use U and writing mode at once"); + "mode U cannot be combined with x', 'w', 'a', or '+'"); return NULL; } if (PyErr_WarnEx(PyExc_DeprecationWarning, @@ -437,10 +438,10 @@ _io_open_impl(PyModuleDef *module, PyObject *file, const char *mode, /* wraps into a TextIOWrapper */ wrapper = PyObject_CallFunction((PyObject *)&PyTextIOWrapper_Type, - "Osssi", - buffer, - encoding, errors, newline, - line_buffering); + "Osssi", + buffer, + encoding, errors, newline, + line_buffering); if (wrapper == NULL) goto error; result = wrapper; diff --git a/Modules/_sre.c b/Modules/_sre.c index 957ccbc..6a3d811 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -62,9 +62,6 @@ static char copyright[] = /* -------------------------------------------------------------------- */ /* optional features */ -/* enables fast searching */ -#define USE_FAST_SEARCH - /* enables copy/deepcopy handling (work in progress) */ #undef USE_BUILTIN_COPY diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index ba0a24b..1f013c2 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -2646,7 +2646,9 @@ run_in_subinterp(PyObject *self, PyObject *args) static int check_time_rounding(int round) { - if (round != _PyTime_ROUND_FLOOR && round != _PyTime_ROUND_CEILING) { + if (round != _PyTime_ROUND_FLOOR + && round != _PyTime_ROUND_CEILING + && round != _PyTime_ROUND_HALF_EVEN) { PyErr_SetString(PyExc_ValueError, "invalid rounding"); return -1; } @@ -4112,6 +4114,7 @@ PyInit__testcapi(void) PyModule_AddObject(m, "PY_SSIZE_T_MAX", PyLong_FromSsize_t(PY_SSIZE_T_MAX)); PyModule_AddObject(m, "PY_SSIZE_T_MIN", PyLong_FromSsize_t(PY_SSIZE_T_MIN)); PyModule_AddObject(m, "SIZEOF_PYGC_HEAD", PyLong_FromSsize_t(sizeof(PyGC_Head))); + PyModule_AddObject(m, "SIZEOF_TIME_T", PyLong_FromSsize_t(sizeof(time_t))); Py_INCREF(&PyInstanceMethod_Type); PyModule_AddObject(m, "instancemethod", (PyObject *)&PyInstanceMethod_Type); diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 9ef702a..a48de6a 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -2116,7 +2116,7 @@ PyDoc_STRVAR(os_sched_getaffinity__doc__, "sched_getaffinity($module, pid, /)\n" "--\n" "\n" -"Return the affinity of the process identified by pid.\n" +"Return the affinity of the process identified by pid (or the current process if zero).\n" "\n" "The affinity is returned as a set of CPU identifiers."); @@ -5178,7 +5178,11 @@ PyDoc_STRVAR(os_cpu_count__doc__, "cpu_count($module, /)\n" "--\n" "\n" -"Return the number of CPUs in the system; return None if indeterminable."); +"Return the number of CPUs in the system; return None if indeterminable.\n" +"\n" +"This number is not equivalent to the number of CPUs the current process can\n" +"use. The number of usable CPUs can be obtained with\n" +"``len(os.sched_getaffinity(0))``"); #define OS_CPU_COUNT_METHODDEF \ {"cpu_count", (PyCFunction)os_cpu_count, METH_NOARGS, os_cpu_count__doc__}, @@ -5788,4 +5792,4 @@ exit: #ifndef OS_SET_HANDLE_INHERITABLE_METHODDEF #define OS_SET_HANDLE_INHERITABLE_METHODDEF #endif /* !defined(OS_SET_HANDLE_INHERITABLE_METHODDEF) */ -/*[clinic end generated code: output=95824c52fd034654 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a5c9bef9ad11a20b input=a9049054013a1b77]*/ diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 16ac2fb..ff7867d 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -1,15 +1,16 @@ +#define PY_SSIZE_T_CLEAN #include "Python.h" #include "structmember.h" /* Itertools module written and maintained by Raymond D. Hettinger <python@rcn.com> - Copyright (c) 2003-2013 Python Software Foundation. + Copyright (c) 2003-2015 Python Software Foundation. All rights reserved. */ -/* groupby object ***********************************************************/ +/* groupby object ************************************************************/ typedef struct { PyObject_HEAD @@ -87,8 +88,7 @@ groupby_next(groupbyobject *gbo) else { int rcmp; - rcmp = PyObject_RichCompareBool(gbo->tgtkey, - gbo->currkey, Py_EQ); + rcmp = PyObject_RichCompareBool(gbo->tgtkey, gbo->currkey, Py_EQ); if (rcmp == -1) return NULL; else if (rcmp == 0) @@ -103,8 +103,7 @@ groupby_next(groupbyobject *gbo) newkey = newvalue; Py_INCREF(newvalue); } else { - newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc, - newvalue, NULL); + newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc, newvalue, NULL); if (newkey == NULL) { Py_DECREF(newvalue); return NULL; @@ -178,7 +177,7 @@ static PyMethodDef groupby_methods[] = { reduce_doc}, {"__setstate__", (PyCFunction)groupby_setstate, METH_O, setstate_doc}, - {NULL, NULL} /* sentinel */ + {NULL, NULL} /* sentinel */ }; PyDoc_STRVAR(groupby_doc, @@ -301,8 +300,7 @@ _grouper_next(_grouperobject *igo) newkey = newvalue; Py_INCREF(newvalue); } else { - newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc, - newvalue, NULL); + newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc, newvalue, NULL); if (newkey == NULL) { Py_DECREF(newvalue); return NULL; @@ -330,8 +328,7 @@ _grouper_next(_grouperobject *igo) static PyObject * _grouper_reduce(_grouperobject *lz) { - return Py_BuildValue("O(OO)", Py_TYPE(lz), - lz->parent, lz->tgtkey); + return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->parent, lz->tgtkey); } static PyMethodDef _grouper_methods[] = { @@ -364,7 +361,7 @@ static PyTypeObject _grouper_type = { 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ - (traverseproc)_grouper_traverse,/* tp_traverse */ + (traverseproc)_grouper_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ @@ -385,8 +382,7 @@ static PyTypeObject _grouper_type = { }; - -/* tee object and with supporting function and objects ***************/ +/* tee object and with supporting function and objects ***********************/ /* The teedataobject pre-allocates space for LINKCELLS number of objects. To help the object fit neatly inside cache lines (space for 16 to 32 @@ -401,7 +397,7 @@ static PyTypeObject _grouper_type = { typedef struct { PyObject_HEAD PyObject *it; - int numread; /* 0 <= numread <= LINKCELLS */ + int numread; /* 0 <= numread <= LINKCELLS */ PyObject *nextlink; PyObject *(values[LINKCELLS]); } teedataobject; @@ -409,7 +405,7 @@ typedef struct { typedef struct { PyObject_HEAD teedataobject *dataobj; - int index; /* 0 <= index <= LINKCELLS */ + int index; /* 0 <= index <= LINKCELLS */ PyObject *weakreflist; } teeobject; @@ -466,6 +462,7 @@ static int teedataobject_traverse(teedataobject *tdo, visitproc visit, void * arg) { int i; + Py_VISIT(tdo->it); for (i = 0; i < tdo->numread; i++) Py_VISIT(tdo->values[i]); @@ -515,6 +512,7 @@ teedataobject_reduce(teedataobject *tdo) int i; /* create a temporary list of already iterated values */ PyObject *values = PyList_New(tdo->numread); + if (!values) return NULL; for (i=0 ; i<tdo->numread ; i++) { @@ -582,7 +580,7 @@ static PyMethodDef teedataobject_methods[] = { PyDoc_STRVAR(teedataobject_doc, "Data container common to multiple tee objects."); static PyTypeObject teedataobject_type = { - PyVarObject_HEAD_INIT(0, 0) /* Must fill in type value later */ + PyVarObject_HEAD_INIT(0, 0) /* Must fill in type value later */ "itertools._tee_dataobject", /* tp_name */ sizeof(teedataobject), /* tp_basicsize */ 0, /* tp_itemsize */ @@ -602,7 +600,7 @@ static PyTypeObject teedataobject_type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ teedataobject_doc, /* tp_doc */ (traverseproc)teedataobject_traverse, /* tp_traverse */ (inquiry)teedataobject_clear, /* tp_clear */ @@ -759,9 +757,9 @@ PyDoc_STRVAR(teeobject_doc, "Iterator wrapped to make it copyable"); static PyMethodDef tee_methods[] = { - {"__copy__", (PyCFunction)tee_copy, METH_NOARGS, teecopy_doc}, - {"__reduce__", (PyCFunction)tee_reduce, METH_NOARGS, reduce_doc}, - {"__setstate__", (PyCFunction)tee_setstate, METH_O, setstate_doc}, + {"__copy__", (PyCFunction)tee_copy, METH_NOARGS, teecopy_doc}, + {"__reduce__", (PyCFunction)tee_reduce, METH_NOARGS, reduce_doc}, + {"__setstate__", (PyCFunction)tee_setstate, METH_O, setstate_doc}, {NULL, NULL} /* sentinel */ }; @@ -791,7 +789,7 @@ static PyTypeObject tee_type = { (traverseproc)tee_traverse, /* tp_traverse */ (inquiry)tee_clear, /* tp_clear */ 0, /* tp_richcompare */ - offsetof(teeobject, weakreflist), /* tp_weaklistoffset */ + offsetof(teeobject, weakreflist), /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ (iternextfunc)tee_next, /* tp_iternext */ tee_methods, /* tp_methods */ @@ -857,12 +855,13 @@ PyDoc_STRVAR(tee_doc, "tee(iterable, n=2) --> tuple of n independent iterators."); -/* cycle object **********************************************************/ +/* cycle object **************************************************************/ typedef struct { PyObject_HEAD PyObject *it; PyObject *saved; + Py_ssize_t index; int firstpass; } cycleobject; @@ -902,6 +901,7 @@ cycle_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } lz->it = it; lz->saved = saved; + lz->index = 0; lz->firstpass = 0; return (PyObject *)lz; @@ -911,15 +911,16 @@ static void cycle_dealloc(cycleobject *lz) { PyObject_GC_UnTrack(lz); - Py_XDECREF(lz->saved); Py_XDECREF(lz->it); + Py_XDECREF(lz->saved); Py_TYPE(lz)->tp_free(lz); } static int cycle_traverse(cycleobject *lz, visitproc visit, void *arg) { - Py_VISIT(lz->it); + if (lz->it) + Py_VISIT(lz->it); Py_VISIT(lz->saved); return 0; } @@ -928,57 +929,70 @@ static PyObject * cycle_next(cycleobject *lz) { PyObject *item; - PyObject *it; - PyObject *tmp; - while (1) { + if (lz->it != NULL) { item = PyIter_Next(lz->it); if (item != NULL) { - if (!lz->firstpass && PyList_Append(lz->saved, item)) { + if (lz->firstpass) + return item; + if (PyList_Append(lz->saved, item)) { Py_DECREF(item); return NULL; } return item; } - if (PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_StopIteration)) - PyErr_Clear(); - else - return NULL; - } - if (PyList_Size(lz->saved) == 0) - return NULL; - it = PyObject_GetIter(lz->saved); - if (it == NULL) + /* Note: StopIteration is already cleared by PyIter_Next() */ + if (PyErr_Occurred()) return NULL; - tmp = lz->it; - lz->it = it; - lz->firstpass = 1; - Py_DECREF(tmp); + Py_CLEAR(lz->it); } + if (Py_SIZE(lz->saved) == 0) + return NULL; + item = PyList_GET_ITEM(lz->saved, lz->index); + lz->index++; + if (lz->index >= Py_SIZE(lz->saved)) + lz->index = 0; + Py_INCREF(item); + return item; } static PyObject * cycle_reduce(cycleobject *lz) { - /* Create a new cycle with the iterator tuple, then set - * the saved state on it. - */ - return Py_BuildValue("O(O)(Oi)", Py_TYPE(lz), - lz->it, lz->saved, lz->firstpass); + /* Create a new cycle with the iterator tuple, then set the saved state */ + if (lz->it == NULL) { + PyObject *it = PyObject_GetIter(lz->saved); + if (it == NULL) + return NULL; + if (lz->index != 0) { + _Py_IDENTIFIER(__setstate__); + PyObject *res = _PyObject_CallMethodId(it, &PyId___setstate__, + "n", lz->index); + if (res == NULL) { + Py_DECREF(it); + return NULL; + } + Py_DECREF(res); + } + return Py_BuildValue("O(N)(Oi)", Py_TYPE(lz), it, lz->saved, 1); } + return Py_BuildValue("O(O)(Oi)", Py_TYPE(lz), lz->it, lz->saved, + lz->firstpass); +} static PyObject * cycle_setstate(cycleobject *lz, PyObject *state) { PyObject *saved=NULL; int firstpass; - if (!PyArg_ParseTuple(state, "Oi", &saved, &firstpass)) + + if (!PyArg_ParseTuple(state, "O!i", &PyList_Type, &saved, &firstpass)) return NULL; + Py_INCREF(saved); Py_CLEAR(lz->saved); lz->saved = saved; - Py_XINCREF(lz->saved); lz->firstpass = firstpass != 0; + lz->index = 0; Py_RETURN_NONE; } @@ -1047,7 +1061,7 @@ typedef struct { PyObject_HEAD PyObject *func; PyObject *it; - long start; + long start; } dropwhileobject; static PyTypeObject dropwhile_type; @@ -1137,8 +1151,7 @@ dropwhile_next(dropwhileobject *lz) static PyObject * dropwhile_reduce(dropwhileobject *lz) { - return Py_BuildValue("O(OO)l", Py_TYPE(lz), - lz->func, lz->it, lz->start); + return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->start); } static PyObject * @@ -1189,13 +1202,13 @@ static PyTypeObject dropwhile_type = { Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */ dropwhile_doc, /* tp_doc */ - (traverseproc)dropwhile_traverse, /* tp_traverse */ + (traverseproc)dropwhile_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ (iternextfunc)dropwhile_next, /* tp_iternext */ - dropwhile_methods, /* tp_methods */ + dropwhile_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ @@ -1216,7 +1229,7 @@ typedef struct { PyObject_HEAD PyObject *func; PyObject *it; - long stop; + long stop; } takewhileobject; static PyTypeObject takewhile_type; @@ -1291,7 +1304,7 @@ takewhile_next(takewhileobject *lz) } ok = PyObject_IsTrue(good); Py_DECREF(good); - if (ok == 1) + if (ok > 0) return item; Py_DECREF(item); if (ok == 0) @@ -1302,14 +1315,14 @@ takewhile_next(takewhileobject *lz) static PyObject * takewhile_reduce(takewhileobject *lz) { - return Py_BuildValue("O(OO)l", Py_TYPE(lz), - lz->func, lz->it, lz->stop); + return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->stop); } static PyObject * takewhile_reduce_setstate(takewhileobject *lz, PyObject *state) { int stop = PyObject_IsTrue(state); + if (stop < 0) return NULL; lz->stop = stop; @@ -1353,7 +1366,7 @@ static PyTypeObject takewhile_type = { Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */ takewhile_doc, /* tp_doc */ - (traverseproc)takewhile_traverse, /* tp_traverse */ + (traverseproc)takewhile_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ @@ -1374,7 +1387,7 @@ static PyTypeObject takewhile_type = { }; -/* islice object ************************************************************/ +/* islice object *************************************************************/ typedef struct { PyObject_HEAD @@ -1410,7 +1423,8 @@ islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (PyErr_Occurred()) PyErr_Clear(); PyErr_SetString(PyExc_ValueError, - "Stop argument for islice() must be None or an integer: 0 <= x <= sys.maxsize."); + "Stop argument for islice() must be None or " + "an integer: 0 <= x <= sys.maxsize."); return NULL; } } @@ -1425,14 +1439,16 @@ islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (PyErr_Occurred()) PyErr_Clear(); PyErr_SetString(PyExc_ValueError, - "Stop argument for islice() must be None or an integer: 0 <= x <= sys.maxsize."); + "Stop argument for islice() must be None or " + "an integer: 0 <= x <= sys.maxsize."); return NULL; } } } if (start<0 || stop<-1) { PyErr_SetString(PyExc_ValueError, - "Indices for islice() must be None or an integer: 0 <= x <= sys.maxsize."); + "Indices for islice() must be None or " + "an integer: 0 <= x <= sys.maxsize."); return NULL; } @@ -1529,6 +1545,7 @@ islice_reduce(isliceobject *lz) * then 'setstate' with the next and count */ PyObject *stop; + if (lz->it == NULL) { PyObject *empty_list; PyObject *empty_it; @@ -1558,6 +1575,7 @@ static PyObject * islice_setstate(isliceobject *lz, PyObject *state) { Py_ssize_t cnt = PyLong_AsSsize_t(state); + if (cnt == -1 && PyErr_Occurred()) return NULL; lz->cnt = cnt; @@ -1772,7 +1790,7 @@ static PyTypeObject starmap_type = { }; -/* chain object ************************************************************/ +/* chain object **************************************************************/ typedef struct { PyObject_HEAD @@ -1848,32 +1866,32 @@ chain_next(chainobject *lz) PyObject *item; if (lz->source == NULL) - return NULL; /* already stopped */ + return NULL; /* already stopped */ if (lz->active == NULL) { PyObject *iterable = PyIter_Next(lz->source); if (iterable == NULL) { Py_CLEAR(lz->source); - return NULL; /* no more input sources */ + return NULL; /* no more input sources */ } lz->active = PyObject_GetIter(iterable); Py_DECREF(iterable); if (lz->active == NULL) { Py_CLEAR(lz->source); - return NULL; /* input not iterable */ + return NULL; /* input not iterable */ } } - item = PyIter_Next(lz->active); + item = (*Py_TYPE(lz->active)->tp_iternext)(lz->active); if (item != NULL) return item; if (PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_StopIteration)) PyErr_Clear(); else - return NULL; /* input raised an exception */ + return NULL; /* input raised an exception */ } Py_CLEAR(lz->active); - return chain_next(lz); /* recurse and use next active */ + return chain_next(lz); /* recurse and use next active */ } static PyObject * @@ -1899,6 +1917,7 @@ static PyObject * chain_setstate(chainobject *lz, PyObject *state) { PyObject *source, *active=NULL; + if (! PyArg_ParseTuple(state, "O|O", &source, &active)) return NULL; @@ -1925,13 +1944,13 @@ Alternate chain() contructor taking a single iterable argument\n\ that evaluates lazily."); static PyMethodDef chain_methods[] = { - {"from_iterable", (PyCFunction) chain_new_from_iterable, METH_O | METH_CLASS, - chain_from_iterable_doc}, + {"from_iterable", (PyCFunction) chain_new_from_iterable, METH_O | METH_CLASS, + chain_from_iterable_doc}, {"__reduce__", (PyCFunction)chain_reduce, METH_NOARGS, reduce_doc}, {"__setstate__", (PyCFunction)chain_setstate, METH_O, setstate_doc}, - {NULL, NULL} /* sentinel */ + {NULL, NULL} /* sentinel */ }; static PyTypeObject chain_type = { @@ -1983,10 +2002,10 @@ static PyTypeObject chain_type = { typedef struct { PyObject_HEAD - PyObject *pools; /* tuple of pool tuples */ - Py_ssize_t *indices; /* one index per pool */ - PyObject *result; /* most recently returned result tuple */ - int stopped; /* set to 1 when the product iterator is exhausted */ + PyObject *pools; /* tuple of pool tuples */ + Py_ssize_t *indices; /* one index per pool */ + PyObject *result; /* most recently returned result tuple */ + int stopped; /* set to 1 when the iterator is exhausted */ } productobject; static PyTypeObject product_type; @@ -2005,7 +2024,8 @@ product_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyObject *tmpargs = PyTuple_New(0); if (tmpargs == NULL) return NULL; - if (!PyArg_ParseTupleAndKeywords(tmpargs, kwds, "|n:product", kwlist, &repeat)) { + if (!PyArg_ParseTupleAndKeywords(tmpargs, kwds, "|n:product", + kwlist, &repeat)) { Py_DECREF(tmpargs); return NULL; } @@ -2295,7 +2315,7 @@ product((0,1), (0,1), (0,1)) --> (0,0,0) (0,0,1) (0,1,0) (0,1,1) (1,0,0) ..."); static PyTypeObject product_type = { PyVarObject_HEAD_INIT(NULL, 0) "itertools.product", /* tp_name */ - sizeof(productobject), /* tp_basicsize */ + sizeof(productobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)product_dealloc, /* tp_dealloc */ @@ -2337,15 +2357,15 @@ static PyTypeObject product_type = { }; -/* combinations object ************************************************************/ +/* combinations object *******************************************************/ typedef struct { PyObject_HEAD - PyObject *pool; /* input converted to a tuple */ - Py_ssize_t *indices; /* one index per result element */ - PyObject *result; /* most recently returned result tuple */ - Py_ssize_t r; /* size of result tuple */ - int stopped; /* set to 1 when the combinations iterator is exhausted */ + PyObject *pool; /* input converted to a tuple */ + Py_ssize_t *indices; /* one index per result element */ + PyObject *result; /* most recently returned result tuple */ + Py_ssize_t r; /* size of result tuple */ + int stopped; /* set to 1 when the iterator is exhausted */ } combinationsobject; static PyTypeObject combinations_type; @@ -2555,17 +2575,16 @@ combinations_setstate(combinationsobject *lz, PyObject *state) Py_ssize_t i; Py_ssize_t n = PyTuple_GET_SIZE(lz->pool); - if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != lz->r) - { + if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != lz->r) { PyErr_SetString(PyExc_ValueError, "invalid arguments"); return NULL; } - for (i=0; i<lz->r; i++) - { + for (i=0; i<lz->r; i++) { Py_ssize_t max; PyObject* indexObject = PyTuple_GET_ITEM(state, i); Py_ssize_t index = PyLong_AsSsize_t(indexObject); + if (index == -1 && PyErr_Occurred()) return NULL; /* not an integer */ max = i + n - lz->r; @@ -2652,7 +2671,7 @@ static PyTypeObject combinations_type = { }; -/* combinations with replacement object *******************************************/ +/* combinations with replacement object **************************************/ /* Equivalent to: @@ -2682,11 +2701,11 @@ static PyTypeObject combinations_type = { */ typedef struct { PyObject_HEAD - PyObject *pool; /* input converted to a tuple */ + PyObject *pool; /* input converted to a tuple */ Py_ssize_t *indices; /* one index per result element */ PyObject *result; /* most recently returned result tuple */ - Py_ssize_t r; /* size of result tuple */ - int stopped; /* set to 1 when the cwr iterator is exhausted */ + Py_ssize_t r; /* size of result tuple */ + int stopped; /* set to 1 when the cwr iterator is exhausted */ } cwrobject; static PyTypeObject cwr_type; @@ -2703,8 +2722,9 @@ cwr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) Py_ssize_t i; static char *kwargs[] = {"iterable", "r", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:combinations_with_replacement", kwargs, - &iterable, &r)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "On:combinations_with_replacement", + kwargs, &iterable, &r)) return NULL; pool = PySequence_Tuple(iterable); @@ -2869,8 +2889,7 @@ cwr_reduce(cwrobject *lz) indices = PyTuple_New(lz->r); if (!indices) return NULL; - for (i=0; i<lz->r; i++) - { + for (i=0; i<lz->r; i++) { PyObject* index = PyLong_FromSsize_t(lz->indices[i]); if (!index) { Py_DECREF(indices); @@ -2896,10 +2915,10 @@ cwr_setstate(cwrobject *lz, PyObject *state) } n = PyTuple_GET_SIZE(lz->pool); - for (i=0; i<lz->r; i++) - { + for (i=0; i<lz->r; i++) { PyObject* indexObject = PyTuple_GET_ITEM(state, i); Py_ssize_t index = PyLong_AsSsize_t(indexObject); + if (index < 0 && PyErr_Occurred()) return NULL; /* not an integer */ /* clamp the index */ @@ -2984,7 +3003,7 @@ static PyTypeObject cwr_type = { }; -/* permutations object ************************************************************ +/* permutations object ******************************************************** def permutations(iterable, r=None): 'permutations(range(3), 2) --> (0,1) (0,2) (1,0) (1,2) (2,0) (2,1)' @@ -3011,12 +3030,12 @@ def permutations(iterable, r=None): typedef struct { PyObject_HEAD - PyObject *pool; /* input converted to a tuple */ - Py_ssize_t *indices; /* one index per element in the pool */ - Py_ssize_t *cycles; /* one rollover counter per element in the result */ - PyObject *result; /* most recently returned result tuple */ - Py_ssize_t r; /* size of result tuple */ - int stopped; /* set to 1 when the permutations iterator is exhausted */ + PyObject *pool; /* input converted to a tuple */ + Py_ssize_t *indices; /* one index per element in the pool */ + Py_ssize_t *cycles; /* one rollover counter per element in the result */ + PyObject *result; /* most recently returned result tuple */ + Py_ssize_t r; /* size of result tuple */ + int stopped; /* set to 1 when the iterator is exhausted */ } permutationsobject; static PyTypeObject permutations_type; @@ -3231,7 +3250,7 @@ permutations_reduce(permutationsobject *po) indices = PyTuple_New(n); if (indices == NULL) goto err; - for (i=0; i<n; i++){ + for (i=0; i<n; i++) { PyObject* index = PyLong_FromSsize_t(po->indices[i]); if (!index) goto err; @@ -3241,8 +3260,7 @@ permutations_reduce(permutationsobject *po) cycles = PyTuple_New(po->r); if (cycles == NULL) goto err; - for (i=0; i<po->r; i++) - { + for (i=0 ; i<po->r ; i++) { PyObject* index = PyLong_FromSsize_t(po->cycles[i]); if (!index) goto err; @@ -3270,15 +3288,12 @@ permutations_setstate(permutationsobject *po, PyObject *state) return NULL; n = PyTuple_GET_SIZE(po->pool); - if (PyTuple_GET_SIZE(indices) != n || - PyTuple_GET_SIZE(cycles) != po->r) - { + if (PyTuple_GET_SIZE(indices) != n || PyTuple_GET_SIZE(cycles) != po->r) { PyErr_SetString(PyExc_ValueError, "invalid arguments"); return NULL; } - for (i=0; i<n; i++) - { + for (i=0; i<n; i++) { PyObject* indexObject = PyTuple_GET_ITEM(indices, i); Py_ssize_t index = PyLong_AsSsize_t(indexObject); if (index < 0 && PyErr_Occurred()) @@ -3291,8 +3306,7 @@ permutations_setstate(permutationsobject *po, PyObject *state) po->indices[i] = index; } - for (i=0; i<po->r; i++) - { + for (i=0; i<po->r; i++) { PyObject* indexObject = PyTuple_GET_ITEM(cycles, i); Py_ssize_t index = PyLong_AsSsize_t(indexObject); if (index < 0 && PyErr_Occurred()) @@ -3334,11 +3348,11 @@ permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1)"); static PyTypeObject permutations_type = { PyVarObject_HEAD_INIT(NULL, 0) - "itertools.permutations", /* tp_name */ + "itertools.permutations", /* tp_name */ sizeof(permutationsobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ - (destructor)permutations_dealloc, /* tp_dealloc */ + (destructor)permutations_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -3355,13 +3369,13 @@ static PyTypeObject permutations_type = { 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */ - permutations_doc, /* tp_doc */ - (traverseproc)permutations_traverse, /* tp_traverse */ + permutations_doc, /* tp_doc */ + (traverseproc)permutations_traverse,/* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ - (iternextfunc)permutations_next, /* tp_iternext */ + (iternextfunc)permutations_next, /* tp_iternext */ permuations_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ @@ -3372,11 +3386,11 @@ static PyTypeObject permutations_type = { 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - permutations_new, /* tp_new */ + permutations_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ }; -/* accumulate object ************************************************************/ +/* accumulate object ********************************************************/ typedef struct { PyObject_HEAD @@ -3445,7 +3459,7 @@ accumulate_next(accumulateobject *lz) { PyObject *val, *oldtotal, *newtotal; - val = PyIter_Next(lz->it); + val = (*Py_TYPE(lz->it)->tp_iternext)(lz->it); if (val == NULL) return NULL; @@ -3477,7 +3491,7 @@ accumulate_reduce(accumulateobject *lz) return Py_BuildValue("O(OO)O", Py_TYPE(lz), lz->it, lz->binop?lz->binop:Py_None, lz->total?lz->total:Py_None); - } +} static PyObject * accumulate_setstate(accumulateobject *lz, PyObject *state) @@ -3640,7 +3654,7 @@ compress_next(compressobject *lz) ok = PyObject_IsTrue(selector); Py_DECREF(selector); - if (ok == 1) + if (ok > 0) return datum; Py_DECREF(datum); if (ok < 0) @@ -3653,7 +3667,7 @@ compress_reduce(compressobject *lz) { return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->data, lz->selectors); - } +} static PyMethodDef compress_methods[] = { {"__reduce__", (PyCFunction)compress_reduce, METH_NOARGS, @@ -3672,44 +3686,44 @@ static PyTypeObject compress_type = { PyVarObject_HEAD_INIT(NULL, 0) "itertools.compress", /* tp_name */ sizeof(compressobject), /* tp_basicsize */ - 0, /* tp_itemsize */ + 0, /* tp_itemsize */ /* methods */ (destructor)compress_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - compress_doc, /* tp_doc */ - (traverseproc)compress_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ + Py_TPFLAGS_BASETYPE, /* tp_flags */ + compress_doc, /* tp_doc */ + (traverseproc)compress_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ (iternextfunc)compress_next, /* tp_iternext */ - compress_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - compress_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ + compress_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + compress_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ }; @@ -3790,8 +3804,7 @@ filterfalse_next(filterfalseobject *lz) ok = PyObject_IsTrue(item); } else { PyObject *good; - good = PyObject_CallFunctionObjArgs(lz->func, - item, NULL); + good = PyObject_CallFunctionObjArgs(lz->func, item, NULL); if (good == NULL) { Py_DECREF(item); return NULL; @@ -3810,9 +3823,8 @@ filterfalse_next(filterfalseobject *lz) static PyObject * filterfalse_reduce(filterfalseobject *lz) { - return Py_BuildValue("O(OO)", Py_TYPE(lz), - lz->func, lz->it); - } + return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it); +} static PyMethodDef filterfalse_methods[] = { {"__reduce__", (PyCFunction)filterfalse_reduce, METH_NOARGS, @@ -3832,7 +3844,7 @@ static PyTypeObject filterfalse_type = { sizeof(filterfalseobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ - (destructor)filterfalse_dealloc, /* tp_dealloc */ + (destructor)filterfalse_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -3850,7 +3862,7 @@ static PyTypeObject filterfalse_type = { Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */ filterfalse_doc, /* tp_doc */ - (traverseproc)filterfalse_traverse, /* tp_traverse */ + (traverseproc)filterfalse_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ @@ -4089,15 +4101,15 @@ static PyTypeObject count_type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + Py_TPFLAGS_BASETYPE, /* tp_flags */ count_doc, /* tp_doc */ - (traverseproc)count_traverse, /* tp_traverse */ + (traverseproc)count_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ (iternextfunc)count_next, /* tp_iternext */ - count_methods, /* tp_methods */ + count_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ @@ -4263,9 +4275,7 @@ static PyTypeObject repeat_type = { PyObject_GC_Del, /* tp_free */ }; -/* ziplongest object ************************************************************/ - -#include "Python.h" +/* ziplongest object *********************************************************/ typedef struct { PyObject_HEAD @@ -4304,7 +4314,7 @@ zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ittuple = PyTuple_New(tuplesize); if (ittuple == NULL) return NULL; - for (i=0; i < tuplesize; ++i) { + for (i=0; i < tuplesize; i++) { PyObject *item = PyTuple_GET_ITEM(args, i); PyObject *it = PyObject_GetIter(item); if (it == NULL) { @@ -4445,6 +4455,7 @@ zip_longest_reduce(ziplongestobject *lz) */ int i; PyObject *args = PyTuple_New(PyTuple_GET_SIZE(lz->ittuple)); + if (args == NULL) return NULL; for (i=0; i<PyTuple_GET_SIZE(lz->ittuple); i++) { @@ -4496,7 +4507,7 @@ static PyTypeObject ziplongest_type = { sizeof(ziplongestobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ - (destructor)zip_longest_dealloc, /* tp_dealloc */ + (destructor)zip_longest_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -4513,8 +4524,8 @@ static PyTypeObject ziplongest_type = { 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */ - zip_longest_doc, /* tp_doc */ - (traverseproc)zip_longest_traverse, /* tp_traverse */ + zip_longest_doc, /* tp_doc */ + (traverseproc)zip_longest_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ @@ -4530,7 +4541,7 @@ static PyTypeObject ziplongest_type = { 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - zip_longest_new, /* tp_new */ + zip_longest_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ }; diff --git a/Modules/nismodule.c b/Modules/nismodule.c index 64eb5db..b6a855c 100644 --- a/Modules/nismodule.c +++ b/Modules/nismodule.c @@ -76,11 +76,7 @@ nis_mapname (char *map, int *pfix) *pfix = 0; for (i=0; aliases[i].alias != 0L; i++) { - if (!strcmp (aliases[i].alias, map)) { - *pfix = aliases[i].fix; - return aliases[i].map; - } - if (!strcmp (aliases[i].map, map)) { + if (!strcmp (aliases[i].alias, map) || !strcmp (aliases[i].map, map)) { *pfix = aliases[i].fix; return aliases[i].map; } diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 854a749..467ce2c 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -4605,11 +4605,11 @@ utime_fd(utime_t *ut, int fd) #define PATH_UTIME_HAVE_FD 0 #endif +#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES) +# define UTIME_HAVE_NOFOLLOW_SYMLINKS +#endif -#define UTIME_HAVE_NOFOLLOW_SYMLINKS \ - (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)) - -#if UTIME_HAVE_NOFOLLOW_SYMLINKS +#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS static int utime_nofollow_symlinks(utime_t *ut, char *path) @@ -4771,7 +4771,7 @@ os_utime_impl(PyModuleDef *module, path_t *path, PyObject *times, utime.now = 1; } -#if !UTIME_HAVE_NOFOLLOW_SYMLINKS +#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS) if (follow_symlinks_specified("utime", follow_symlinks)) goto exit; #endif @@ -4825,7 +4825,7 @@ os_utime_impl(PyModuleDef *module, path_t *path, PyObject *times, #else /* MS_WINDOWS */ Py_BEGIN_ALLOW_THREADS -#if UTIME_HAVE_NOFOLLOW_SYMLINKS +#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) result = utime_nofollow_symlinks(&utime, path->narrow); else @@ -5756,14 +5756,14 @@ os.sched_getaffinity pid: pid_t / -Return the affinity of the process identified by pid. +Return the affinity of the process identified by pid (or the current process if zero). The affinity is returned as a set of CPU identifiers. [clinic start generated code]*/ static PyObject * os_sched_getaffinity_impl(PyModuleDef *module, pid_t pid) -/*[clinic end generated code: output=b431a8f310e369e7 input=eaf161936874b8a1]*/ +/*[clinic end generated code: output=b431a8f310e369e7 input=983ce7cb4a565980]*/ { int cpu, ncpus, count; size_t setsize; @@ -9482,7 +9482,7 @@ os__getdiskusage_impl(PyModuleDef *module, Py_UNICODE *path) */ struct constdef { char *name; - long value; + int value; }; static int @@ -9490,7 +9490,10 @@ conv_confname(PyObject *arg, int *valuep, struct constdef *table, size_t tablesize) { if (PyLong_Check(arg)) { - *valuep = PyLong_AS_LONG(arg); + int value = _PyLong_AsInt(arg); + if (value == -1 && PyErr_Occurred()) + return 0; + *valuep = value; return 1; } else { @@ -11199,11 +11202,15 @@ get_terminal_size(PyObject *self, PyObject *args) os.cpu_count Return the number of CPUs in the system; return None if indeterminable. + +This number is not equivalent to the number of CPUs the current process can +use. The number of usable CPUs can be obtained with +``len(os.sched_getaffinity(0))`` [clinic start generated code]*/ static PyObject * os_cpu_count_impl(PyModuleDef *module) -/*[clinic end generated code: output=c59ee7f6bce832b8 input=d55e2f8f3823a628]*/ +/*[clinic end generated code: output=c59ee7f6bce832b8 input=e7c8f4ba6dbbadd3]*/ { int ncpu = 0; #ifdef MS_WINDOWS diff --git a/Modules/readline.c b/Modules/readline.c index f6b52a0..09877f2 100644 --- a/Modules/readline.c +++ b/Modules/readline.c @@ -840,7 +840,7 @@ on_hook(PyObject *func) if (r == Py_None) result = 0; else { - result = PyLong_AsLong(r); + result = _PyLong_AsInt(r); if (result == -1 && PyErr_Occurred()) goto error; } diff --git a/Modules/sre_lib.h b/Modules/sre_lib.h index 128c71e..6ad2ab7 100644 --- a/Modules/sre_lib.h +++ b/Modules/sre_lib.h @@ -1256,7 +1256,32 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern) prefix, prefix_len, prefix_skip)); TRACE(("charset = %p\n", charset)); -#if defined(USE_FAST_SEARCH) + if (prefix_len == 1) { + /* pattern starts with a literal character */ + SRE_CHAR c = (SRE_CHAR) prefix[0]; +#if SIZEOF_SRE_CHAR < 4 + if ((SRE_CODE) c != prefix[0]) + return 0; /* literal can't match: doesn't fit in char width */ +#endif + end = (SRE_CHAR *)state->end; + while (ptr < end) { + while (*ptr != c) { + if (++ptr >= end) + return 0; + } + TRACE(("|%p|%p|SEARCH LITERAL\n", pattern, ptr)); + state->start = ptr; + state->ptr = ptr + prefix_skip; + if (flags & SRE_INFO_LITERAL) + return 1; /* we got all of it */ + status = SRE(match)(state, pattern + 2*prefix_skip, 0); + if (status != 0) + return status; + ++ptr; + } + return 0; + } + if (prefix_len > 1) { /* pattern starts with a known prefix. use the overlap table to skip forward as fast as we possibly can */ @@ -1305,32 +1330,8 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern) } return 0; } -#endif - if (pattern[0] == SRE_OP_LITERAL) { - /* pattern starts with a literal character. this is used - for short prefixes, and if fast search is disabled */ - SRE_CHAR c = (SRE_CHAR) pattern[1]; -#if SIZEOF_SRE_CHAR < 4 - if ((SRE_CODE) c != pattern[1]) - return 0; /* literal can't match: doesn't fit in char width */ -#endif - end = (SRE_CHAR *)state->end; - while (ptr < end) { - while (*ptr != c) { - if (++ptr >= end) - return 0; - } - TRACE(("|%p|%p|SEARCH LITERAL\n", pattern, ptr)); - state->start = ptr; - state->ptr = ++ptr; - if (flags & SRE_INFO_LITERAL) - return 1; /* we got all of it */ - status = SRE(match)(state, pattern + 2, 0); - if (status != 0) - break; - } - } else if (charset) { + if (charset) { /* pattern starts with a character from a known set */ end = (SRE_CHAR *)state->end; for (;;) { |