Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Poor handling of multi-line string literals using slash continuation #1183

Closed
peterjc opened this issue Nov 29, 2019 · 3 comments · Fixed by #1132
Closed

Poor handling of multi-line string literals using slash continuation #1183

peterjc opened this issue Nov 29, 2019 · 3 comments · Fixed by #1132
Labels
T: bug Something isn't working

Comments

@peterjc
Copy link

peterjc commented Nov 29, 2019

Describe the bug A clear and concise description of what the bug is.

To Reproduce Steps to reproduce the behavior:

  1. Make a small Python file containing the following:
if True:
    # Pointless if-statement just for indentation here:
    print("\
    \nMESSAGE - printing a multi-line message to the user here as a single\
    \nlong string literal taking multiple lines of Python source code.")
  1. Run Black on it with default arguments
  2. Observer the following output:
if True:
    # Pointless if-statement just for indentation here:
    print(
        "\
    \nMESSAGE - printing a multi-line message to the user here as a single\
    \nlong string literal taking multiple lines of Python source code."
    )

I find this apparently mixed indentation very ugly, but it works and may be the least bad solution without removing the slash line continuation.

Expected behavior A clear and concise description of what you expected to happen.

The ideal output would be something like this, but would require black to break up string literals (already covered on separate issues like #182):

if True:
    # Pointless if-statement just for indentation here:
    print(
        "\nMESSAGE - printing a multi-line message to the user here as a single"
        "\nlong string literal taking multiple lines of Python source code."
    )

A possible compromise would be remove the slash continuation giving a long string:

if True:
    # Pointless if-statement just for indentation here:
    print(
        "\nMESSAGE - printing a multi-line message to the user here as a single\nlong string literal taking multiple lines of Python source code."
    )

The output is not ideal, but would be easy to spot with linters, and the behaviour is simple to explain.

Environment (please complete the following information):

  • Version: 19.10b0 according to pip (although --version reports 19.3b0)
  • OS and Python version: macOS, Python 3.7.4 (conda)

Same on master checked with https://black.now.sh/?version=master

Additional context

This example is based on some real code https://github.com/biopython/biopython/blob/biopython-175/Scripts/Restriction/ranacompiler.py#L279 originally written in 2004.

@peterjc
Copy link
Author

peterjc commented Dec 1, 2019

If #1132 would fix this too, great 👍

@ambv
Copy link
Collaborator

ambv commented Mar 3, 2020

This will be handled as part of #182, as solved by #1132.

@ambv ambv closed this as completed Mar 3, 2020
ambv pushed a commit that referenced this issue May 8, 2020
This pull request's main intention is to wraps long strings (as requested by #182); however, it also provides better string handling in general and, in doing so, closes the following issues:

Closes #26
Closes #182
Closes #933
Closes #1183
Closes #1243
@peterjc
Copy link
Author

peterjc commented Mar 21, 2022

(Reviewing this with black v22.1.0 now that the functionality is in a stable release)

Input (with a hidden wrong assumption about the four spaces for indentation):

if True:
    # Pointless if-statement just for indentation here:
    print("\
    \nMESSAGE - printing a multi-line message to the user here as a single\
    \nlong string literal taking multiple lines of Python source code.")

With black v22.1.0 (no change from when I opened this issue),

if True:
    # Pointless if-statement just for indentation here:
    print(
        "\
    \nMESSAGE - printing a multi-line message to the user here as a single\
    \nlong string literal taking multiple lines of Python source code."
    )

With black v22.1.0 and --preview:

if True:
    # Pointless if-statement just for indentation here:
    print(
        "    \nMESSAGE - printing a multi-line message to the user here as a single   "
        " \nlong string literal taking multiple lines of Python source code."
    )

Note that the original really does mean the output lines have four trailing spaces! This is probably a common user error, a wrong assumption about how the line continuation \ is interpreted.

That means black with --preview highlights this error, and the author might then revise their code so something like this:

if True:
    # Pointless if-statement just for indentation here:
    print(
        "\nMESSAGE - printing a multi-line message to the user here as a single"
        "\nlong string literal taking multiple lines of Python source code."
    )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T: bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants