One thing I love about .startswith() and .endswith() is matching multiple options. It's a little funny the multiple options must be a tuple exactly (not a list, not a set, not an iterator), but whatever. It would be about to lack that symmetry in the .cut_suffix() method.
E.g now:
if fname.endswith(('.jpg', '.png', '.gif)): ...
I'd expect to be able to do:
basename = fname.cut_suffix(('.jpg', '.png', '.gif))
An idea worth considering: one can think of the “strip” family of methods as currently taking an iterable of strings as an argument (since a string is itself an sequence of strings):
"abcd".rstrip("dc") 'ab'
It would not be a huge logical leap to allow them to take any iterable. Backward compatible, no new methods:
fname.rstrip(('.jpg', '.png', '.gif'))
It even, in my opinion, can clarify "classic" strip/rstrip/lstrip usage:
"abcd".rstrip(("d", "c")) 'ab'
Maybe I’m missing a breaking case though, or this isn’t as clear for others. Thoughts? Brandt