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

formatter removes blank line after class definition #8566

Closed
spaceone opened this issue Nov 8, 2023 · 10 comments
Closed

formatter removes blank line after class definition #8566

spaceone opened this issue Nov 8, 2023 · 10 comments
Labels
formatter Related to the formatter style How should formatted code look

Comments

@spaceone
Copy link
Contributor

spaceone commented Nov 8, 2023

$ black --diff foo.py 
All done! ✨ 🍰 ✨
1 file would be left unchanged.
$ ruff format --diff foo.py
--- foo.py
+++ foo.py
@@ -1,5 +1,4 @@
 class Foo:
-
     bar = 1
 
     def __init__(self):

$ cat foo.py
class Foo:

    bar = 1

    def __init__(self):
        pass

β†’ ruff should not remove the blank line

@spaceone
Copy link
Contributor Author

spaceone commented Nov 8, 2023

$ black --version
black, 22.10.0 (compiled: yes)
Python (CPython) 3.7.3

same for:

class Foo:

    # bar

    def __init__(self):
        pass

Additionally I would like to have a flag in ruff which prevents that

class Foo:

    def __init__(self):
        pass

get converted to:

class Foo:
    def __init__(self):
        pass

@charliermarsh
Copy link
Member

Our current behavior is identical to Black's though in all of the above cases -- see the playground link I shared above.

@spaceone
Copy link
Contributor Author

spaceone commented Nov 8, 2023

OK, then see this as feature request to change it via a config option.

@zanieb zanieb added formatter Related to the formatter style How should formatted code look labels Nov 8, 2023
@charliermarsh
Copy link
Member

Realistically, I think we're unlikely to implement a setting for this given that it's so specific. We also enforce a blank line if you use a docstring for your classes which should mitigate this, but I'm gonna close for now in the interest of keeping the issue queue manageable.

@charliermarsh charliermarsh closed this as not planned Won't fix, can't repro, duplicate, stale Nov 9, 2023
@Frost
Copy link

Frost commented Nov 15, 2023

$ black --version
black, 22.10.0 (compiled: yes)
Python (CPython) 3.7.3

same for:

class Foo:

    # bar

    def __init__(self):
        pass

Additionally I would like to have a flag in ruff which prevents that

class Foo:

    def __init__(self):
        pass

get converted to:

class Foo:
    def __init__(self):
        pass

This behavior changed between black 22.x and 23.x. Black has a stable format that they only update yearly. This means that once per year, you can suddenly get massive diffs from black, if you keep your dependencies updated.

@spaceone
Copy link
Contributor Author

This formatting is one of multiple reasons I don't use black - the maintainers also have strong opinions and you cannot argue with them. I have the hope that ruff is more user friendly and configurable.

@Frost
Copy link

Frost commented Nov 15, 2023

As long as ruff follows what black does, the same problem will exist. Soon it's 2024, and black will do some changes to their format again. There's a separate issue for tracking that here: #8678.

@jongracecox
Copy link

I'm using black==24.2.0 and ruff==0.3.2, and finding they produce different results:

Input file

class MyClass:

    def __init__(self):
        pass

black

class MyClass:

    def __init__(self):
        pass

ruff

class MyClass:
    def __init__(self):
        pass

Something interesting to note is that black will leave the blank line after class statement if it is there, but won't insert one if it's not already there. This means if you take my input file and run black then ruff, only ruff will make changes to the file. However, if you run ruff then black, black will not change the file - it won't revert the ruff changes. It will accept the ruff formatting. This means there's a subtle difference in behavior that could be made more consistent between the two tools:

  • Black honors the existing blank lines after the class statement
  • Ruff always removes the blank line after the class statement

What's the stance on conformity with black? It would help me a lot if it was a true drop-in like-for-like.

Side note: Thanks for an AMAZING project! I appreciate how complicated it is to manage everyones expectations.

@MichaReiser
Copy link
Member

Hi @jongracecox

Thanks for the excellent write-up. Yes, Black 24 or newer allows an optional blank line at the start of a block. We intentionally didn't implement this design change (yet?) because it can lead to unintentionally blank lines at the top of blocks after moving or deleting code.

Currently, we are concerned that allowing blank lines at the start of a block leads #8893 (comment). However, we will consider adopting Black's formatting at a later point with an improved heuristic. The style change is tracked in #9745.
source

I'm glad that you pointed this out because it made me realize that the known deviations on our website don't mention this deviation yet because I only updated the README.md in the ruff-python-formatter crate but not the markdown file rendered on the website. I fixed this, and the deviations should be correctly reflected when we push the next version of our documentation.

Side note: Thanks for an AMAZING project! I appreciate how complicated it is to manage everyones expectations.

Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
formatter Related to the formatter style How should formatted code look
Projects
None yet
Development

No branches or pull requests

6 participants