[New-bugs-announce] [issue24243] behavior for finding an empty string is inconsistent with documentation

swanson report at bugs.python.org
Wed May 20 06:02:42 CEST 2015

New submission from swanson:

Perhaps this has been addressed elsewhere, but I couldn't find it.  To me, semantically, the whole idea of finding nothing, whether in something or in nothing is complete and utter nonsense.  I'm a fail-quickly, fail-loudly kind of guy, and I'd prefer that any attempt to find nothing would result in an exception being raised.

But for whatever reason, the following behavior has long existed:
>>> "".index("") == "A".index("") == 0
>>> "" in "" and b"" in b"" and b"" in bytearray(b"")
>>> "" in "A" and b"" in b"A" and b"" in bytearray(b"A")

The Problem:
The various string types (str, bytes, bytearray) all have the following functions: count, find, rfind, index, rindex
Each of these functions accepts optional parameters "start" and "end".  The documentation for each says something like "Optional arguments start and end are interpreted as in slice notation."  This is not the case.

On the one hand:
>>> "".find("") == ""[0:0].find("") == "".find("", 0, 0) == 0

Consistent so far, however:
>>> "".find("") == ""[1:0].find("") == 0 and "".find("", 1, 0) == -1

So, you see that 'start' and 'end' are NOT in all cases interpreted the same way as slicing.  This problem has been around forever, affecting both Python 3 and 2, so I don't know how many people's code you'd break if you changed the behavior to make it consistent with the docs.  But if it's not going to be changed, it should at least be a well-documented "feature" of the functions with a line or two of explanation in the relevant docs:

The built-in types bytes, bytearray, and str also have the functions "startswith" and "endswith" that also take optional 'start' and 'end' arguments.  The documentation does not specifically say (as for count, (r)find, and (r)index) that these are "interpreted as in slice notation".  Instead, it says: "With optional start, test string beginning at that position. With optional end, stop comparing string at that position."  That wording is equally confusing and erroneous.  The natural interpretation of that would lead you to believe that, unlike slicing:
"A".startswith("A",0,0) == True
however it's really == False because the 'end' index is like slicing.

Now, as to the interpretation of finding nothing, it's a mixed bag:

For str:
>>> "".startswith("",0,0)
>>> "".startswith("",1,0)
>>> "".endswith("",0,0)
>>> "".endswith("",1,0)

For bytes: (and the same for bytearray)
>>> b"".startswith(b"",0,0)
>>> b"".startswith(b"",1,0)
>>> b"".endswith(b"",0,0)
>>> b"".endswith(b"",1,0)

assignee: docs at python
components: Documentation
messages: 243640
nosy: docs at python, swanson
priority: normal
severity: normal
status: open
title: behavior for finding an empty string is inconsistent with documentation
type: behavior

Python tracker <report at bugs.python.org>

More information about the New-bugs-announce mailing list