[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)