[HN Gopher] Django: Reformatted code with Black
       ___________________________________________________________________
        
       Django: Reformatted code with Black
        
       Author : tams
       Score  : 226 points
       Date   : 2022-02-08 14:10 UTC (8 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | wyuenho wrote:
       | Every time I was tempted to do something like this, I hesitated
       | because I didn't want every other line in every file with my name
       | on a single commit, mostly to avoid making git blame harder than
       | necessary. It would be nice if there was a kind of diffing
       | algorithm that can diff code units *syntactically* across
       | history.
        
         | rurp wrote:
         | Not everyone uses PyCharm, but if you do it's really easy to
         | highlight a specific code block and look through the git commit
         | history for that section. I've used it many times for this
         | exact type of problem, trying to find when the last
         | _substantive_ change happened.
         | 
         | To do this just highlight the block, right click, and choose
         | Git > Show History for Selection.
        
         | timhh wrote:
         | In my experience it's better to just bite the bullet and do it.
         | Eventually you _will_ do it, so you either screw up git blame
         | for a small codebase with a small amount of history, or wait
         | until it is a large codebase with a large amount of history to
         | screw up.
         | 
         | > It would be nice if there was a kind of diffing algorithm
         | that can diff code units _syntactically_ across history.
         | 
         | There have been quite a few attempts at that though I've only
         | seen them applied to resolving merge conflicts. It would be
         | interesting to try them for blame too.
        
         | simonw wrote:
         | You can tell "git blame" to ignore specific commits which helps
         | a lot here: https://www.moxio.com/blog/43/ignoring-bulk-change-
         | commits-w...
        
           | wyuenho wrote:
           | The problem with this approach is, the blame before and after
           | the ignored wouldn't make any sense to the viewer if he
           | didn't know about ignoring the formatting commit. Also, you
           | will need to configure that for every clone. Since tree
           | diffing algorithms are pretty well known these days, I don't
           | know why there hasn't been any real effort to implement a git
           | plugin that can chase syntax tree node changes instead of
           | doing string diffing like it was the 70s. Syntax parsers are
           | so easy write now and surely the tree node changes can be
           | cached. Your usual diff/patch tooling wouldn't work for this
           | kind of diff, but that's just an option away when you need
           | them back.
        
           | terr-dav wrote:
           | Here's a script that automates the once-per-repository local
           | setup of this feature:
           | 
           | https://github.com/ipython/ipython/pull/12091/files
           | 
           | Unfortunately there isn't support for it in GitHub or GitLab
           | yet, but there's at least a GitLab issue here requesting it:
           | 
           | https://gitlab.com/gitlab-org/gitlab/-/issues/31423
        
           | dmart wrote:
           | This is a nice feature, but I do wish that .git-blame-ignore-
           | revs was automatically applied, similarly to .gitignore and
           | .gitattributes. Hopefully there are plans to do so in a
           | future Git release?
        
         | OJFord wrote:
         | Does the user matter? As long as the commit message is
         | something sensible like 'Autoformat with black' it can be
         | easily ignored when seen, and you can avoid seeing it with
         | blame as simonw suggests.
        
           | mynegation wrote:
           | The problem is that this revision will override all the
           | previous ones in the "blame" output so it needs to be
           | explicitly ignored. See a great link elsewhere in the thread
           | on how to deal with that in newer versions of git.
        
             | OJFord wrote:
             | Yes, as I said?
             | 
             | My point was that the _user_ doesn 't matter (vs. anything
             | else about the commit) to me in any context that I see it.
             | 
             | And then I mentioned without reiterating the advice about
             | hiding the commit from blame just as you did.
             | 
             | In any context where I see "OJFord committed 'Autoformat
             | with black'" for this, it's not 'OJFord' that's the problem
             | IMO.
        
             | adamrt wrote:
             | Git blame has a feature just for this `git blame -w -M`. -w
             | ignores white space changes and -M isn't really necessary
             | but will ignore moved lines
        
         | throwthere wrote:
         | On the flip side you can get an intern to commit. /s.
         | 
         | Probably best to just make a one time git user to do it.
        
       | SodiumMerchant0 wrote:
        
       | ibejoeb wrote:
       | In general, what are the strategies for large public codebases
       | like this to mitigate supply chain attacks or other source-level
       | attacks?
       | 
       | For clarity, I'm hoping to open us discussion about how we're
       | dealing with massive changesets like this that are difficult to
       | review due chiefly to the breadth of it.
        
         | sciurus wrote:
         | For a purely mechanical change like this, someone could run
         | black against the same revision of Django and verify the
         | changes they see locally match the changes in this PR.
        
           | ibejoeb wrote:
           | That's true as long as the results are predictable and
           | reproducible. I don't happen to know if Black is, and it's
           | not apparent from the documentation.
           | 
           | Update: Found it:
           | 
           | > How stable is Black's style?
           | 
           | > Starting in 2022, the formatting output will be stable for
           | the releases made in the same year
           | 
           | https://black.readthedocs.io/en/stable/faq.html
        
         | fritzo wrote:
         | Interesting! Can you help me imagine attack scenarios? All I
         | can think of is:
         | 
         | - The changeset is authored by a trusted committer but the
         | committer's tools have been locally compromised.
         | 
         | - The public tool itself (e.g. black) has been compromised to
         | automatically create vulnerabilities in difficult-to-review
         | bits of code (a Ken Thompson hack).
        
         | jamessb wrote:
         | As a reformatting tool should only change the formatting, you
         | could check that the Abstract Syntax Tree is unchanged. The ast
         | module in the standard library gives access to the AST [1].
         | 
         | [1]: https://docs.python.org/3/library/ast.html
        
       | tomp wrote:
       | worst things about Black:
       | 
       | - doesn't respect vertical space - sure, making the code fit on
       | screen might be valuable (though the default width should be at
       | least 120 characters, I mean we're in 2022 after all), but Black
       | does it by blowing up the _vertical_ space used by the code
       | 
       | - spurious changes in commits - if you happen to indent a block,
       | Black will cause lines to break
       | 
       | - Black fails at its most basic premise - "avoiding manual code
       | formatting" - because a trailing comma causes a list/function
       | call to be split over lines _regardless_ of width
        
         | throwaway894345 wrote:
         | > oesn't respect vertical space - sure, making the code fit on
         | screen might be valuable (though the default width should be at
         | least 120 characters, I mean we're in 2022 after all), but
         | Black does it by blowing up the vertical space used by the code
         | 
         | This is fine with me--I think it makes sense to optimize for
         | readability, and I can read a long vertical list of arguments a
         | lot more readily than a long comma-delineated list.
         | 
         | > spurious changes in commits - if you happen to indent a
         | block, Black will cause lines to break
         | 
         | Is this a generic argument against wrapping lines, or am I
         | misunderstanding something?
         | 
         | > Black fails at its most basic premise - "avoiding manual code
         | formatting" - because a trailing comma causes a list/function
         | call to be split over lines regardless of width
         | 
         | I'm not following this either. If black _automatically_
         | reformats your code over multiple lines, that doesn 't suggest
         | manual formatting. Maybe you're arguing that all code which
         | produces a given AST should be formatted in the same way--this
         | would be cool and I would agree, but black gets us 95% of the
         | way there so to argue that it "fails" is to imply that "0%" and
         | "<100%" are equivalent.
        
           | otherme123 wrote:
           | I also noticed we are in 2022, and my screen is so big I can
           | have three or four files of 80'ish chars wide side to side.
           | Specially with Django, where you usually need models.py,
           | views.py, forms.py and a template open at the same time. With
           | 120'ish lines, I lose one vertical split.
        
           | yawaramin wrote:
           | > the default width should be at least 120 characters, I mean
           | we're in 2022 after all
           | 
           | Even in 2022, some people don't have wide external monitors,
           | sometimes like to view two files (or a diff) side-by-side, or
           | need to use GitHub/BitBucket/etc. code viewer pages. Also,
           | it's still difficult for humans to read long lines.
        
             | throwaway894345 wrote:
             | Agreed. It's _really nice_ to be able to have two files
             | side-by-side (or a file plus a shell) without having tiny
             | font. I still do the overwhelming majority of my work on a
             | laptop--maybe I 'd feel differently with one or more 27" 4K
             | monitors, but even then I don't think a code formatter
             | should make these kinds of assumptions.
        
             | neamar wrote:
             | True, but we also have word wrap to deal with this
             | automatically!
        
         | saila wrote:
         | I have to bump up my font size a bit and find 120 characters
         | too wide on a 27" monitor where I need to look at multiple
         | things side by side. It's also harder to read even when viewing
         | a single file.
         | 
         | IMO, < 80 is ideal where possible with an absolute maximum of
         | 99. I think Black's choice of 88 (plus maybe a little more in
         | special cases) is quite good.
        
         | skybrian wrote:
         | It's odd that nobody followed Go's formatter in letting
         | developers break lines themselves and mostly fixing indentation
         | and spacing. I thought they made good choices.
        
           | gloryjulio wrote:
           | I'm in this camp. Why do we still waste brain cells on this
           | problem? Just copy it
        
           | throwaway894345 wrote:
           | Honestly the only grievance I have with Go's formatter is
           | that it doesn't automatically break lines. I'd be a big fan
           | of "if two programs parse to the same AST, they should format
           | the same" and if that's too aggressive perhaps allow for `//
           | go:nofmt` annotations or something. In whatever case, `gofmt`
           | gets at least 95% right.
        
             | rob74 wrote:
             | Nah, I can totally understand why they decided to stay away
             | from this can of worms. First, what max line width do you
             | choose? Second, where do you break a line if it's too long?
             | I think gofmt gets the balance exactly right: makes source
             | code easier to read by providing a unified formatting
             | style, but doesn't get in your way more than necessary.
        
               | perryizgr8 wrote:
               | > what max line width do you choose?
               | 
               | 80
               | 
               | > where do you break a line if it's too long
               | 
               | Wherever a keyword or name ends, but does not exceed 80.
               | 
               | Gofmt has made opinionated decisions about everything,
               | why stop at line breaks?
        
               | johnmaguire wrote:
               | IME 80 is terribly short in almost any language.
        
               | coryrc wrote:
               | When I'm writing Python at Google, and get yet another
               | error because my Python or Markdown line exceeds 80
               | characters, and read the fights on the mailing lists
               | about changing the limit, I think Go was created because
               | it was easier to create a whole new language than get the
               | line length increased for Python.
        
               | throwaway894345 wrote:
               | Why do you get errors rather than auto-formatting (in the
               | editor or in CI) and moving on with your day? I would
               | have thought Google would have this sorted already?
        
               | coryrc wrote:
               | I know! Usually the editor autoformats on save and while
               | typing, but there are some edge cases where the regular
               | incremental formatter fails but it's rare enough that I
               | don't reflexively hit the "format all files" button and
               | then get caught out by pre-submit tests.
        
               | throwaway894345 wrote:
               | > First, what max line width do you choose?
               | 
               | The whole point of an opinionated formatter is to have
               | opinions about these sorts of things.
               | 
               | > Second, where do you break a line if it's too long?
               | 
               | It depends on the context. Yeah, writing the algorithm to
               | make these decisions is a little complex, but it's also
               | well-understood.
               | 
               | > doesn't get in your way more than necessary
               | 
               | What is "necessary"? It seems like you're trying to say
               | "it makes decisions on the things I think it should make
               | decisions on" which is fine, but it's not like choosing
               | between `struct {` and `struct{` is objectively more
               | critical than line wrapping.
        
               | skybrian wrote:
               | I believe one reason they chose it is so that automatic
               | reformats like renaming a variable don't cause reformats
               | to more lines than necessary.
               | 
               | Keeping lines reasonably short is nice but doesn't need
               | to be done strictly. It can wait until someone edits the
               | code.
        
         | polote wrote:
         | > - Black fails at its most basic premise - "avoiding manual
         | code formatting" - because a trailing comma causes a
         | list/function call to be split over lines regardless of width
         | 
         | Ah that's why `manage.py shell` now split json pasted on
         | several lines, very annoying
        
         | wodenokoto wrote:
         | > - Black fails at its most basic premise - "avoiding manual
         | code formatting" - because a trailing comma causes a
         | list/function call to be split over lines regardless of width
         | 
         | Yeah, this one drives me nuts too.
        
           | flightlevel180 wrote:
           | If I'm understanding your problem correctly, it seems that
           | you can avoid it by using the --skip-magic-trailing-comma
           | option [0].
           | 
           | [0] https://black.readthedocs.io/en/stable/the_black_code_sty
           | le/...
        
           | epistasis wrote:
           | It's one of my favorite things about black, and I've started
           | to use that formatting of function calls with long arguments
           | for other languages too.
           | 
           | But I also despise long lines with a passion, I hate having
           | to go to the right, and would much much rather scroll up and
           | down with a consistent width, so that I can put multiple
           | views next to each other.
        
         | digisign wrote:
         | My monitor is in portrait mode. Even when I used one in
         | landscape, I typically had two windows side by side. So extra-
         | wide lines of code are less readable.
        
       | ReleaseCandidat wrote:
       | I would really appreciate if there would exist exactly _one_
       | formatter (without any options) per language.
       | 
       | It is way better to deal with ugly formatting as long as it is
       | consistent than with discussions where to put a closing
       | brace/bracket/paren.
        
       | TheRealPomax wrote:
       | The reason to use Black is the same as Prettier on the
       | HTML/CSS/JS side: forever stop having an opinion on code style,
       | it's wasted time and effort. Any "it's not exactly what we want"
       | comment with an attempt to customize the style to be closer to
       | "what we were already using" is exactly why these things exist:
       | by all means have that opinion, but that's exactly the kind of
       | opinion you shouldn't ever even need to have, tooling should
       | style the code universally consistently "good enough". Which
       | quotes to use, what indent to use, when to split args over
       | multiple lines, it's all time wasted. Even if you worked on a
       | project for 15 years, once you finally add autoformatting, buy in
       | to it. It's going to give you a new code style, and you will
       | never even actively have to follow it. You just need to be able
       | to read it. Auto-formatting will do the rest.
        
       | MahajanVardhan wrote:
       | I am so sorry, but what is Black? I use django but I have never
       | heard of Black
        
         | rcv wrote:
         | Black is a tool that can reformat Python code. It's remarkable
         | for it's lack of configuration.
         | 
         | https://github.com/psf/black
        
       | rowanseymour wrote:
       | I love this except the use of the default black line length of
       | 88. One of the things I appreciate about gofmt is being trusted
       | with deciding on line breaks.
        
       | VWWHFSfQ wrote:
       | So now when you look at the annotated change history all you're
       | going to see is a bunch of changes by the person that reformatted
       | the code instead of the person that wrote it.
        
         | justinmchase wrote:
         | You can see both of course. That's the beauty of history.
        
         | Cthulhu_ wrote:
         | There's workarounds that others have mentioned, but indeed, the
         | unfortunate side-effect of deciding to apply a formatter is a
         | 'formatting' commit, causing a lot of code churn and issues if
         | naively using git blame.
         | 
         | But, it's a "rip the plaster off" kinda thing, because it
         | should ensure a lot less churn, inconsistent code style, or
         | arguments and reviews about formatting after this is merged. It
         | frees up a lot of headspace and distractions in code reviews. I
         | don't know about you, but when I did code reviews I'd always
         | end up zooming in on code style issues - ' vs ", things on
         | newlines or no, JS objects with stringed keys, etc.
        
         | [deleted]
        
         | tempay wrote:
         | The `.git-blame-ignore-revs` file can be used to ignore that
         | (and will be [1]). Unfortunatly GitHub doesn't support it but
         | at least it's possible to have clients behave in a reasonable
         | way.
         | 
         | [1]
         | https://github.com/django/django/pull/15387#issuecomment-103...
        
           | acidburnNSA wrote:
           | TIL about that git feature. Very nice.
        
           | sciurus wrote:
           | For anyone looking for more explanation of this feature:
           | 
           | https://michaelheap.com/git-ignore-rev/
        
           | terr-dav wrote:
           | You can automate setup for developers using this simple
           | script:
           | 
           | https://github.com/ipython/ipython/pull/12091/files
           | 
           | And here's a GitLab issue requesting support for blame-
           | ignore:
           | 
           | https://gitlab.com/gitlab-org/gitlab/-/issues/31423
           | 
           | I don't think there's a corresponding GitHub request, but
           | maybe if GitLab adds this feature GitHub will have some
           | incentive to follow suit.
        
         | [deleted]
        
         | alecbz wrote:
         | Uh so is your take "don't do broad refactors ever?"
         | 
         | Beyond `.git-blame-ignore-revs` (which is neat and TIL), in
         | GitHub's web viewer, if you find the line you're interested in
         | and see that the most recent PR is a reformat, you click the
         | "view blame prior to this change" button. I think most blame
         | viewers do (or at least should) have a feature like this.
        
       | justinmchase wrote:
       | The output does look better but this also just looks like every
       | PR for applying a linter / formatter I've ever seen. Not sure why
       | this is news worthy.
        
         | dabeeeenster wrote:
        
         | [deleted]
        
         | simonw wrote:
         | It's a significant milestone in the adoption of Black by
         | influential projects within the Python ecosystem, which makes
         | it a good hook for discussing the idea that Black, now stable,
         | is becoming established as the standard for code formatting for
         | Python.
        
         | owaislone wrote:
         | Using black is not about how the code looks but to eliminate an
         | entire suite of review comments/discussions. Everyone simply
         | runs black over all code before submitting and no one ever
         | comments about how anything is formatted.
        
           | mbot5324 wrote:
           | By chaining yourself to a format preferred by a machine, you
           | free yourself of having to understand how and why another
           | human thinks the way they do and prefers what they prefer.
           | 
           | Simply give up your mind and you too can be free.
        
           | captainmuon wrote:
           | Naive question, but why is everybody so aggravated by
           | formatting discussions? It seems to be a widespread opinion
           | that these discussions are just 1) pointless and 2) difficult
           | and time consuming.
           | 
           | My personal experience is that 1) in many cases you _do_
           | benefit from taking a moment, going through your code and
           | thinking about presentation. And 2) I find it not at all
           | difficult to settle. A change either doesn 't matter, then
           | you just don't discuss it at all, or it is important, then
           | you quickly agree on the best solution. (In the worst case,
           | "best" means what the project lead finds prettier.) If you
           | don't have a social mechanism to agree on something as basic
           | as coding style, then your team probably has bigger problems.
           | 
           | I actually find robo-formated code annoying to read: Go code
           | from a bloody beginner who doesn't know what they are doing
           | looks exactly like carefully tended for, highly thought-out
           | code. And in autoformatted Python, you for example cannot
           | make formulas clearer by removing spaces around operators
           | with higher precidence. Parentheses placement is dicated by
           | how long words are and not by what logically belongs
           | together, etc..
        
             | zmmmmm wrote:
             | Like you, I'm quite fascinated by the apparent massive
             | frustration and time sink that is apparently happening due
             | to formatting discussions. Been working nearly 25 years in
             | software at all levels, rarely using auto-formatted code,
             | literally can't remember having one of these discussions.
             | If anything I might even say I wish people cared a little
             | more.
             | 
             | I do quite often artisanally craft formatting of specific
             | code sections to highlight the intent of the algorithm or
             | design. I assume black would merrily destroy all my hard
             | work.
        
             | WesolyKubeczek wrote:
             | Those discussions, indeed, _are_ pointless.
             | 
             | They are also huge timesinks, people spend less time
             | sometimes deciding which framework or language or cloud
             | provider to use and which country to register their company
             | in, than spending hours and hours on how some SICK ANIMAL
             | forgot a trailing comma somewhere, or bikeshedding how many
             | spaces to indent with, and who uses an ultrawide monitor
             | and wants wide columns (but then again someone turns theirs
             | into portrait mode, and wants narrow columns), etc. Gobs
             | and gobs of time, totally disproportionate to the issue at
             | hand!
             | 
             | Yes, black sometimes produces fugly code, but at least the
             | bikeshedding can fucking stop. There are bugs to fix, for
             | chrissake. Yes, some people are not thoughtful enough to
             | format their code like a piece of poetry, so what? Should
             | everyone take Typography 101?
             | 
             | There is also a huge cohort of programmers who, when doing
             | reviews and finding nothing to nitpick, resort to
             | criticizing, in great detail, the code formatting of pull
             | requests. They fell they MUST leave some critique or else
             | their review is incomplete and their peepee is small. I
             | find it hugely enjoyable that a tool like black can deprive
             | them of the joy of belittling someone else for
             | microscopically minor things and concentrate on, say, the
             | actual merit of a change.
        
             | acdha wrote:
             | I think it's more that formatting discussion is _easy_: if
             | you get a merge request, you can start adding comments like
             | "this should be indented differently" or "wrap this here"
             | and spend a lot of time "reviewing" the request without
             | noticing that you missed an error in the logic because you
             | were focused on the most visibly upsetting problem.
             | 
             | Using an automatic formatter also can help reduce diff
             | noise, which is something I've noticed on more active
             | projects. Using Black drives close to zero the amount of
             | time I spend confirming that someone didn't actually change
             | functionality along with formatting. There are other ways
             | to get this, of course, but it's so easy just to enable
             | Black and never spend your time on it again.
             | 
             | > Parentheses placement is dicated by how long words are
             | and not by what logically belongs together, etc..
             | 
             | This is actually a bit more subtle: Black will remove
             | parentheses when they don't have any effect (e.g. `(3 _2)`
             | will become `3_ 2` because it covers the entire expression)
             | but if you use them for only a subset of the expression
             | they 'll be preserved (e.g. `(1 _(3_ 2))` becomes `1 * (3 *
             | 2)`.
        
           | musingsole wrote:
        
           | tayo42 wrote:
           | With a style guide and linter I've never experienced this and
           | idk why you would. Then the only time style comments come up
           | is pointing someone to the guide
        
       | supreme_berry wrote:
       | "Black" developer refused for a long time to add option to format
       | code with single quotes with very aggressive manners. Now Django
       | devs didn't see that option for single quotes and code looks
       | unpleasant.
        
         | SodiumMerchant0 wrote:
        
         | vitorfs wrote:
         | I have always used single quotes for Python code since I start
         | working with it. When I started to adopt Black on my projects
         | it indeed felt weird and the code looked unpleasant. But after
         | a while you get used to it.
         | 
         | Some people make the case that it's easier to write single
         | quotes (well, depending on the keyboard format anyway). For
         | keyboards in the US standard you have to hold the Shift key to
         | write a double quote. But the good thing about Black is that
         | you can still write your code using single quote and when you
         | run the command line utility it will fix/normalize the code to
         | use double quotes.
         | 
         | Nowadays I got so used to it that I even write my Python code
         | using double quotes. And looking at Python code using single
         | quotes looks weird/unpleasant for me.
        
           | digisign wrote:
           | The repl still uses single quotes.
        
           | valparaiso wrote:
        
         | INTPenis wrote:
         | I reacted to this too, in the changed files tab.
         | 
         | Technically single or double quotes have the exact same meaning
         | in Python. What makes people use single quotes is probably
         | other languages like PHP, Perl and Bash.
         | 
         | I know I've made it a habit to default to single quotes unless
         | I know I need double quotes. So that might be where the habit
         | comes from in the Django project. But it's not actually
         | necessary in python so might as well use the most commonly used
         | type of quote.
        
         | digisign wrote:
         | Use nero or blue instead, which both use single quotes.
        
         | pchf wrote:
         | To keep the single quotes, which in my opinion make the code
         | less cluttered and closer to the REPL, I use the pre-commit
         | hook double-quote-string-fixer, in conjunction with black's
         | option skip-string-normalization set to true.
        
       | declnz wrote:
       | Aside: I love a good linter, but as a long-time Python fan I find
       | it sad that Black has _so_ little configuration (yes, I know, but
       | still) and moreover that it often produces code that _no_ human
       | Python dev I know would write...
       | 
       | Python was always meant to look concise / beautiful... (MyPy has
       | also made this trickier too)
        
         | rob74 wrote:
         | Well, you'll be surprised to find out that gofmt has exactly
         | zero configuration. Ok, they (wisely in my opinion) decided not
         | to mess with breaking lines automatically, and the job was far
         | easier to do with a new language than with an already-
         | established one where most developers have their long-treasured
         | preferences.
        
         | Kinrany wrote:
         | People conflate opinionated formats with autoformatting for
         | some reason.
         | 
         | An autoformatter removes 99% effort from formatting code, and
         | that includes code actively being worked on. Autoformatters are
         | incredibly useful.
         | 
         | A standardized format removes effort spent learning to read a
         | new format. That's an hour per format at most.
         | 
         | I don't see any good reasons for an autoformatter to enforce a
         | standard. A standard would work just as well if defined as a
         | specific configuration.
        
           | njharman wrote:
           | In 30yrs of dev the truest statement in standards I can make
           | is that they change, all the time. The 2nd truest is I and
           | coworkers have wasted far to much energy on arguing and
           | maintaing STDs.
           | 
           | Blacks value isn't autoformatter, it's preemptive discussion
           | ender.
        
           | 3pt14159 wrote:
           | Well, sorta. It's really, really mentally annoying switching
           | between projects where standards are different. For example
           | 80 char limit to 120 char limit takes me at least a month to
           | fully get used to. I agree black is better than the
           | alternative, I agree it has downsides, I'm happy some of the
           | parameters are tunable, but I'm also glad most of them are
           | not. I just want to write software with tools I'm used to.
        
             | jessaustin wrote:
             | Who is using 120 chars?!?!? I can certainly understand the
             | adjustment difficulties...
        
               | barbazoo wrote:
               | Are 120 chars bad?
        
               | jessaustin wrote:
               | Maybe it's because I only have one eye and the resulting
               | slightly reduced width of field, but wide lines drive me
               | crazy. I need to see the whole line without scanning.
               | This was one of python's original appeals to me...
               | 
               | https://pep8.org/#maximum-line-length
        
               | barbazoo wrote:
               | I can see how that would make it hard for you. I hope
               | your team is accommodating.
        
               | rbanffy wrote:
               | God made the ASR-33 teletype with 80 columns for a
               | reason.
        
               | s5806533 wrote:
               | moi
        
           | crad wrote:
           | yeah, it's just too bad that black violates PEP-8.
        
         | alecbz wrote:
         | OOC what are your grips with black's style? I generally find
         | black pretty "beautiful" ( _concise_ maybe not as much).
        
           | declnz wrote:
           | I guess the closing parens irk me the most e.g.
           | assert outputs.get("foo.bar.baz", "default") ==
           | pytest.approx(             time_recorder.time_taken,
           | abs=0.0001         )
           | 
           | I get why it's done that, but I just don't think it helps
           | humans read. Part of the twisted beauty of PEP-008's narrow
           | lines is that you're forced to extract (named) variables, or
           | avoid overly indented code by extracting methods or applying
           | higher level abstractions.
           | 
           | In the last few years I find devs are happier to format and
           | push to "sort that problem out", leaving the readability
           | benefit of that thought process lost.
           | 
           | TL;DR writing readable code isn't just about getting the
           | spaces and brackets right...
        
             | saila wrote:
             | This looks like bad coding style to me--trying to cram too
             | much on a line and an overly complex conditional
             | expression.
             | 
             | Using the same three lines, you could instead assign each
             | result to a temporary var:                   x =
             | outputs.get("foo.bar.baz", "default")         y =
             | pytest.approx(time_recorder.time_taken, abs=0.0001)
             | assert x == y
             | 
             | If using an assert method, I think this looks okay too
             | (although still a bit noisy):
             | self.assertEqual(             outputs.get("foo.bar.baz",
             | "default"),
             | pytest.approx(time_recorder.time_taken, abs=0.0001),
             | )
             | 
             | I find that if black produces ugly output, it's _usually_
             | because of something that I could improve, and I appreciate
             | the hint.
        
             | alecbz wrote:
             | I tend to prefer the trailing paren on the following line.
             | I'm not sure if there's a principled reason it helps (or
             | hurts), but stuff like:                   assert
             | outputs.get("foo.bar.baz", "default") == pytest.approx(
             | time_recorder.time_taken, abs=0.0001)
             | 
             | always feels a bit off and "unbalanced" to me. The opening
             | paren doesn't have anything immediately following it, so it
             | feels 'symmetric' that the closing paren shouldn't have
             | anything preceding it.
             | 
             | And also it feels like the open and closing parens should
             | be on lines that start at the same indentation level.
             | Honestly this I think does aid in readability a bit.
             | 
             | > Part of the twisted beauty of PEP-008's narrow lines is
             | that you're forced to extract (named) variables, or avoid
             | overly indented code by extracting methods or applying
             | higher level abstractions.
             | 
             | This feels orthogonal? The line is wrapping either way,
             | which might sufficiently annoy someone to extract things
             | out a bit more. But IMO it feels like a bit of an anti-
             | pattern to create abstractions on the basis of syntax as
             | opposed to the structure of the program.
             | 
             | > writing readable code isn't just about getting the spaces
             | and brackets right...
             | 
             | ? I mean of course not, but that's what we're talking about
             | in the context of formatters right? I think the real, major
             | way auto-formatters help with readability is by getting
             | people to stop wasting mental cycles on things like spaces
             | and brackets so that they can focus on more important code
             | organization concerns.
        
               | ziml77 wrote:
               | I agree with it feeling unbalanced. I don't register that
               | statement as being complete. Putting the parenthesis on
               | its own line is the same as putting a closing curly brace
               | on its own line in languages that use those.
               | int foo() {             return 1; }
               | 
               | (This example actually breaks up vertically in my mind.
               | As if it's just the number 1 being bracketed)
               | 
               | Maybe it could be broken up differently though to avoid
               | the lone paren.                   assert
               | (outputs.get("foo.bar.baz", "default") ==
               | pytest.approx(time_recorder.time_taken, abs=0.0001))
        
               | philote wrote:
               | I also prefer the close paren to be on it's own line.
               | Besides how it looks, it feels easier to me to add to the
               | code inside the parens (but this is likely because I use
               | vim).
        
           | mrtranscendence wrote:
           | Sometimes it takes code like this:
           | 
           | foo = (                   spark              .read
           | .parquet(...)              .filter(...)
           | .withColumn(...)
           | 
           | )
           | 
           | and turns it into
           | 
           | foo = spark.read.parquet(                   ...
           | 
           | ).filter(                   ...
           | 
           | ).withColumn(                   ...
           | 
           | )
           | 
           | which feels harder to parse for me. I also never quite got on
           | board with the trailing commas.
        
             | jreese wrote:
             | Actually, modern versions of black will retain the fluent
             | style you prefer, though it will collapse up to the first
             | method call on the first line within the parens, so you end
             | up with something like:                   foo = (
             | spark.read.parquet(...)             .filter(...)
             | .withColumn(...)         )
        
             | philote wrote:
             | Personally I prefer my code to read more like a sentence
             | 
             | instead
             | 
             | of
             | 
             | being
             | 
             | split
             | 
             | up
             | 
             | into
             | 
             | too
             | 
             | many
             | 
             | lines.
        
               | ihaveajob wrote:
               | I guess the point of the parent applies when the
               | parameter lists are long, thus breaking the sentence-like
               | appearance of the chained calls.
        
               | BeFlatXIII wrote:
               | These examples remind me why Elixir's pipe operator is so
               | beloved.
        
         | crad wrote:
         | I'll take yapf --style=pep8 formatting over black any day.
        
           | albertzeyer wrote:
           | I found this comment:
           | https://news.ycombinator.com/item?id=17155048
           | 
           | Are the mentioned issues resolved by now? E.g. the quadratic
           | algorithm?
        
           | 0xJRS wrote:
           | Having gone through the effort of testing yapf and black a
           | few years back I also prefer yapf.
        
       | VBprogrammer wrote:
       | Reading some of the comments here it's become clear to me that
       | the next stage in the development of auto-formatters is to have
       | the formatter commit the code as a canonical format but to
       | display the code to each individual contributor in the style of
       | their choosing. Thus removing all kinds of arguments about
       | whether 80 or 120 columns is the one true width.
        
         | whalesalad wrote:
         | I think this is the most wonderful part of Lisp. Specifically
         | its homoiconicity, or the fact that the syntax of the program
         | is the program, and yet the syntax (as far as linebreaks,
         | indentation, spaces vs tabs, etc) is completely irrelevant to
         | the meaning of the code.
         | 
         | Ostensibly you could craft a future where what is on disk is
         | not what the user is actually editing - a-la the virtual DOM.
         | And on read/save the developer's preference is used to
         | transform the syntax into their ideal shape. This is trivial in
         | a Lisp, but not so easy in other languages.
        
           | sockpuppet69 wrote:
        
           | eternauta3k wrote:
           | Indentation is not the reason why it's hard to autoformat
           | Python code, or any other language for that matter.
        
         | wyuenho wrote:
         | I'm pretty sure you can already do that with some scripting.
         | Just write a git alias, say _git edit_ , which will run the
         | work tree copy through your favorite formatter to a temp file
         | and send that temp file to your editor, and a commit hook to
         | rename all the temp files back to the original and format them
         | back to whatever the canonical format is. You can also
         | configure your git diff and stash etc to make them aware of the
         | temp file naming convention. You might even be able to write a
         | script to generate all these aliases. There are some annoying
         | details such as needing a separate command to temporarily move
         | the temp files to the work tree to give your IDE a hand, but
         | totally doable. It's going to take maybe a few weeks of work,
         | but doable for a single person.
        
         | mulmen wrote:
         | You're absolutely right of course.
         | 
         | But even now I have to adapt on screen shares when my coworkers
         | are using dark themes before sunset. Can't imagine what that
         | would be like with different code formatting. So the next next
         | step is to display _their_ desktop with _my_ theme.
         | 
         | IOW collaboration tools still have a long way to go.
        
         | gfunk911 wrote:
         | You brilliant lunatic
        
         | dom111 wrote:
         | I've been thinking about this for a while too.
         | 
         | I think that making editors do this is within the realms of
         | feasibility. Most support auto-formatting to your preferred
         | style so it doesn't feel like a leap for it to format to your
         | preferred style but keep the file on disk the project owner's
         | preferred style. I haven't looked extensively to see if this
         | already exists though but we chatted about this at work as I
         | was advocating for use of prettier on a front-end project!
        
         | michaelbarton wrote:
         | I think that's already possible using git smudge.
         | 
         | Example here: https://bignerdranch.com/blog/git-smudge-and-
         | clean-filters-m...
        
           | williamvds wrote:
           | Smudge & clean might do the trick, but it could be dirty. The
           | smudge -> clean process might produce additional changes that
           | aren't related to the purpose of your commit. Whitespace in
           | particular could be a problem, especially where there's
           | ambiguity in how it should be used. black isn't as bad
           | because it has stricter rules on whitespace. Still, if you
           | aren't checking style rules before every merge someone using
           | smudge and clean could end up reformatting entire files.
           | 
           | IMO the next next step is, as others have discussed on HN,
           | getting your version control to store and abstract syntax
           | tree. tree-sitter could make this easier nowadays, but I
           | think it'd need more invasive changes in Git than just using
           | the filters.
           | 
           | See this HN thread
           | https://news.ycombinator.com/item?id=28670372
        
       | euler_angles wrote:
       | Had a great experience with black. Only thing I did was change
       | its default line length limit to 120 characters (I was regularly
       | dealing with signal names from source data that were about 90
       | chars).
        
       | samwillis wrote:
       | I believe from memory Django decided to move to using Black back
       | in 2019 [0] but delayed the change until Black exited Beta. Black
       | became none beta at the end of January [1].
       | 
       | This was finally merged to the main branch today [2].
       | 
       | I suspect there are lots of other both open source and private
       | projects that are also making the change now. This is a show of
       | confidence in Black as the standard code formatter for Python.
       | 
       | 0:
       | https://github.com/django/deps/blob/main/accepted/0008-black...
       | 
       | 1: https://news.ycombinator.com/item?id=30130316
       | 
       | 2: https://github.com/django/django/pull/15387
        
         | dwightgunning wrote:
         | This is right. Black emerging from beta was discussed on the
         | Django mailing list in the last week or so, and triggered the
         | work.
        
       | bwhmather wrote:
       | Shameless plug: For people who like black, I've been working on
       | ssort[0], a python source code sorter that will organize python
       | statements into topological order based on their dependencies. It
       | aims to resolve a similar source of bikeshedding and back and
       | forth commits.
       | 
       | 0: https://github.com/bwhmather/ssort
        
         | stjohnswarts wrote:
         | This sounds like a living hell if you use git diff a lot to
         | compare for small changes that might introduce a bug? which is
         | what happens at work all the time since our unit test and CI
         | are a joke. Not dumping on your project but the idea of that
         | much of a change up of the code scares the dickens out of me.
        
           | danuker wrote:
           | Once the code is initially migrated (which should not break
           | it), the diffs won't be large, since the order should be
           | consistent.
        
             | bwhmather wrote:
             | One thing worth mentioning is that the `git blame` ignore
             | file trick doesn't work as well with ssort as it does with
             | black because the changes ssort makes tend to be much less
             | local.
        
           | drcongo wrote:
           | Use it at the editor level instead of in CI and I can't see
           | how it can cause you any problems at all. I could easily be
           | missing something though?
        
         | aaronchall wrote:
         | Does it put high-level business logic at the top or the
         | implementation details at the top?
         | 
         | Which is preferable, and why?
        
           | bwhmather wrote:
           | Implementation details at the top. Python is a scripting
           | language so modules are actually evaluated from top to
           | bottom. Putting high level logic up top is nice when you just
           | have functions, which defer lookup until they are called, but
           | you quickly run into places (decorators, base classes) where
           | it doesn't work and then you have to switch. Better to use
           | the same convention everywhere. You quickly get used to
           | reading a module from bottom to top.
        
             | mkesper wrote:
             | But this is really backwards? Everyone uses the if __name__
             | == "__main__" dance to avoid calling functions before
             | they're defined, no?
        
               | bwhmather wrote:
               | It is a bit backwards, but in exchange you get
               | predictability
               | 
               | With backwards sorting you know that, unless there is a
               | cycle, you can always scroll up from a call site to find
               | the definition or down from a definition to see where it
               | is used. With forwards sorting you can scroll down to
               | find a definition, unless the function was imported, or
               | used as a decorator somewhere, or called by something
               | that was used as a decorator, or used in some other way
               | that I haven't thought of.
               | 
               | My personal experience is that this predictability is
               | hugely useful. It almost entirely obviates the need for
               | jump-to-definition within a module, and gives modules a
               | very obvious shape and structure.
        
         | mulmboy wrote:
         | Sounds interesting and perhaps novel. Might help if there were
         | an example or two in the readme - as it is I still don't
         | exactly know what this is.
        
         | dopeboy wrote:
         | Very cool - I'll be following this.
        
         | VWWHFSfQ wrote:
         | Looks cool but it seems like it might still need some work?
         | 
         | I tried it on one of my Django `admin.py` files and it created
         | NameErrors.                   class
         | TestAdmin(admin.ModelAdmin):           list_filter =
         | ("foo_method",)                def foo_method(self, obj):
         | return "something"                foo_method.short_description
         | = "Foo method"              # It turned it into this:
         | class TestAdmin(admin.ModelAdmin):           list_filter =
         | ("foo_method",)                # NameError
         | foo_method.short_description = "Foo method"                def
         | foo_method(self, obj):             return "something"
        
           | bwhmather wrote:
           | Yup, that's a bug. All assignments are treated as properties
           | and moved to the top. Fix to follow shortly.
        
         | progval wrote:
         | Could you show an example in the README? The first two pairs of
         | input/output in
         | https://github.com/bwhmather/ssort/tree/master/examples look
         | unchanged
        
           | bwhmather wrote:
           | Will do. Examples directory isn't terribly helpful as
           | documentation as it mostly contains real code with
           | problematic syntax (and compatible licensing) that tripped up
           | ssort when I ran it on a copy of my pip cache. I will move it
           | into tests to avoid confusion
        
         | drcongo wrote:
         | This is relevant to my interests. We have an internal code
         | style guide at my company that includes guidelines for order of
         | class statements, roughly matching yours. I have one pet peeve
         | that made me write the style guide in the first place -
         | Django's `class Meta` which we _always_ have at the top of the
         | class because it contains vital information you need to know as
         | a programmer, like whether this class is abstract or not.
         | Whenever I have to work with an external Django codebase and
         | find myself scrolling through enormous classes trying to find
         | the meta my blood pressure rises.
        
           | bwhmather wrote:
           | I've had the same problem with pydantic. Currently,
           | properties are special cased and moved to the top. Everything
           | else, including classes, is grouped with methods. Meta
           | classes will end up somewhere in the middle, which is
           | probably the worst possible case.
           | 
           | SSort is currently used for several hundred kilobytes of
           | python so I'm wary, but if I'm going to make a breaking
           | change before 1.0 then I think this is likely to be it.
        
         | atoav wrote:
         | Some illustrative before-after syntax-highlighted code segments
         | would be a nice addition for the readme.
        
         | BeFlatXIII wrote:
         | Thanks for sharing this. When solo coding, I tend to dump new
         | classes and functions wherever is physically closest to where I
         | was previously editing. It makes sense in the moment so I don't
         | disrupt my train of thought by jumping all over the file, but
         | then is a confusing ball of mud when I need to return to the
         | project after time off. Was the shortest scroll direction up or
         | down when I implemented it? etc...
        
         | evilsnoopi3 wrote:
         | We use isort[0] for this. It even has a "black" compatible
         | profile that line spits along black's defaults. Additionally we
         | use autoflake[1] to remove unused import statements in place.
         | 
         | [0](https://github.com/PyCQA/isort)
         | 
         | [1](https://github.com/PyCQA/autoflake)
        
           | bwhmather wrote:
           | isort only sorts imports. ssort will sort all other
           | statements within a module so that they go after any other
           | statements they depend on. The two are complementary and I
           | usually run both.
        
         | BiteCode_dev wrote:
         | Very interesting, especially the method order part. I dislike
         | the order you chose, and yet, I would be tempted to use it on
         | my projects anyway, because being congruent is so important to
         | me.
        
       | phplovesong wrote:
       | Good bye git history!
        
       | NAHWheatCracker wrote:
       | I suggested Black to a team I was on a year ago and one developer
       | hemmed and hawed about how he likes to format arrays or
       | something. I didn't win any friends by pointing out that
       | disregarding those personal preferences is part of why I was
       | recommending it.
       | 
       | A year later and it seems to be the default on all projects I'm
       | working on and I'm loving it.
        
       | glacials wrote:
       | Black is slowly creeping into gofmt-level universality in the
       | Python community and it's great. The next big milestone is a
       | first-party recommendation by python.org itself.
        
         | VWWHFSfQ wrote:
         | I'm pretty sure it's a PSF project
        
       | vitorfs wrote:
       | This is such a great news. We've been using Black in the company
       | that I work for the past 3 years or so and it was a game changer
       | for code reviews. Hopefully other open source Python/Django
       | projects will follow the lead.
        
       | umvi wrote:
       | What's the point of putting linters into CI? Is the point to fail
       | the build if the code wasn't pre-formatted with i.e. Black? Or is
       | the point to autoformat and autocommit the formatted code?
        
         | selestify wrote:
         | > Is the point to fail the build if the code wasn't pre-
         | formatted with i.e. Black?
         | 
         | It's this. Ensures that anything merged to master keeps the
         | formatting conventions established in the project.
        
         | seattle_spring wrote:
         | The former, in my case. Last thing I want is someone merging
         | their own "creative interpretation" of proper formatting.
        
         | bckr wrote:
         | > Is the point to fail the build if the code wasn't pre-
         | formatted with i.e. Black?
         | 
         | It's this one
         | 
         | > Or is the point to autoformat
         | 
         | This one is done with pre-commit (which should probably be
         | named pre-push?) hooks
         | 
         | > and autocommit the formatted code?
         | 
         | I don't think this one is done, and I think it's undesirable
        
           | mkesper wrote:
           | Pre-commit hooks really happen when you type 'git commit'. If
           | you have failing checks in them, your commit will be aborted.
        
       | daenz wrote:
       | I'm so happy that languages are settling more and more on heavy
       | reformatter usage. I'd like to think it was triggered by Go and
       | gofmt. Working on a team where each engineer has their own
       | personal syntax is not fun.
        
         | MisterTea wrote:
         | > Working on a team where each engineer has their own personal
         | syntax is not fun.
         | 
         | Why did your team not implement a style guide? Not following
         | style is not working as a team and this needs to be addressed.
        
           | daenz wrote:
           | On this particular small team, there was no style guide, and
           | nobody could agree on what would go in it. It was
           | dysfunctional.
        
           | acdha wrote:
           | Style guides are a notorious time-sink where people will
           | spend enormous amounts of time debating various conventions
           | without that being linked to measurable benefits. One of the
           | big problems here is that people notoriously conflate
           | "familiar" with "better" and you rarely run the counter-
           | experiment showing that after a couple weeks everyone would
           | be familiar with any of the serious proposals.
           | 
           | The advantage of a tool like Black is that it avoids that
           | constant bikeshedding and the fact that it actually does the
           | work for you puts the conversation in a different light
           | because the option which is the least work is just letting
           | Black format the code. Whatever you pick for style, you
           | really want automatic formatting to avoid it seeming like a
           | chore.
        
             | MisterTea wrote:
             | > Style guides are a notorious time-sink where people will
             | spend enormous amounts of time debating various conventions
             | without that being linked to measurable benefits.
             | 
             | It feels like we're trying to justify the continued
             | employment of uncooperative, contrarian egoists. Pick a
             | style and use it or they can go find another job to waste
             | time debating nonsense.
        
               | acdha wrote:
               | There's some truth to that but I think it's more than
               | that. This comes up all of the time in the UI world: if
               | you ask people their opinion on something in the
               | abstract, they'll often provide a ton of ideas but if you
               | give them something which they can use now they'll
               | probably either say it's okay or come up with a much
               | smaller list of things they actually care about. Things
               | like style guides are especially tricky here because
               | people have opinions but they don't get a bill for
               | changes -- having a formatter available can shift that
               | dynamic to where you can basically say "Black does this
               | for free every time you hit save. Are you willing to
               | build a tool which maintains that level of effort?"
               | 
               | I've had that happen a few times and the number of people
               | who will volunteer opinions has consistently been at
               | least an order of magnitude larger than those who are
               | willing to contribute something like linter or formatter
               | configuration.
        
               | BeFlatXIII wrote:
               | Once they're all fired, there will be no one left to do
               | the work.
        
         | kaesar14 wrote:
         | Go and gofmt definitely pushed a lot of the momentum of the
         | current wave but don't forget to give respect to Ruby / Rubocop
         | where it's due, where the adage of Convention over
         | Configurability has reigned supreme for decades.
        
           | NegativeLatency wrote:
           | Rubocop has about a thousand config options
        
             | kaesar14 wrote:
             | Sure but the style guide standards exist and it's pretty
             | rare for a Ruby application to stray from them (from my
             | experience at a multi-billion dollar public company Ruby
             | shop)
        
         | belval wrote:
         | Indeed, I don't like Black's style, but I prefer working in a
         | Black codebase than one where everyone has their own
         | preference. Having style guidelines in a team is also a great
         | way to remove pointless debates when reviewing PRs.
        
           | daenz wrote:
           | Agreed, and what's interesting is that despite all of those
           | pointless style debates, there hasn't been much pushback on
           | using reformatters (that I've seen). This tells me that the
           | debates weren't really about "my style is objectively best"
           | but more about "I'd like to use a consistent/predictable
           | style (with preference to mine)."
        
             | belval wrote:
             | Quite right, I have not met a lot of people that were
             | actually strongly opinionated about their coding style.
             | They simply did not want to use a tribal one that was not
             | well defined that just added friction to the development
             | process.
        
           | declnz wrote:
           | +1
           | 
           | ...which is why I wish Black allowed more configuration. A
           | _team_ can often agree on a set of styles. Every team on the
           | Python planet agreeing... now that 's much harder
        
             | belval wrote:
             | I disagree on that though. By sticking to vanilla Black (no
             | pun intended) you ensure that people joining your time will
             | probably already be familiar with the style, you prevent
             | strongly opinionated employees from pushing for changes in
             | the linter config.
             | 
             | Black is opinionated, so it skips the debate entirely. We
             | just use Black, not black with 120 characters lines, just
             | Black.
             | 
             | To each their own I guess, but to me it just seems like
             | pandora's box. Once you show that you are open to changes
             | in the linting configuration, it makes the rules mutable
             | and pretty much guarantees that at some point someone will
             | say "how about we just change this one parameter in the
             | linter", which will probably be agreed by the rest of the
             | team, not because they actually agree but because they
             | don't want to argue.
        
             | harikb wrote:
             | > A team can often agree
             | 
             | this usually just means new team members are stuck
             | respecting the wishes of the old-timers
        
               | david422 wrote:
               | Yea, but in this case the old timers have chosen Black so
               | what's the difference?
        
             | heavenlyblue wrote:
             | > A team can often agree on a set of styles.
             | 
             | What for? Just to be clear even Django itself isn't
             | obviously using a configuration, what makes your team so
             | special they need this?
        
             | dumdumdumdum wrote:
             | https://github.com/google/yapf
        
             | pinkman68419 wrote:
             | The etymology of black is "any color you like, as long as
             | it's black" [0]. The whole point is that it's _not_
             | configurable.
             | 
             | [0] https://github.com/psf/black#readme
        
             | throwaway894345 wrote:
             | More configuration would allow for _more_ fragmentation...
        
       | mrtranscendence wrote:
       | 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.
        
         | steve_taylor wrote:
         | At least it doesn't have a dishonest name such as Prettier,
         | which turns perfectly good looking code into digital vomit.
        
           | [deleted]
        
           | thiht wrote:
           | Stop thinking opinions on code style are objective. Prettier
           | is good enough and NOT << digital vomit >>. Wtf.
        
         | magnusmundus wrote:
         | 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.
        
           | mrtranscendence wrote:
           | No, sorry, I meant python-reorder-imports, not black. It's a
           | separate project. I thought it was related but maybe I was
           | wrong.
        
         | heavenlyblue wrote:
         | 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.
        
           | declnz wrote:
           | 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_
        
           | jeffshek wrote:
           | There is an option to hide and autoformat inports.
        
           | mrtranscendence wrote:
           | 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.
        
         | Joeboy wrote:
         | 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.
        
           | mrtranscendence wrote:
           | Sorry, that's python-reorder-imports doing the reordering,
           | not black. I just thought it was a related (but separate)
           | project.
        
           | OJFord wrote:
           | 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,
        
             | mrtranscendence wrote:
             | 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.
        
         | ziml77 wrote:
         | Try isort instead https://github.com/PyCQA/isort
        
           | luhn wrote:
           | 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.
           | ..
        
           | jreese wrote:
           | Give usort 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
        
             | Spiritus wrote:
             | For me usort 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.
        
               | jreese wrote:
               | 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.
        
           | progval wrote:
           | 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
        
             | jreese wrote:
             | This is something usort 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
        
         | BeFlatXIII wrote:
         | 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.
        
       | SoylentOrange wrote:
       | I've been using black for about a year and I'm generally a big
       | fan. However my biggest gripe with it is bad VS Code integration.
        
         | claytonjy wrote:
         | bad how? i use vscode, I save a file, it reformats on save,
         | that's it.
        
       | jnothing wrote:
       | Why is it impossible to rebase? I didn't understand the
       | conversation around merging and rebasing
        
       | wolverine876 wrote:
       | Do Black and other autoformatters enable significantly more
       | reusable code and computer-generated code? Formatting is
       | certainly not the only or greatest barrier, but if format is
       | standardized across projects, it's easier to plug and play code
       | from outside.
        
       | codingkev wrote:
       | A little shoutout to a alternative Python formating tool
       | https://github.com/google/yapf (developed by Google).
       | 
       | The built in "facebook style" formating felt by far the most
       | natural to me with the out of the box settings and no extra
       | config.
        
         | BiteCode_dev wrote:
         | yapf is configurable, and that's why it never won.
        
           | crad wrote:
           | What's wrong with configurable? Too much opportunity to
           | bikeshed?
           | 
           | I figured yapf was not "new" which is why black won.
           | 
           | Starting about 5-6 years ago there was a push in the Python
           | community to replace solved problems with new ones in what
           | appears to me as chasing the JavaScript community.
           | 
           | Instead of consolidating on existing tools that worked well
           | but had some rough edges to smooth out, numerous projects
           | came about to reinvent the wheel.
        
             | BiteCode_dev wrote:
             | There is no "best format". It's a matter of opinion.
             | 
             | Taste is something we cannot objectively agree, and in
             | fact, people will end up arguing even about this very
             | statement, offering what they think is an objective
             | measure.
             | 
             | Bikesheding, yes. Hours lost in meeting, chat debates,
             | documentation to write, linting configuration. To be redone
             | for each project, team, etc. Worse even in FOSS where
             | everybody will come in a ticket and complain. And after
             | while, you do it again, because the debate is never settle
             | even in the same team or project.
             | 
             | There is not way to take a team of 3 people, choose a
             | style, and make it so that they are all 100% happy with it.
             | 
             | Black took the road of gofmt: you can't chose. And it won
             | because of that: it saved people time and energy.
             | 
             | People realize the cost was not worth the satisfaction,
             | which you are unlikely to get anyway. Let's just move on to
             | what matters, it's good enough. Pareto.
        
               | eredengrin wrote:
               | > Bikesheding, yes. Hours lost in meeting, chat debates,
               | documentation to write, linting configuration
               | 
               | Sounds like a team problem, I've been on plenty of teams
               | that use clang-format for c/c++ and there have never been
               | any issues like this. Team players know that (almost all)
               | arguing over formatting is not a good use of time. (edit:
               | in case not clear, clang-format is extremely
               | configurable. Set a default config and live with it
               | forever, that's how those teams work.)
               | 
               | > Black took the road of gofmt: you can't chose. And it
               | won because of that: it saved people time and energy.
               | 
               | I don't see how this follows, if a team was dysfunctional
               | enough to be wasting hours and hours of time before, I
               | can't imagine why that wouldn't continue. It just shifts
               | from "let's change this flag in yapf" to "let's switch to
               | yapf because black looks ugly and gives us no options".
        
               | BeetleB wrote:
               | All problems are team problems. It's OK to use technical
               | solutions to get around them.
        
               | BiteCode_dev wrote:
               | > Sounds like a team problem,
               | 
               | You had a good team. I had a great mum. Some people have
               | great doctors.
               | 
               | > It just shifts from "let's change this flag in yapf" to
               | "let's switch to yapf because black looks ugly and gives
               | us no options".
               | 
               | If the practice doesn't match the theory, I'd rather
               | trust the practice.
        
               | eredengrin wrote:
               | Well if it helps your team out then that's great, I just
               | wouldn't expect that to generalize well. But who knows,
               | people are weird, maybe more would give up fighting about
               | style because of a tool change than I expect.
        
               | BiteCode_dev wrote:
               | I don't have one team, I'm a freelancer, I meet 2 teams
               | each month. I have a large sample to generalize from.
        
             | stavros wrote:
             | > Too much opportunity to bikeshed?
             | 
             | Yes, and also too hard to set up. It's extremely dumb, but
             | I'm much more likely to use something I can't configure,
             | because if I _can_ configure it, I 'm going to _want to_ ,
             | and it'll take forever to make all those choices.
        
               | crad wrote:
               | I've never had to configure yapf, even though I could...
               | 
               | "yapf -i --style=pep8" works great.
        
         | timhh wrote:
         | I did a blind survey of YAPF vs Black at my work. The results
         | came back as 70% in favour of Black.
         | 
         | Black gives generally nicer output, and also _more predictable_
         | output because its folding algorithm is simpler. YAPF uses a
         | global optimisation which makes it make very strange decisions
         | sometimes. Black does too, but much less often.
         | 
         | There are also non-style problems with YAPF. It occasionally
         | fails to produce stable output, i.e. yapf(yapf(x)) != yapf(x).
         | In some cases it never stabilises - flip flopping between
         | alternatives forever!
         | 
         | Finally it seems to have very bad worst case performance. On
         | some long files it takes so long that we have to exclude them
         | from formatting. Black has no issue.
         | 
         | In conclusion, don't use YAPF! Black is better in almost every
         | way!
        
           | VectorLock wrote:
           | How did you perform the blind survey? Format some code with
           | Black and YAPF and ask people which they liked better?
        
         | lelandbatey wrote:
         | YAPF is slower than Black for many degenerate cases, a fact I
         | notice most strongly since I use an "auto-format file on file
         | save" extension in my editor. The case I found in particular
         | was editing large JSON schema definitions in Python, as they're
         | represented as deeply nested dictionaries. Black seems to
         | format them in linear time based on the number of bytes in the
         | file, while YAPF seems to get exponentially slower based on the
         | complexity of the hard-coded data structure. It was a niche
         | case, and the maximum slowdown was only ~1-2 seconds, but that
         | editing freeze was quite annoying.
        
       ___________________________________________________________________
       (page generated 2022-02-08 23:01 UTC)