3 ms·
I was not sure about the difficulty. Python has some really weird behaviors with some of the custom __format__. For instance f"{'None':<010}" will pad out, bu
by the_mitsuhiko 1y ago
I was not sure about the difficulty. Python has some really weird behaviors with some of the custom __format__. For instance f"{'None':<010}" will pad out, but f"{None:<010}" will error. The only one I ended up putting in is the gotcha that bool is an int subclass and gets the int behavior for custom format parameters (which almost sounds like a bug). f'{''''''''''''}' is also a weird one, but that is mostly an issue with the string concatenation syntax and not fstrings :)
There definitely are some more odd / confusing ones.
- OJFord 1y ago> For instance f"{'None':<010}" will pad out, but f"{None:<010}" will error. Is that any different than being surprised that 1 + 1 is 2 and '1' + '1' is '11'?
- lionkor 1y agonot really, since None stringifies to "None", so you would expect None -> "None" -> padding and whatnot added
- the_mitsuhiko 1y agoI don't know, but I find this quite confusing: >>> f"{'42':<10}" '42 ' >>> f"{42:<10}" '42 ' >>> f"{None:<10}" Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported format string passed to NoneType.__format__ (Or any other type. What can be padded is quite inconsistent)
- OJFord 1y agoAh I see, fair enough I suppose. Quite nice for catching bugs though to be honest - since you'll hit an error and realise you need to handle the None case appropriately, rather than a more subtle 'None' appearing somewhere bug.
- zahlman 1y agoThat is strange (and would have made a better question I think). Why is it willing to stringify the integer, if not the NoneType?
- davepeck 1y ago> What can be padded is quite inconsistent. Yes, I agree. “What works” is type dependent and Python’s builtin types don’t always behave the same way. I know you know this, but for those who may not have run across it before and are curious: f-strings invoke the format() builtin on the evaluated value. In the case of None: >>> format(None) # as in f"{None}" 'None' >>> format(None, '<10') # as in f"{None:<10}" TypeError: unsupported format string passed to NoneType.__format__ Under the hood, format() turns around and calls type(value).__format__(format_spec). Looking at the docstrings: >>> help(type(None).__format__) Help on built-in function __format__: __format__(self, format_spec, /) Default object formatter. Return str(self) if format_spec is empty. Raise Type Error otherwise. That is, NoneType inherits Python's default object formatter, which doesn't support any format spec; if it's not empty, it's a TypeError. On the other hand, `str` and `int` both have deep custom __format__ implementations that can do much more, like padding [0]. PS: upcoming t-strings in 3.14 add another twist to format specs: rather than being type dependent, "what works" depends on whatever code processes the Template instance. Unlike with f-strings, format() is not called automatically when t-strings are evaluated; in fact, there's no requirement that processing code does anything with the format specs at all. (Good processing code probably will want to do something!) [0] https://docs.python.org/3/library/string.html#format-specification-mini-language https://docs.python.org/3/library/string.html#format-specifi...