New submission from swanson:
Background:
-----------
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
True
>>> "" in "" and b"" in b"" and b"" in bytearray(b"")
True
>>> "" in "A" and b"" in b"A" and b"" in bytearray(b"A")
True
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
True
Consistent so far, however:
>>> "".find("") == ""[1:0].find("") == 0 and "".find("", 1, 0) == -1
True
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:
https://docs.python.org/3/library/stdtypes.html#bytes-and-bytearray-operations
https://docs.python.org/3/library/stdtypes.html#string-methods
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)
True
>>> "".startswith("",1,0)
True
>>> "".endswith("",0,0)
True
>>> "".endswith("",1,0)
True
For bytes: (and the same for bytearray)
>>> b"".startswith(b"",0,0)
True
>>> b"".startswith(b"",1,0)
False
>>> b"".endswith(b"",0,0)
True
>>> b"".endswith(b"",1,0)
False
----------
assignee: docs@python
components: Documentation
messages: 243640
nosy: docs@python, swanson
priority: normal
severity: normal
status: open
title: behavior for finding an empty string is inconsistent with documentation
type: behavior
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue24243>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com