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