3 ms·
Even worse IMHO is the semantics of strings being implicitly iterable. Often it ends up that you're intending to iterate over something for item in orders
by philsnow 12y ago
Even worse IMHO is the semantics of strings being implicitly iterable. Often it ends up that you're intending to iterate over something
for item in orders:
do_something_with(item)
So if `foo` is usually `[Order(...), Order(...), ...]` but due to a bug elsewhere, sometimes `foo` is "some string". Then you get a mysterious exception somewhere down in `do_something_with` or one of its callees at run time, and all because the above snippet calls do_something_with('s'), do_something_with('o'), etc.
In my experience, this behavior is so seldom what is wanted that it should be removable (with a from __future__ style declaration) or just off by default.
- dalke 12y agoI use "for c in s", to read characters in a string, pretty often. Here's an example from Python3.2's quopri.py: def unhex(s): """Get the integer value of a hexadecimal number.""" bits = 0 for c in s: c = bytes((c,)) if b'0' <= c <= b'9': i = ord('0') elif b'a' <= c <= b'f': i = ord('a')-10 elif b'A' <= c <= b'F': i = ord(b'A')-10 else: assert False, "non-hex digit "+repr(c) bits = bits*16 + (ord(c) - i) return bits Here's another example of iterating over characters in a string, from pydoc.py: if any((0xD800 <= ord(ch) <= 0xDFFF) for ch in name) It seems like a pretty heavy-weight prohibition for little gain. After all, you could pass foo = open("/etc/passwd") and still end up with a large gap between making the bug and its consequences.
- unwind 12y agoShouldn't unhex() just be int(s, 16)? Not sure what it adds, but I don't quite understand it yet and perhaps there's something magic in the context of MIME quoted printable that I'm missing.
- dalke 12y agoThat is an excellent point! Based on my reading, there's nothing magic. The context is: elif i+2 < n and ishex(line[i+1:i+2]) and ishex(line[i+2:i+3]): new = new + bytes((unhex(line[i+1:i+3]),)); i = i+3 I tweaked it to new = new + bytes((int(line[i+1:i+3], 16),)); i = i+3 and the self-tests still pass. (I also changed the 16 to 15 to double-check that the tests were actually exercising that code.) It's not part of the public API, so it looks like it can simply be removed. Do you want to file the bug report? Or perhaps it's best to update http://bugs.python.org/issue21869 http://bugs.python.org/issue21869 ("Clean up quopri, correct method names encodestring and decodestring")?
- yoha 12y ago> It's not part of the public API, so it looks like it can simply be removed. https://docs.python.org/3/library/functions.html#int https://docs.python.org/3/library/functions.html#int So that is actually standard. Maybe I just don't know what you mean by public API though.