21/26, with a couple of sleep-deprived brainfarts and a misclick. Learned very little, although I had the wrong reasoning for one of the ones I got right (tested afterward). I don't even use the {var=} thing or walrus operator, though.
I would definitely not do nearly as well on jsdate.wtf. I really still think JS has the greater WTFs.
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.
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!)
Ah 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.
I would definitely not do nearly as well on jsdate.wtf. I really still think JS has the greater WTFs.