Have you looked at textwrap.dedent?
raise ValueError("File exists, not uploading: "
f"{filename} -> {bucket}, {key}")
...which is short enough that it's readable, and it's clear where exactly each variable is going. It's the single obvious solution, so much so that I don't spend a second thinking about it (very Pythonic!). Compare it to using `str.format` with the same continued indentation: raise ValueError(("File exists, not uploading: {filename} -> "
"{bucket}, {key}").format(filename=filename,
bucket=bucket,
key=key))
Even this minimal example looks terrible! Remember that a lot of exceptions are raised within multiply-nested blocks, and then format pushes things farther to the right (while also ruining your automated string-literal concatenation, hence the extra parentheses), leaving very little room for the format arguments. You can use a more self-consistent and readable indentation strategy: raise ValueError(
(
"File exists, not uploading: {filename} -> "
"{bucket}, {key}"
).format(filename, bucket, key)
)
This is unquestionably more pleasant to read than the former, but it's 3 times longer than the simple f-string solution, and I would argue it is not any more readable than the f-string for this simple example. My point with having a `str.wrap` builtin is that at least you could use the docstring convention of terminating multi-line strings on a newline, which would get rid of the string concatenation issues while leaving you a consistent (albeit diminished by the "wrap" call) amount of rightward room for the `format` args: raise ValueError("""File exists, not uploading: {filename} ->
{bucket}, {key}
""".dedent().format(filename=filename,
bucket=bucket, key=key))
Maybe a little bit better than the first one, especially if you're writing a longer docstring and don't want to think about string concatenation. But still a kludge. You can use positional formatting to shorten things up, but the fundamental weakness of `str.format` remains. str_fmt = "File exists, not uploading: {filename} -> {bucket}, {key}"
fmt_vals = dict(filename=filename, bucket=bucket, key=key)
raise ValueError(str_fmt.dedent().format(**fmt_vals)) raise ValueError(“File exists, not uploading: {filename} -> {bucket}, {key}”.format(**locals())) raise ValueError(("File exists, not uploading: {filename} -> "
"{bucket}, {key}").format(filename=filename, bucket=bucket, key=key))