Issue34425
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2018-08-18 00:18 by Jason Spencer, last changed 2022-04-11 14:59 by admin. This issue is now closed.
Messages (6) | |||
---|---|---|---|
msg323688 - (view) | Author: Jason Spencer (Jason Spencer) | Date: 2018-08-18 00:18 | |
Objects with __str__ but WITHOUT __format__ are string-convertible and default-to-str formattable. But the explicit use of '{:s}' as a format string fails to format these objects as expected. Either it is no longer the case that '{}' and '{:s}' are equivalent format strings, or formatting for {:s} is broken. Users would not expect the following to be true. (Tested in 3.5.3 and 3.6. Maybe be the same in later releases.) Python 3.5.3 (default, Jan 19 2017, 14:11:04) [GCC 6.3.0 20170118] on linux Type "help", "copyright", "credits" or "license" for more information. >>> class Coord: ... def __init__(self, a, b): ... self.a=a ... self.b=b ... def __str__(self): ... return '{:d}:{:d}'.format(self.a, self.b) ... >>> c = Coord(3,4) >>> str(c) '3:4' >>> '{:s}'.format(c) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported format string passed to Coord.__format__ >>> '{}'.format(c) '3:4' >>> '{!s:s}'.format(c) '3:4' >>> |
|||
msg323689 - (view) | Author: Martin Panter (martin.panter) * | Date: 2018-08-18 04:59 | |
It looks like you are describing the result of Issue 7994. Documentation: https://docs.python.org/release/3.5.3/reference/datamodel.html#object.__format__ https://docs.python.org/release/3.5.3/whatsnew/3.4.html#api-and-feature-removals |
|||
msg323719 - (view) | Author: Eric V. Smith (eric.smith) * | Date: 2018-08-18 17:12 | |
I agree this is the desired behavior, and not a bug. Because you are not specifying a __format__ in your class, object.__format__ is being called. By design, it does not understand any formatting specifiers, instead reserving them for your class to implement. "!s" is the correct way to convert your type to a string. Either that, or add a __format__ that understands "s". Note that not all types understand "s", for example, datetime. |
|||
msg323798 - (view) | Author: Jason Spencer (Jason Spencer) | Date: 2018-08-20 16:26 | |
Then I would argue that it is at least a documentation bug. The 3.6 format spec mini language still claims that {} is equivalent to {:s}, which now is only conditionally true. I would also argue that having different behavior for {} and {:s}, which are semantically the same in the client's eye, forces the client code to understand more about the object they are stringifying than should be necessary. If one works, so should the other by all descriptions of the format spec. If the format spec is *just* ':s', the library should call the target's __str__ if __format__ is not defined. The library seems willing to do this for the empty format string, but not when the client code specifically asks for a string.... On Sat, Aug 18, 2018 at 10:12 AM Eric V. Smith <report@bugs.python.org> wrote: > > Eric V. Smith <eric@trueblade.com> added the comment: > > I agree this is the desired behavior, and not a bug. > > Because you are not specifying a __format__ in your class, > object.__format__ is being called. By design, it does not understand any > formatting specifiers, instead reserving them for your class to implement. > "!s" is the correct way to convert your type to a string. Either that, or > add a __format__ that understands "s". > > Note that not all types understand "s", for example, datetime. > > ---------- > assignee: -> eric.smith > nosy: +eric.smith > stage: -> resolved > status: pending -> closed > > _______________________________________ > Python tracker <report@bugs.python.org> > <https://bugs.python.org/issue34425> > _______________________________________ > |
|||
msg323887 - (view) | Author: Eric V. Smith (eric.smith) * | Date: 2018-08-22 14:28 | |
About translating ":s" to "": > The library seems willing to do this for the empty format string, but not when the client code specifically asks for a string.... You're not asking for a string when you specify ":s". You're asking the object to interpret "s" however it wants. For example, if the object is a datetime, you're asking for the output to be "s": >>> f'{datetime.datetime.now():s}' 's' versus: >>> f'{datetime.datetime.now()}' '2018-08-22 10:27:25.188891' It's precisely because we want to let the object interpret the string that Python no longer guesses as to what you might mean. For example, say you have a MyDate object, that doesn't support __format__, and you want Python to decide that format(MyDate(), 's') means is the same as format(MyDate(), ''). But later you decide that you want the format strings to call strftime (like datetime does). You couldn't do that without breaking existing usage of your library. This actually happened with complex when I added complex.__format__. |
|||
msg323891 - (view) | Author: Eric V. Smith (eric.smith) * | Date: 2018-08-22 15:44 | |
Forgot to add: I haven't looked at the docs yet, but I agree they should be clear on this issue. The docs should say: for types that implement the documented mini-language, "s" is the same as "". It's just that not all types implement the mini-language (like datetime, and probably many non-standard, user-defined types). If they don't say that, can you open a separate documentation issue? Thanks. Or, maybe the problem is that the docs make it seem like all types do (or should?) implement the mini-language? That's definitely not true, and they shouldn't say that. |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-11 14:59:04 | admin | set | github: 78606 |
2018-08-22 15:44:49 | eric.smith | set | messages: + msg323891 |
2018-08-22 14:28:21 | eric.smith | set | messages: + msg323887 |
2018-08-20 16:26:18 | Jason Spencer | set | messages: + msg323798 |
2018-08-18 17:12:08 | eric.smith | set | status: pending -> closed nosy: + eric.smith messages: + msg323719 assignee: eric.smith stage: resolved |
2018-08-18 04:59:44 | martin.panter | set | status: open -> pending nosy: + martin.panter messages: + msg323689 superseder: object.__format__ should reject format strings resolution: not a bug |
2018-08-18 00:18:56 | Jason Spencer | create |