[Python-3000] find -> index patch (original) (raw)

Jack Diederich jack at psynchronous.com
Thu Aug 24 02:39:48 CEST 2006


On Wed, Aug 23, 2006 at 02🔞59PM -0700, Guido van Rossum wrote:

Here's the patch (by Hasan Diwan, BTW) for people's perusal. It just gets rid of all uses of find/rfind from Lib; it doesn't actually modify stringobject.c or unicodeobject.c. It doesn't use [r]partition()'; someone could look for opportunities to use that separately.

I make a go at doing an idiomatic convertion of the first few modules tagged by 'grep find( *.py' in Lib, patch attached.

WOW, I love partition. In all the instances that weren't a simple "in" test I ended up using [r]partition. In some cases one of the returned strings gets thrown away but in those cases it is guaranteed to be small. The new code is usually smaller than the old and generally clearer. ex/ cgi.py

If folks like the way this partial set looks I'll convert the rest.

-Jack -------------- next part -------------- Index: Lib/CGIHTTPServer.py

--- Lib/CGIHTTPServer.py (revision 51530) +++ Lib/CGIHTTPServer.py (working copy) @@ -106,16 +106,9 @@ def run_cgi(self): """Execute a CGI script.""" dir, rest = self.cgi_info - i = rest.rfind('?') - if i >= 0: - rest, query = rest[:i], rest[i+1:] - else: - query = '' - i = rest.find('/') - if i >= 0: - script, rest = rest[:i], rest[i:] - else: - script, rest = rest, '' + (rest, sep, query) = rest.rpartition('?') + (rest, sep, script) = rest.partition('/') + rest = sep + rest # keep the slash scriptname = dir + '/' + script scriptfile = self.translate_path(scriptname) if not os.path.exists(scriptfile): Index: Lib/asynchat.py

--- Lib/asynchat.py (revision 51530) +++ Lib/asynchat.py (working copy) @@ -125,14 +125,13 @@ # collect data to the prefix # 3) end of buffer does not match any prefix: # collect data - terminator_len = len(terminator) - index = self.ac_in_buffer.find(terminator) - if index != -1: + (data, term_found, more_data) = self.ac_in_buffer.partition(terminator) + if term_found: # we found the terminator - if index > 0: + if data: # don't bother reporting the empty string (source of subtle bugs) - self.collect_incoming_data (self.ac_in_buffer[:index]) - self.ac_in_buffer = self.ac_in_buffer[index+terminator_len:] + self.collect_incoming_data(data) + self.ac_in_buffer = more_data # This does the Right Thing if the terminator is changed here. self.found_terminator() else: Index: Lib/cookielib.py

--- Lib/cookielib.py (revision 51530) +++ Lib/cookielib.py (working copy) @@ -531,8 +531,10 @@ return True if not is_HDN(A): return False - i = A.rfind(B) - if i == -1 or i == 0: + if (not B): + return False + (before_B, sep, after_B) = A.rpartition(B) + if not sep or not before_B: # A does not have form NB, or N is the empty string return False if not B.startswith("."): @@ -595,7 +597,7 @@ """ erhn = req_host = request_host(request) - if req_host.find(".") == -1 and not IPV4_RE.search(req_host): + if "." not in req_host and not IPV4_RE.search(req_host): erhn = req_host + ".local" return req_host, erhn @@ -616,16 +618,12 @@ def request_port(request): host = request.get_host() - i = host.find(':') - if i >= 0: - port = host[i+1:] - try: - int(port) - except ValueError: - _debug("nonnumeric port: '%s'", port) - return None - else: - port = DEFAULT_HTTP_PORT + port = host.partition(':')[-1] or DEFAULT_HTTP_PORT + try: + int(port) + except ValueError: + debug("nonnumeric port: '%s'", port) + return None return port # Characters in addition to A-Z, a-z, 0-9, '', '.', and '-' that don't @@ -676,13 +674,9 @@ '.local' """ - i = h.find(".") - if i >= 0: - #a = h[:i] # this line is only here to show what a is - b = h[i+1:] - i = b.find(".") - if is_HDN(h) and (i >= 0 or b == "local"): - return "."+b + (a, sep, b) = h.partition(".") + if sep and is_HDN(h) and ("." in b or b == "local"): + return "."+b return h def is_third_party(request): @@ -986,11 +980,9 @@ # XXX This should probably be compared with the Konqueror # (kcookiejar.cpp) and Mozilla implementations, but it's a # losing battle. - i = domain.rfind(".") - j = domain.rfind(".", 0, i) - if j == 0: # domain like .foo.bar - tld = domain[i+1:] - sld = domain[j+1:i] + (extra, dot, tld) = domain.rpartition(".") + (extra, dot, sld) = extra.rpartition(".") + if not extra: # domain like .foo.bar if sld.lower() in ("co", "ac", "com", "edu", "org", "net", "gov", "mil", "int", "aero", "biz", "cat", "coop", "info", "jobs", "mobi", "museum", "name", "pro", @@ -1002,7 +994,7 @@ undotted_domain = domain[1:] else: undotted_domain = domain - embedded_dots = (undotted_domain.find(".") >= 0) + embedded_dots = ("." in undotted_domain) if not embedded_dots and domain != ".local": _debug(" non-local domain %s contains no embedded dot", domain) @@ -1024,8 +1016,7 @@ if (cookie.version > 0 or (self.strict_ns_domain & self.DomainStrictNoDots)): host_prefix = req_host[:-len(domain)] - if (host_prefix.find(".") >= 0 and - not IPV4_RE.search(req_host)): + if ("." in host_prefix and not IPV4_RE.search(req_host)): _debug(" host prefix %s for domain %s contains a dot", host_prefix, domain) return False @@ -1462,13 +1453,13 @@ else: path_specified = False path = request_path(request) - i = path.rfind("/") - if i != -1: + (path, sep, dummy) = path.rpartition("/") + if sep: if version == 0: # Netscape spec parts company from reality here - path = path[:i] + pass else: - path = path[:i+1] + path = path + sep if len(path) == 0: path = "/" # set default domain Index: Lib/cgi.py

--- Lib/cgi.py (revision 51530) +++ Lib/cgi.py (working copy) @@ -340,10 +340,10 @@ key = plist.pop(0).lower() pdict = {} for p in plist: - i = p.find('=') - if i >= 0: - name = p[:i].strip().lower() - value = p[i+1:].strip() + (name, sep_found, value) = p.partition('=') + if (sep_found): + name = name.strip().lower() + value = value.strip() if len(value) >= 2 and value[0] == value[-1] == '"': value = value[1:-1] value = value.replace('\\', '\').replace('\"', '"') Index: Lib/ConfigParser.py

--- Lib/ConfigParser.py (revision 51530) +++ Lib/ConfigParser.py (working copy) @@ -468,9 +468,9 @@ if vi in ('=', ':') and ';' in optval: # ';' is a comment delimiter only if it follows # a spacing character

@@ -599,14 +599,13 @@ if depth > MAX_INTERPOLATION_DEPTH: raise InterpolationDepthError(option, section, rest) while rest:



More information about the Python-3000 mailing list