Hacker News new | ask | show | jobs
by mrtranscendence 1587 days ago
I've been using black at work for over a year now. I don't much care for some of the choices it makes, which can sometimes be quite ugly, but I've grown used to it and can (nearly) always anticipate how it will format code. One nice side effect of encouraging its use is how, at least where I work, it was very common to use the line continuation operator \ instead of encompassing an expression in parentheses. I always hated that and black does away with it.

What I don't much care for is reorder-python-imports, which I think is related to black (but don't quote me). For the sake of reducing merge conflicts it turns the innocuous

from typing import overload, List, Dict, Tuple, Option, Any

into

from typing import overload

from typing import List

from typing import Tuple

from typing import Option

from typing import Any

Ugh. Gross. Maybe I'm just lucky but I've never had a merge conflict due to an import line so the cure seems worse than the disease.

Edit: Just to be 100% clear: this is python-reorder-imports, not black. I thought they were related projects, though maybe I'm wrong. Regardless, black on its own won't reorder imports.

6 comments

It also has a built-in "black" profile, so it only takes one line of config to get it to play nicely with Black.

https://pycqa.github.io/isort/docs/configuration/black_compa...

Give µsort a try instead; it's focused on providing more safety when applying sorting to large codebases, and is designed to pair well with black out of the box:

https://usort.readthedocs.io

https://ufmt.omnilib.dev

For me µsort is a non-starter since it doesn't ignore the import/from part when sorting lexicographically. So when an import changes from `import foo` to `from foo import bar` (and vice versa), the import is moved. Sorting should start at the package name, nothing else.
I suspect you are fighting the tide of common practice in the Python community. In your example, switching from `import foo` to `from foo import bar` is changing the entire nature of the import. Sorting module- and from-imports separately also makes it much easier for many people to visually scan a block of imports. And similar to black, having a tool be consistent and predictable across projects and modules is more important than bikeshedding every possible opinion.
> I suspect you are fighting the tide of common practice in the Python community.

I hope not!

> Sorting module- and from-imports separately also makes it much easier for many people to visually scan a block of imports.

For me it's the opposite. My brain skips over the irrelevant parts (i.e. import/from). Not moving the import also produces better git diffs

isort also kind of has this bad behavior when using 'import as':

    $ cat foo.py 
    from x import a, b, d, e
    from x import c as C

    $ isort foo.py 
    Fixing /tmp/foo.py

    $ cat foo.py 
    from x import a, b
    from x import c as C
    from x import d, e
This is something µsort actually gets right:

    $ usort diff foo.py
    --- a/foo.py
    +++ b/foo.py
    @@ -1,2 +1 @@
    -from x import a, b, d, e
    -from x import c as C
    +from x import a, b, c as C, d, e
https://usort.readthedocs.io

    from typing import (
        overload,
        List,
        etc...,
    )
would seem more sensible to me. I know you can make isort do that, I guess maybe not black.
My preference is actually for what GP doesn't like; the reason I don't like your suggestion is that:

    from typing import (
        overload,
    )
is silly, but I don't want:

    -from typing import overload
    +from typing import (
    +    overload,
    +    List,
    +)
when all I actually did (semantically) was:

    +    List,
It feels to me like importing names from a module gets you a set of names from that module, so I'm already thinking about it as a collection. It doesn't bother me at all that it's turned into a tuple and spread over multiple lines.
I think I prefer it (first example) to the diff (second), it's just that a singular thing imported is such a common case that three lines for it where it so easily fits on one does seem a bit silly.

Maybe if I were allowed new syntax:

    from typing:
        import overload
        import List
Sorry, that's python-reorder-imports doing the reordering, not black. I just thought it was a related (but separate) project.
Really? I just put that exact line in a file I'm working on, and black didn't change anything. Maybe you mean in case it exceeds the line length limit, rather than that specific example.

In any case, you can wrap those in parentheses, in which case black will just enforce its usual tuple formatting: single line if it fits; one line per item if not, with a trailing comma.

edit: I tried it on a long line with a backslash break, and black wrapped the imports in parentheses like I suggested above. I wonder what causes the behaviour you see on your end.

No, sorry, I meant python-reorder-imports, not black. It's a separate project. I thought it was related but maybe I was wrong.
Why do you even care? I never look at that part of the code. If PyCharm automatically removed/added imports without me managing them I would be a happier person.
But Pycharm can (pretty much)!

Alt-enter over the would-be imported term to add an import, ctrl-alt-O to autoformat / autoremove (aka optimise) redundant ones.

You can then turn on folding to not see those imports much via Prefs -> Editor -> General -> Code Folding

I look at that part of the code routinely. When I'm reading code I didn't write it lets me know what package something came from.
There is an option to hide and autoformat inports.
I have a bad habit of

from typing import *

because I get annoyed at having to change my imports each time I need a new type in my type annotations.

At least it doesn’t have a dishonest name such as Prettier, which turns perfectly good looking code into digital vomit.
Stop thinking opinions on code style are objective. Prettier is good enough and NOT « digital vomit ». Wtf.