
20.04.21 17:56, Ethan Furman пише:
urllib.urlencode currently uses `str()` on its non-bytes objects before encoding the result. This causes a compatibility break when integer module constants are converted to IntEnum, as `str(IntEnum.MEMBER)` no longer returns the integer representation; however, `format()` does still return the integer representation.
The fix is to add a separate branch to check if the argument is an Enum, and use the value if so -- but it got me wondering: in general, are there differences between calling str() vs calling format() on Python objects?
format() without format specifier and str() should return the same value in general, otherwise it will confuse users. But str() for enum should in general return a symbolic name, not the attached value which is an implementation detail. This is the purpose of enums. I think that __format__ should return the same as __str__ by default. This can break some user code, but custom __str__ can break it as well. Some breakage is inevitable when we convert some constants in the stdlib to enums. If user want to get an integer representation of an enum member, it should use IntEnum.MEMBER.value or int(IntEnum.MEMBER).