sourcery-ai / sourcery

Instant AI code reviews
https://sourcery.ai
MIT License
1.5k stars 65 forks source link

Indentation issue with AI-generated docstrings #352

Closed amogorkon closed 1 year ago

amogorkon commented 1 year ago

Description

Using VSC with the new AI-powered docstring generation feature, when applying the auto-fix to a method, the method loses the proper indentation, demoting it to a global function, thus making any following code unreachable (which sourcery complains about, and wants to remove it, too, ironically).

Code snippet that reproduces issue

class Task:
    ...
    def set_deadline(self, deadline: float):
        assert isinstance(deadline, float), "Deadline must be a float."
        assert deadline >= 0, "Deadline cannot be negative."

        # removing deadline
        if deadline == float("inf"):
            db.execute(f"DELETE FROM deadlines WHERE task_id={self.id}")
            db.commit()
            return

        query = db.execute(f"SELECT time_of_reference FROM deadlines WHERE task_id={self.id}")

        # changing deadline
        if query.fetchone():
            db.execute(f"UPDATE deadlines SET time_of_reference={deadline} WHERE task_id={self.id}")
        else:  # new deadline
            db.execute(f"INSERT INTO deadlines (task_id, time_of_reference) VALUES ({self.id}, {deadline})")

        db.commit()

applying quick-fix results in

class Task:
    ...
def set_deadline(self, deadline: float):
    """Sets the deadline for a task.

    If deadline is set to infinity, the deadline is removed from the database.
    If the deadline already exists, it is updated with the new deadline.
    If the deadline does not exist, a new deadline is created in the database.

    Args:
        deadline (float): The deadline to be set for the task.

    Returns:
        None

    Raises:
        AssertionError: If deadline is not a float.
        AssertionError: If deadline is negative.

    Examples:
        >>> task = Task()
        >>> task.set_deadline(10.0)
        >>> task.set_deadline(float("inf"))
        >>> task.set_deadline(-1.0)
        Traceback (most recent call last):
            ...
        AssertionError: Deadline cannot be negative.
    """
    assert isinstance(deadline, float), "Deadline must be a float."
    assert deadline >= 0, "Deadline cannot be negative."

    # removing deadline
    if deadline == float("inf"):
        db.execute(f"DELETE FROM deadlines WHERE task_id={self.id}")
        db.commit()
        return

    query = db.execute(f"SELECT time_of_reference FROM deadlines WHERE task_id={self.id}")

    # changing deadline
    if query.fetchone():
        db.execute(f"UPDATE deadlines SET time_of_reference={deadline} WHERE task_id={self.id}")
    else:  # new deadline
        db.execute(f"INSERT INTO deadlines (task_id, time_of_reference) VALUES ({self.id}, {deadline})")

    db.commit()

    def ... # unreachable code

Debug Information

IDE Version: Version: 1.79.0-insider (user setup) Commit: a8e719eeed4dac1f59fc2e48ed00545c0acafc42 Date: 2023-06-05T21:50:37.073Z Electron: 22.5.5 Chromium: 108.0.5359.215 Node.js: 16.17.1 V8: 10.8.168.25-electron.0 OS: Windows_NT x64 10.0.19045

Sourcery Version: 1.3.0

PS: Another - possibly better - quick-fix instead of auto-generating docstrings for everything would be to suggest a refactoring to prepend _{function_name} in order to indicate non-public functionality. This is especially true for GUI code where many functions and methods are one-shot functions for callbacks, thus effectively being lambdas and not public at all.

Hellebore commented 1 year ago

This has now been addressed in a nightly build.