Inconsistent behaviour os str.find/str.index when providing optional parameters

Giacomo Alzetta giacomo.alzetta at
Wed Nov 21 13:43:57 CET 2012

I just came across this:

>>> 'spam'.find('', 5)

Now, reading find's documentation:

>>> print(str.find.__doc__)
S.find(sub [,start [,end]]) -> int

Return the lowest index in S where substring sub is found,
such that sub is contained within S[start:end].  Optional
arguments start and end are interpreted as in slice notation.

Return -1 on failure.

Now, the empty string is a substring of every string so how can find fail?
find, from the doc, should be generally be equivalent to S[start:end].find(substring) + start, except if the substring is not found but since the empty string is a substring of the empty string it should never fail.

Looking at the source code for find(in stringlib/find.h):

stringlib_find(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
               const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
               Py_ssize_t offset)
    Py_ssize_t pos;

    if (str_len < 0)
        return -1;

I believe it should be:

    if (str_len < 0)
        return (sub_len == 0 ? 0 : -1);

Is there any reason of having this unexpected behaviour or was this simply overlooked?

More information about the Python-list mailing list