[Python-Dev] PEP 461 - Adding % and {} formatting to bytes (original) (raw)
Steven D'Aprano steve at pearwood.info
Fri Jan 17 08:47:37 CET 2014
- Previous message: [Python-Dev] PEP 461 - Adding % and {} formatting to bytes
- Next message: [Python-Dev] PEP 461 - Adding % and {} formatting to bytes
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Thu, Jan 16, 2014 at 08:23:13AM -0800, Ethan Furman wrote:
As I understand it, str.format will call the object's format. So, for example, if I say:
u'the value is: %d' % myNum(17) then it will be myNum.format that gets called, not int.format;
I seem to have missed something, because I am completely confused... Why are you talking about str.format and then show an example using % instead?
%d calls str, not format. This is in Python 3.3:
py> class MyNum(int): ... def str(self): ... print("Calling MyNum.str") ... return super().str() ... def format(self): ... print("Calling MyNum.format") ... return super().format() ... py> n = MyNum(17) py> u"%d" % n Calling MyNum.str '17'
By analogy, if we have a bytes %d formatting, surely it should either:
(1) call type(n).bytes(n), which is guaranteed to raise if the result isn't ASCII (i.e. like len() raises if the result isn't an int); or
(2) call type(n).str(n).encode("ascii", "strict").
Personally, I lean towards (2), even though that means you can't have a single class provide an ASCII string to b'%d' and a non-ASCII string to u'%d'.
this is precisely what we don't want, since can't know that myNum is only going to return ASCII characters.
It seems to me that Consenting Adults applies here. If class MyNum returns a non-ASCII string, then you ought to get a runtime exception, exactly the same as happens with just about every other failure in Python. If you don't want that possible exception, then don't use MyNum, or explicitly wrap it in a call to int:
b'the value is: %d' % int(MyNum(17))
The worst solution would be to completely ignore MyNum.str. That's a nasty violation of the Principle Of Least Surprise, and will lead to confusion ("why isn't my class' str method being called?") and bugs.
Explicit is better than implicit -- better to explicitly wrap MyNum in a call to int() than to have bytes %d automagically do it for you;
Special cases aren't special enough to break the rules -- bytes %d isn't so special that standard Python rules about calling special methods should be ignored;
Errors should never pass silently -- if MyNum does the wrong thing when used with bytes %d, you should get an exception.
This is why I would have bytes.format, as part of its parsing, call int, index, or float depending on the format code; so the above example would have bytes.format calling int() on myNum(17),
The above example you give doesn't have any bytes in it. Can you explain what you meant to say? I'm guessing you intended this:
b'the value is: %d' % MyNum(17)
rather than using u'' as actually given, but I don't really know.
-- Steven
- Previous message: [Python-Dev] PEP 461 - Adding % and {} formatting to bytes
- Next message: [Python-Dev] PEP 461 - Adding % and {} formatting to bytes
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]