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

add support for formatting reStructuredText code snippets #9003

Merged
merged 6 commits into from
Dec 5, 2023

Commits on Dec 5, 2023

  1. ruff_python_formatter: fix bug in doctest formatting

    This fixes a bug where if the very last line in a docstring is a
    doctest, then it wasn't getting formatted.
    
    We do a little more than fix that bug in this commit. In particular, we
    industrialize how we handle actions by using a queue. Instead of trying
    to do too much with each action, we make each one a bit simpler and
    build the infrastructure necessary to permit more arbitrary composition.
    This in particular lets us handle weird corner cases like "the code
    example and the docstring end at the same time" without much fuss.
    
    In essence, actions like Format and Reset no longer carry the "original"
    line. Instead of doing that, we generate two actions: the first to
    format and the second (if necessary) to print the original line.
    
    This infrastructure will become more apparently useful when dealing with
    reStructuredText blocks.
    BurntSushi committed Dec 5, 2023
    Configuration menu
    Copy the full SHA
    8a9a877 View commit details
    Browse the repository at this point in the history
  2. ruff_python_formatter: simplify format's contract

    There was really no good reason to have it panic if the code block given
    is empty. Instead, we can just return `None` and everything will get
    handled correctly. (It will turn into a `Reset` with zero lines, which
    will in turn be a no-op.)
    
    In practice I do believe empty code blocks are not possible, but I felt
    like this makes the code a bit more robust.
    BurntSushi committed Dec 5, 2023
    Configuration menu
    Copy the full SHA
    6483d89 View commit details
    Browse the repository at this point in the history
  3. ruff_python_formatter: force space indent in code snippets

    The comment in the source code should explain, but basically,
    if the user has tab indentation enabled, then this winds up
    screwing with code snippet formatting. The essential problem
    seems to be that docstring normalization strips tabs, and this
    interplay between code snippet reformatting with tabs winds up
    making formatting non-idempotent.
    
    We justify this hard-coded option by pointing out that tabs
    get stripped as part of docstring normalization anyway.
    BurntSushi committed Dec 5, 2023
    Configuration menu
    Copy the full SHA
    6cebe63 View commit details
    Browse the repository at this point in the history
  4. ruff_python_formatter: group imports

    Small style tweak.
    
    . o O { too bad `imports_granularity` isn't stable in rustfmt yet }
    BurntSushi committed Dec 5, 2023
    Configuration menu
    Copy the full SHA
    148372c View commit details
    Browse the repository at this point in the history
  5. ruff_python_formatter: add reStructuredText docstring formatting support

    This commit makes use of the refactoring done in prior commits to slot
    in reStructuredText support. Essentially, we add a new type of code
    example and look for *both* literal blocks and code block directives.
    Literal blocks are treated as Python by default because it seems to be a
    common practice[1].
    
    That is, literal blocks like this:
    
    ```
    def example():
        """
        Here's an example::
    
            foo( 1 )
    
        All done.
        """
        pass
    ```
    
    Will get reformatted. And code blocks (via reStructuredText directives)
    will also get reformatted:
    
    ```
    def example():
        """
        Here's an example:
    
        .. code-block:: python
    
            foo( 1 )
    
        All done.
        """
        pass
    ```
    
    When looking for a code block, it is possible for it to become invalid.
    In which case, we back out of looking for a code example and print the
    lines out as they are. As with doctest formatting, if reformatting the
    code would result in invalid Python or if the code collected from the
    block is invalid, then formatting is also skipped.
    
    A number of tests have been added to check both the formatting and
    resetting behavior. Mixed indentation is also tested a fair bit, since
    one of my initial attempts at dealing with mixed indentation ended up
    not working.
    
    Closes #8859
    
    [1]: adamchainz/blacken-docs#195
    BurntSushi committed Dec 5, 2023
    Configuration menu
    Copy the full SHA
    e53053e View commit details
    Browse the repository at this point in the history
  6. ruff_python_formatter: add line breaks between fields

    This is what seems consistent with the prevailing code.
    BurntSushi committed Dec 5, 2023
    Configuration menu
    Copy the full SHA
    618e48d View commit details
    Browse the repository at this point in the history