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 _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com