[Python-ideas] Deprecate str.find

Nick Coghlan ncoghlan at gmail.com
Sun Jul 17 14:38:32 CEST 2011


On Sun, Jul 17, 2011 at 8:56 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> I can't really see that they do "everything and their reverse". There are
> two basic strategies: return an out-of-bound value, and raise an exception,
> both of which Python already does.

In a language that accepts negative indices, -1 is not out of bounds,
and hence is an objectively bad value to return. If str.find()
returned None for missing substrings, we wouldn't be having this
discussion. However, backwards compatibility requirements mean that
option is not available to us.

Is this a language wart where the correct answer is to tell everyone
new to the language that complains about the current behaviour to
"suck it up and learn to live with it"? Maybe. But claiming that
str.find() is a *good* API in a language that accepts negative indices
would be flat out wrong. Good *enough*, maybe, but not good in an
absolute sense.

As I see it, there are a few options.

1. Do nothing.

Quite a reasonable option. str.find() is flawed and str.index() can be
annoying to use, but fixing this may not be worth the hassle. However,
this is not the same as claiming the str.find() behaviour is a good
API - it's just acknowledging the wart and deciding not to address it.

2. Add an alternate behaviour to str.index() that allows the exception
to optionally be converted into a sentinel value.

Inspired by getattr, getitem, dict.get, next, etc. Made messy by the
need for the sentinel to go after the existing arguments and the fact
that the number of sane sentinel values is extremely limited (aside
from None, the only remotely useful possibilities I can think of are 0
and len(seq), and even those only hypothetically). This solution
requires changing a builtin method API, as well as adding keyword
argument support to CPython string methods.

Also raises the question of whether or not the Sequence ABC (and
sequences in the stdlib) should be adjusted accordingly.

3. Search for a more general solution that simplifies the following
common try/except pattern into a single expression (or simple
statement):
  try:
    val = f()
  except RelevantException:
    val = default
  # further operations using val

This has been attempted before, but never successfully as it isn't
*that* common (so ugly solutions are never going to be accepted as
better than the status quo) and it's extremely difficult to come up
with a syntax that neatly captures the 3 necessary elements and can
still be handled easily by the parser.

Since I have no reason to believe 3 will get any further than it has
in that past, making an explicit decision between 1 and 2 is the
reason I'd like to see a PEP. PEPs aren't just about getting new
features into the language - the Rejected ones are also about
documenting the reasons we have chosen *not* to do certain things (and
the Deferred ones point out that some things are just hard to do in a
way that provides a net benefit to the language).

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia



More information about the Python-ideas mailing list