how to dynamically change indentation in a multiline string?

Question:

I’m using docstrings to document my code with Sphinx. I recently started to use ruff to lint my code and It is by default applying D212 instead of D213. The only difference being that the first line of the docstring (short description) must start on the first line.

It breaks one of the decorator that I’m using (deprecated) as it cannot handle both types. The decorator handles docstring as followed:

docstring = textwrap.dedent(wrapped.__doc__ or "")
# do stuff with docstring 

How can I update the docstring parsing to handle docstring starting on a newline (D213) and starting on the first line (D212) the same way ?

# respecting D213
def func_a():
    """
    one liner
    
    Args: 
        toto
    """

# respecting D212
def func_a():
    """one liner 
    
    Args: 
        toto
    """

I tried to manipulate func_b.__doc__ in combination with dedent with no success.

Asked By: Pierrick Rambaud

||

Answers:

# respecting D212
def func_b():
    """
    one liner 

    Args: 
        toto
    """

After some digging I came up with the following code:

docstring = func_b.__doc__ or ""
lines = docstring.splitlines(keepends=True) or [""]
docstring = textwrap.dedent("".join(lines[1:])) if len(lines) > 1 else ""
docstring = lines[0] + docstring

If I feed this with func_a it remains unchanged and with func_b the indentation is set back at the start. bonus: it works as well with 1-liner docstrings.

Answered By: Pierrick Rambaud
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.