classification
Title: str.replace does strange things when given a negative count
Type: behavior Stage: resolved
Components: Documentation Versions: Python 3.1, Python 3.2, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: docs@python Nosy List: LambertDW, ajaksu2, dmajnemer, docs@python, georg.brandl, orsenthil, rhettinger, terry.reedy
Priority: normal Keywords:

Created on 2009-03-04 10:52 by dmajnemer, last changed 2010-09-08 13:02 by orsenthil. This issue is now closed.

Messages (10)
msg83119 - (view) Author: David Majnemer (dmajnemer) Date: 2009-03-04 10:52
str.replace("", "", "asdf", -1) returns "asdf", I believe this is not
correct and strictly speaking not up to the documentation posted. I am
of the opinion that it should function like str.replace("", "", "asdf",
0) which returns ""
msg83122 - (view) Author: Daniel Diniz (ajaksu2) (Python triager) Date: 2009-03-04 14:56
Confirmed in trunk and py3k. Changing to RFE, set it to behavior if you
disagree.

Python 2.4 does return "" for str.replace("", "", "asdf", -1), the
change happened in rev46226, with the effbot adding this snippet (by
Andrew Dalke?):

      if (maxcount < 0) {
             maxcount = PY_SSIZE_T_MAX;
      } else if (maxcount == 0 || PyString_GET_SIZE(self) == 0) {
           /* nothing to do; return the original string */
           return return_self(self);
      }


I'm not sure the current behavior can be considered better than what
David proposes, but I also wonder whether it matters at all.
msg83123 - (view) Author: Senthil Kumaran (orsenthil) * (Python committer) Date: 2009-03-04 15:04
And also look at the help on string.replace which sets -1 as the
default value for maxsplit optional argument and which again defaults
to replace-all.
Clearly, maxsplit= -1 is not equal to maxsplit = 0.

replace(s, old, new, maxsplit=-1)
    replace (str, old, new[, maxsplit]) -> string

    Return a copy of string str with all occurrences of substring
    old replaced by new. If the optional argument maxsplit is
    given, only the first maxsplit occurrences are replaced.

- Daniel, thanks for digging this out from Py2.4, unless we get an
rationale behind this change, my only though on this issue was -
document the maxsplit argument  saying that -1 defaults to replace
all.
msg83127 - (view) Author: David W. Lambert (LambertDW) Date: 2009-03-04 16:49
I completely agree that this is a documentation issue.

Also, or perhaps for foolish completeness, in

http://docs.python.org/3.0/library/stdtypes.html

we would point out that the following group of string methods also work
for bytes and bytearrays.  Of these, only str type has format method.

"String Methods

String objects support the methods listed below. Note that none of these
methods take keyword arguments.

In addition, Python’s strings support the sequence type methods
described in the Sequence Types — str, bytes, bytearray, list, tuple,
range section. To output formatted strings, see the String Formatting
section. Also, see the re module for string functions based on regular
expressions."
msg113371 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2010-08-09 03:58
Changing to doc issue as two people suggested. Can anyone suggest new text to add?
msg113402 - (view) Author: Senthil Kumaran (orsenthil) * (Python committer) Date: 2010-08-09 09:04
Fixed the doc string for release27-maint in revision r83879.
py3k (r83880) and release31-maint in r83881.
msg113629 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2010-08-11 21:23
FWIW, we should be cautious about documenting all behaviors.  It is arguable that this was an implementation detail and not a guaranteed behavior.  As soon as you document it, people will rely on the API and all other implementations will need to change in order to comply.

Please consider whether this doc change should be reverted.
msg113655 - (view) Author: Senthil Kumaran (orsenthil) * (Python committer) Date: 2010-08-12 03:36
I am fine with your proposal, Raymond. When I went about the change the docstrings, I did notice that it is not an intentional feature to provide negative values in the replace argument. The negative value (-1 as count) was being used somewhat as a sentinel value to denote replace-all.

I have no problem in reverting current documentation fix, but as a fix we can remove the existing reference of -1 in docstrings of str.replace so that it does not cause any confusing, which was the point of the original bug-report.
msg113659 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2010-08-12 07:00
Thank you.  Please do the reversion and the docstring fixup.
msg115867 - (view) Author: Senthil Kumaran (orsenthil) * (Python committer) Date: 2010-09-08 13:02
Reverted the changes in r84626 (release27-maint), r84629(py3k), r84630 (release31-maint).

- Minor doc clarification included wherein maxreplace is the argument instead of maxsplit in py27.

- Also, did not bother to remove -1 in maxreplace. It is used as sentinel value for an optional argument. As it is not explicitly documented, the negative value for arg should not be relied upon.
History
Date User Action Args
2010-09-08 13:02:55orsenthilsetstatus: open -> closed

messages: + msg115867
2010-08-12 07:00:14rhettingersetmessages: + msg113659
2010-08-12 03:36:14orsenthilsetmessages: + msg113655
2010-08-11 21:23:17rhettingersetstatus: closed -> open
nosy: + rhettinger
messages: + msg113629

2010-08-09 09:04:19orsenthilsetstatus: open -> closed
type: enhancement -> behavior
messages: + msg113402

resolution: fixed
stage: needs patch -> resolved
2010-08-09 03:58:47terry.reedysetassignee: georg.brandl -> docs@python
components: + Documentation, - Interpreter Core
versions: + Python 3.2
nosy: + terry.reedy, docs@python

messages: + msg113371
stage: test needed -> needs patch
2009-04-05 15:17:19georg.brandlsetassignee: georg.brandl

nosy: + georg.brandl
2009-03-04 16:49:51LambertDWsetnosy: + LambertDW
messages: + msg83127
2009-03-04 15:04:57orsenthilsetnosy: + orsenthil
messages: + msg83123
2009-03-04 14:56:06ajaksu2settype: enhancement
stage: test needed
messages: + msg83122
nosy: + ajaksu2
versions: + Python 3.1, Python 2.7, - Python 2.5
2009-03-04 10:52:10dmajnemercreate