45 ms·
Black: An uncompromising Python code formatter
- alexhill 8y agoI love it. Something I always wish for with linters is an easy way to run them only for the lines changed in a particular diff, to allow a codebase to gradually converge on consistency without breaking git blame by reformatting everything. Is there a nice way to do that for any Python linter?
- vjeux 8y agoAt Facebook we only tell you about lint violations for the lines you touch using arcanist from phabricator[1]. While it works great for most lint warnings, this hasn't worked that well for code formatters. The most successful strategy was to add a flag in the file (@format in the header) to tell that a file is automatically formatted. The immediate benefit is that we enable format on save for developers on those files when they use Nuclide (>90% of penetration for JavaScript and Hack). The other advantage is that when we release a new version of the formatter, we can re-run it on all those files so that people don't have lint warnings on code they already formatted in the past. With that setup, there's a strong incentive for individual engineers to run the formatter on their team codebase in one PR and then everyone benefits from now on. [1] https://secure.phabricator.com/ https://secure.phabricator.com/
- philwelch 8y agoHave you run into issues where the "let's reformat the entire codebase" commit makes `git blame` unusable?
- ambivalence 8y agoIt doesn't. Use `git hyper-blame` or `git blame $REV^ -- $PATH`. Sure, there is an additional step but we feel this shouldn't be a blocker for significant workflow improvements. In fact, a single big "reformat all" commit is better than a bunch of incremental ones that reformat areas that you also change semantically. That is harder to filter and makes diffs harder to follow (which changes are logic and which are just style?).
- sciurus 8y agoI hadn't head of hyper-blame before. It's part of chromium's depot_tools. > git hyper-blame is like git blame but it can ignore or "look through" a given set of commits, to find the real culprit. https://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/git-hyper-blame.html https://commondatastorage.googleapis.com/chrome-infra-docs/f...
- nwatson 8y agoMaybe I missed it, but I don't see a comparison with PyCharm's built-in code formatter. Why would I integrate this code-formatter, "black", into PyCharm when PyCharm already does this for me and the whole team?
- dexterdog 8y agoI'm also assuming pycharm has some options. This thing seems to make very specific decisions and if you don't agree with them, tough.
- zepolen 8y agoNot everyone runs PyCharm, and this tool is open source.
- ageitgey 8y agoPyCharm itself is open source. https://github.com/JetBrains/intellij-community/tree/master/python https://github.com/JetBrains/intellij-community/tree/master/...
- philosopherlawr 8y agoYou can run this on pre-commit. While you can set PyCharm to run on file save, it is not guaranteed to run on all files. By using a command line tool, you can enforce that all files across your project are formatted this specific way and never let someone check in something that doesn't conform to it. If you have newbie developers, it can be a lifesaver.
- prawl 8y agoYou edit code, test it, and then have some program rewrite your code after testing but before it becomes an immutable commit hash?
- Twirrim 8y agoWhy do you want your code formatter tied explicitly to an IDE? Why would you want to force everyone on your team to use the same editor? Use independent components, and let people use what they work best in.
- curtis 8y ago> By using it, you agree to cede control over minutiae of hand-formatting. I may be in a minority, but I do not want to cede control over minutiae of hand-formatting. Am I the only person that feels this way?
- jowiar 8y agoIf you’re working alone, fine. But when working with other people, getting everyone to do the same thing, and have that automatically done for you / enforces is incredibly valuable. It’s such a massive win that any deviation from “my personal optimum formatting” is rounding error.
- zephyrfalcon 8y agoNot really. I worked at one place where they enforced PEP8 (using flake8 etc) using a git commit hook. In other words, when you try to commit some code, it would run flake8 which would most likely balk at some of the changes you made (and not let you commit until those were fixed). A lot of the rules/warnings are extremely nitpicky, and they had all of them turned on (except for the line length); I don't know how many times I could not commit my code because I left a space at the end of a line, or an empty line contained whitespace, or I had only one blank line between two class definitions, etc. It was just ridiculous. I can understand the argument for having all code in the same format, but this kind of mechanism just seriously decreased my productivity, not in the least because it constantly pissed me off. Admittedly, Black works differently; as I understand it, it will just auto-reformat your code rather than yelling at you and making you go through your code and fix everything by hand, which is what the aforementioned approach did. Still, I wonder about the usefulness of such tools. Python code is already much more uniform than most other languages. Also, I am not sure you should take the last crumbs of creativity or personal preference away from programmers. Last but not least, PEP 8 is meant as a style guide, not as a book of law that needs to be enforced at all costs. Some of the Python core developers seem to agree; I have seen comments from Guido and others who apparently think that such tools go against the spirit of the PEP.
- 8y ago
- vjeux 8y agoAt Facebook, we are now using prettier[1] on all our JavaScript files, a growing number of Hack files are formatted with Hackfmt[2] and now black is being rolled out for Python. It's a really exciting time :) [1] https://prettier.io/ https://prettier.io/ [2] https://github.com/facebook/hhvm/blob/master/hphp/hack/src/hackfmt.ml https://github.com/facebook/hhvm/blob/master/hphp/hack/src/h...
- philip1209 8y agoWhy black over yapf?
- ambivalence 8y agoBlack is a simple tool. It tries to implement a single code style well. It's not configurable. We tried YAPF before and could never roll it out for everybody. I even contributed the "facebook" style to the tool. There were a few reasons why YAPF didn't work out for us but the most important were: - YAPF would at times not produce deterministic formatting (formatting the same file the second time with no changes in between would create a different formatting); Black treats this as a bug; - YAPF would not format all files that use the latest Python 3.6 features (we have a lot of f-strings, there's cases of async generators, complex unpacking in collections and function calls, and so on); Black solves that; - YAPF is based on a sophisticated algorithm that unwinds the line and applies "penalty points" for things that the user configured they don't like to see. With a bit of dynamic programming magic it arrives at a formatting with the minimal penalty value. This works fine most of the time. When it doesn't, and surprised people ask you to explain, you don't really know why. You might be able to suggest changing the penalty point value of a particular decision from, say, 47 to 48. It might help with this particular situation... but break five others in different places of the codebase.
- vjeux 8y agoAnother issue is that yapf uses an algorithm that is quadratic, so you end up with code you actually see in practice take seconds to minutes to format. The authors have been adding specific workarounds for some cases but it's a general issue with the approach: - https://github.com/google/yapf/issues/264 https://github.com/google/yapf/issues/264 - https://github.com/google/yapf/issues/39 https://github.com/google/yapf/issues/39 Black algorithm doesn't explode in such way. It's also a lot faster overall which makes it possible and reasonable to enable a good format on save experience.
- philosopherlawr 8y agoHow does this compare to yapf?
- deleted 8y ago[deleted]
- ambivalence 8y agoAnswered here: https://news.ycombinator.com/item?id=17155205 https://news.ycombinator.com/item?id=17155205
- ianamartin 8y agoI'm so glad this is a thing. I get so tired of people arguing about the small stuff. Sometimes too much freedom is a bad thing. It seems okay at first, and you try to be as democratic as you can with your team, and then someone wants something really wonky, and PEP8 and PEP257 don't say it's absolutely wrong after all, and shit just wastes time. I don't agree with every detail--double quotes as default is going to be hard for me to adjust to--but the things I don't agree with aren't as important to me as being able to set it and forget it and stop debating it every so often. This is the gofmt the python world needs. As far as I'm concerned this is the new standard. Well done.
- acdha 8y ago> I don't agree with every detail--double quotes as default is going to be hard for me to adjust to--but the things I don't agree with aren't as important to me as being able to set it and forget it and stop debating it every so often. That's the key part for me, too: Black offers the freedom of not needing to waste time talking about things which really don't matter. No more wasting time on code review where the real issues are obscured by sloppy whitespace, idiosyncratic formatting preferences, etc. I also had a preference for single quotes but … every file in every project I work on is consistent as soon as I hit save and I certainly don't care enough not to let that outweigh a minor aesthetic point.
- kungtotte 8y agoEven if your team is totally on board with your style guide, everyone wants to stay pep8/257 compliant, no arguments, you use linters to warn about errors, etc. you will still have some instances of people committing code that breaks the guidelines. Either it gets caught in code review and you have to waste time with nitpicking, or worse it makes it through to the repo and now you have to make a commit to fix what amounts to a typo. Autoformatting with a unified, consistent tool means that you remove all those problems.
- crooked-v 8y ago88 characters per line is a weird choice. Why not 90?
- drivingmenuts 8y ago90 characters?!?!? You heathen. I want 132 characters per line.
- revfried 8y agoScience. 88 produced smaller files than 80. And 90 and above didn’t noticeably shorten files. Like Raymond Hettinger said in his talk beyond pep8, 90ish is better than a strict 80. If you have 81 characters on a line its a waste of time to move that to three lines and now harder to read. So there should be some buffer. that buffer is 10%. The goal is 80 but we are ok with up to 88.
- gugagore 8y agobut no matter what, it's a strict something, right? in Black it's a strict 88 by default (unless it violates some other rule, if I understood the readme)
- ambivalence 8y agoOriginally PEP 8 had 79 characters. Now that was a weird choice so most companies went with 80 instead, including Facebook. You want a low-ish limit because it makes it possible to fit two files side by side on a typical screen resolution. Even if you don't edit like that, you look at diffs like that. More importantly, a low column limit is helpful to disabled engineers who don't have to navigate horizontally so much. So we used 80. I always felt bad when the linter stopped people from pushing impactful changes because they went over the limit by two characters. So two years ago I set up a "highway speed limit" style warning in flake8 (code B950 in PyCQA/flake8-bugbear). What it does is it keeps your limit intact (for example "80") but doesn't trigger unless you went over by more than 10%. So the limit happens to be 88. When I was working on Black, I was faced with a dilemma. Should the formatter stick to 80 or be able to "go over" a bit, too, as we would let humans do. I felt like the latter made more sense as the resulting code looks nicer (fewer occasions to break a single line into three or more). Then I remembered Raymond's talk "Beyond PEP8" where he mentions that experience shows "90-ish" is the wisest choice. So I went with it.
- thanatropism 8y agoAny word out about a version for emacs?
- chimprich 8y agoFrom the linked GitHub page, it says for Emacs integration use https://github.com/proofit404/blacken https://github.com/proofit404/blacken . I haven't tried it.
- revfried 8y agoI find as I write code I no longer worry about alignment or long lines. When I have vim paste a section of code and its at a different indentation I just run black.
- abakus 8y agoI like the spirit of it, but the implementation seems to contain too many exceptions (e.g. trailing comma, whilespaces around :). This problem is not unique to Black, it is actually too common for most auto-formatters. I usually prefer a set of dead-simple formatting/styling rule, easier to enforce, lower cognitive load.
- ambivalence 8y agoWhat don't you like about the exceptions? The code and the documentation would both be simpler without them. They are there because the end result is closer to what a human would do in those situations. And the two exceptions you mentioned are ones you will also have to make if you want to stay PEP 8 compliant (pycodestyle's E203 is invalid inside slices) and you want your code to execute on Python pre-3.6 (where you can't add trailing commas to calls and signatures containing args and *kwargs).
- fishywang 8y ago> where you can't add trailing commas to calls and signatures containing args and kwargs I think that's signature only. You don't have problems with calls: $ python3.5 Python 3.5.5 (default, May 17 2018, 07:04:26) [GCC 7.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> def foo(*args, **kwargs): ... print(*args, **kwargs) ... >>> foo( ... 'abc', ... ) abc >>> The argument black made about not adding trailing comma is also quite unconvincing to me: > Unnecessary trailing commas are removed if an expression fits in one line. This makes it 1% more likely that your line won't exceed the allotted line length limit. Moreover, in this scenario, if you added another argument to your call, you'd probably fit it in the same line anyway. That doesn't make diffs any larger. Who cares about the 1% chance of not exceeding the line length limit? If you really care about that, use one-per-line style, not all arguments in one new line.
- ambivalence 8y agoYeah, call side was fixed in 3.5 but I don't split hairs here. I consider it either 3.6+ or don't put trailing commas after neither signatures nor calls with stars. BTW, your signature doesn't demonstrate a call with unpacking. What you meant to test was: l = [1, 2, 3] foo(0, *l,) This works in 3.5+ but fails on 3.4 and before.
- limsup 8y ago88 column wrap? Yeah - no thanks.
- biswaroop 8y agoCurious, why is this a bad thing? Also it seems like you can change it to a lower number if you want.
- limsup 8y ago80 columns is very standard.
- rhencke 8y agoIt was a standard from a time when we had green-screen terminals only capable of displaying an 80x24 grid of characters. (https://en.wikipedia.org/wiki/VT100 https://en.wikipedia.org/wiki/VT100) It's worth asking - does the standard make sense still, given how we edit today?
- gsich 8y agoProbably not, there is line wrap.
- manigandham 8y agoDefinitely not. We turn all line-wrapping off. Everybody has wide-screens.
- demosito666 8y agoAnd nobody uses split windows? No screen can comfortably fit more then about 200 columns, so I believe 100 is the absolute maximum width.
- manigandham 8y ago
- deleted 8y ago[deleted]
- spocklivelong 8y agoI just tried this on a Django project, and it formatted all the migration files as well. Is there a way to exclude certain directories when formatting a whole project?
- ambivalence 8y agoI'm working on that. In the mean time use your Unix fu with `find | grep | grep -v | xargs black`.
- itwy 8y agoSo what? How is that harmful?
- kbd 8y agoI take it it's because the migration files are auto-generated anyway, so it's odd to auto-format previously auto-generated files. You also don't really want to have repository churn on those files since they're generated once (and then never edited again) along with the feature they're for.
- QasimK 8y agoIt would be a one-time auto-format just like the one-time auto-format that black will do for the rest of the project. Any newly auto-generated files can be formatted before they are committed. So I don't see it actually adding to the harm.
- joobus 8y agoAnyone know how I can get auto format on save to work in Vim with Black? I installed with Plug. Figured it out: `autocmd BufWritePre *.py Black`
- zestyping 8y agoThis is great except for the enforcement of double-quotes around all strings and spaces around slice operators. These two choices contradict the standard Python documentation, most of the standard library, and the behaviour of the interpreter itself. When the language itself has an established convention, Black should follow that convention, not fight it. These two weird choices just generate needless churn, which is surprising as it seems Black has quite the opposite goal. It's a shame, because all the other design choices in Black are pretty good!
- kstrauser 8y agoThat's the #1 complaint I have (and hear) about Black. Everything else, I can live with. And honestly, I can live with using double quotes everywhere, especially when I can type single quotes and then let it re-write them. It's just that they currently look really, really odd to me because that's not how Python is traditionally written.
- stevesimmons 8y agoI prefer a quoting convention of single quotes for text identifiers (as they rarely contain quotes) and double quotes for English text (because contractions are common). Thus: key['first_name'] print("Isn't this clearer?")
- gvx 8y agoI generally follow this convention: 1. Any string literal that contains either ' xor " will be delimited by the other one. 2. For all other string literals, delimit by " if it's meant for human eyes only, delimit by ' if it's meant for computers as well.
- masklinn 8y agoSame, though I'd word the first one as programmatic identifiers. Adopted that from Erlang, where atoms are single-quoted and text strings are double-quoted.
- 8y ago
- ra7 8y agoHow does this compare with Yapf (https://github.com/google/yapf https://github.com/google/yapf)?
- ambivalence 8y agoAnswered here: https://news.ycombinator.com/item?id=17155205 https://news.ycombinator.com/item?id=17155205
- pomber 8y agoIs it possible to bind blackcellmagic[1] to run automatically everytime a cell is ran in a Jupyter notebook? [1] https://github.com/csurfer/blackcellmagic https://github.com/csurfer/blackcellmagic
- sametmax 8y agoYou can explore putting something like : require([ "base/js/namespace", "base/js/events" ], function(Jupyter, events){ events.on('finished_execute.CodeCell', function(){ // execute black here }); }); In ~/.jupyter/custom/custom.js.
- epr 8y ago--single-quoted-strings would be a really nice option for the vast majority of python programmers that use single quotes by default.
- mjkunc 8y agothis is the only issue stopping my team from adopting black.
- prawl 8y agoThis isn't a vast majority by any stretch of the imagination.
- jhall1468 8y agoThe overwhelming response here saying use single quotes begs to differ.
- ambivalence 8y agoThat's not how this works. All the people who are just happy or indifferent about double quotes don't comment about it. And some of the ones that aren't happy about it commented here multiple times. Judging from the additional stars on GitHub, and projects that just migrated (pytest!), I'd say there's a very vocal minority which is very attached to single quotes.
- pkilgore 8y agoSelection bias is real here. I thought dbl quotes smart for all the reasons in the readme. Me commenting 'this is great' is just noise on HN, and discouraged by the rules. Never take self-selected anything as truth, especially comments (tweets/posts/voluntary votes)
- aldanor 8y agoThis is all subjective unless some data is collected. I could say with just as much confidence that all of the major Python projects I've seen or contributed to use single quotes -- e.g. numpy or pandas.
- 49bc 8y ago> You will save time and mental energy for more important matters. Exactly why every language, from here until the end of time, should have a “go fmt” equivalent.
- danpalmer 8y agoI really want to use Black, but we have a particular style point that we’d miss so much that we haven’t adopted it yet... Double quotes for strings that need to be human readable, single quotes otherwise. This makes it so obvious when something is going to be sent to the user, we find it really useful. That said, I think Black’s appeal is it’s uncompromising nature, so I wouldn’t ask it to change. Adding the option to turn off quote formatting would probably go against its vision. Also, it could be argued that we should use the internationalisation functions to denote strings sent to the user, but hey we don’t do i18n yet. For now, this, and one or two places that it fails to have an opinion (number of lines after imports) are keeping us from using it.
- ambivalence 8y agoDo you find your team enforcing the string quote rule consistently? It seems to me like it's easy to miss at times as automatic enforcement is impossible. Are there no cases where a string that wasn't originally planned to be user-visible ends up being so? I've heard this idea at times but when I looked at actual codebases it turns out it's more of an aspiration than an actual rule. And if you can't depend on it, why have it? As for number of lines after imports, how is a lack of enforcement there stopping you from using the tool? Black enforces one line but is fine if you put two (on module level). In general, if you give up on the tool due to a missing rule, you end up having to manually enforce tens of other rules that you'd otherwise be free from.
- lambda 8y agoI kind of subconsciously do the same thing; use single quotes for symbol-like strings, and double for human readable. But I can buy the argument that just having a single auto-enforced rule improves consistency and that has greater benefits than the somewhat vague distinction that is not enforced.
- yycom 8y ago> And if you can't depend on it, why have it? That's a bit rich. There are other conventions in programming that you can't depend on technically but serve a real purpose. Identifier naming and comments are the first that come to mind. If a language gives you a choice of token that has no semantic distinction then different people will adopt different semantics by convention. As an aside, calling a tool "opinionated" is code for "my conventions are better than yours". That's fine if I don't have any conventions or I can't decide, but if I have decided, then it's just offensive.
- abaldwin7302 8y agoIs this conceptually different from using pylint, failing the build for any warnings and saying anyone who modifies the `pylintrc` file gets fired?
- ambivalence 8y agoSounds like you're joking but I'll bite. Yes, it's different because doing what you suggest introduces barriers for people which make landing changes harder. By forcing people to conform to any style manually, especially by blocking them from landing important features and bug fixes due to styling preferences, you are building up opposition. It's just a bad experience for everybody involved. In contrast, when you're promising that this exact problem won't happen anymore because an automatic tool will handle stylistic preference for your team, people are more willing to accept stylistic choices they (mildly) disagree with. Because on average the style is still better and on average everybody can move faster.
- abaldwin7302 8y agoAgreed auto-correct is a big plus. Maybe a better way to phrase my question is this: Can auto-correct be implemented in pylint? Or does allowing configurations create too much of an obstacle? In the ruby world for example, rubocop has an auto-correct feature. However it is only implemented for a subset of the style checks.
- rocky1138 8y agoWhy is this better than autopep8?
- ambivalence 8y agoBlack and YAPF introduce consistent formatting within an entire file. Ironically, autopep8 goes against PEP 8 by only targetting the places in the file that generate pycodestyle warnings. Some of the warnings are also incompatible with PEP 8 (W503, E203) and the chosen formattings might very well be inconsistent with the rest of the file.
- ljm 8y agoIn case of credit where credit’s due, is gofmt where the concept of auto-formatting syntax became mainstream? At first I hated it because I thought I had a style, but later on I enjoyed the consistency far more than I enjoyed my signature approach. A programming language has an opinion on how you build software with it, so it’s appreciated that it also has an opinion on how you should write it so that it remains consistent and easy to follow. No debate about where to put braces or semicolons or whatever else doesn’t matter when putting something in front of your users. It feels like dumbing down in a way, which is sad, but I think this is more for the benefit of collaboration than individualism or artistic intent. In that case you either disable the tool or refuse to use it. In every other case, you’ve automated away almost every nitpick from a code review.
- platinumrad 8y agoI think the unconfigurability of gofmt may be its greatest strength. Indent, etc. have existed for years but getting everyone to just agree on a reasonable style is invaluable. GNU Indent's default style is one that (almost) nobody uses and the number of available options is overwhelming. rustfmt's default style is fine, but it also has an overwhelming number of options, in addition to not handling line wrapping well. ocp-indent is the only other formatter I've used that's as painless as gofmt.
- sametmax 8y agoWhen i heard about gofmt, i hated it. I wanted choice. Then i realised i loved python because it forced people to indent. I gave black a try. I still hate some style decisions, but who cares ? The benefits are far too great to pass up.
- ljm 8y agoI felt the same with Prettier and the 80 char limit. At the same time, it solved every single style problem except the choice of line length! That is a fantastic achievement.
- iainmerrick 8y agoGo is probably where it went mainstream in the current generation, yeah, but the idea has definitely been around for a while. The earliest implementation I know of was COMAL, a very clean and tidy version of BASIC, I think dating from around 1980. A lot of 80s micro BASICs did some level of auto-formatting purely as a side-effect of the source code being stored in tokenized form to save memory.
- manigandham 8y agoI wish there was something like this for C#/.NET .editorconfig is a start but the amount of time saved through automation and removing customization is significant.
- erikig 8y agoI chuckled at this "If you're paid by the line of code you write, you can pass --line-length with a lower number."
- fishywang 8y agoOn the example there's: # in: TracebackException.from_exception(exc, limit, lookup_lines, capture_locals) # out: TracebackException.from_exception( exc, limit, lookup_lines, capture_locals ) I don't like this one. I would prefer that if you have )/]/} on the next line, then you should have a trailing comma, e.g.: TracebackException.from_exception( exc, limit, lookup_lines, capture_locals, ) Also I would prefer one-per-line over all in the same line (but not on the same line with the parentheses), but I feel less strongly about that one.
- makapuf 8y agoSure you can prefer this but it is not the point. The point is that having ONE average way to do it > several best ways for several people.
- fishywang 8y agoI'm saying this is a weird/below-average way to do it. If this cannot fit in one line: foo(arg1, arg2) My first choice would be: foo( arg1, arg2, ) Second choice would be: foo( arg1, arg2, ) While Black chooses: foo( arg1, arg2 ) And made some unconvincing argument about it: > Unnecessary trailing commas are removed if an expression fits in one line. This makes it 1% more likely that your line won't exceed the allotted line length limit. Moreover, in this scenario, if you added another argument to your call, you'd probably fit it in the same line anyway. That doesn't make diffs any larger. Who cares about the 1% chance of not exceeding the line length limit, really?
- makapuf 8y agoI know and I completely agree. Maybe a kind of vote could be made on this kind of choices. But what would be really nice would be git "style lenses" : having different styles to edit or share.
- hrez 8y agoWhat's with python 3.6 requirement? - Major stable distros are at python 3.5. So I can't even try it without messing with system python or OS.
- toyg 8y agoProbably because of f-strings.
- ambivalence 8y agoIt's open source software created by a volunteer. Using the latest version of Python lets me leverage features which help me focus on the problem at hand. f-strings, pathlib integration, the latest typing module, and so on. I'm sorry this makes using my tool harder for you but I'm sure there is an easy way for you to install Python 3.6 without destroying your system Python. There's Homebrew for macOS, deadsnakes for Ubuntu, EPEL for RedHat, and so on.
- foxhop 8y agoThis is so cool. I like all the choices and will be adding it to my workflows for my personal projects.
- jsmeaton 8y agoI wanted to add a bit of positivity and mention that I'm really liking how the black project is approaching problems. For example, a few people brought up fluent interfaces[0] as an issue. There were many opinions about the right and wrong thing to do, but discussion got to a very pragmatic decision I feel. Then there were requests to add command line arguments specifically so that tools could integrate with black that were added almost immediately. Congrats on gaining so much traction so quickly, and thanks for listening to users (when it makes sense). [0] https://github.com/ambv/black/issues/67 https://github.com/ambv/black/issues/67
- zaius 8y agoHas anyone rolled this out to an existing codebase? What's the best practice? A single commit that reformats the whole codebase? How do you avoid creating merge hell?
- ambivalence 8y agoYou can see how this was done for Fabric, PyPA/Warehouse, and pytest. General guidelines: 1. One commit with only the automatic formatting. Afterwards you'll be able to skip over it easily with `git hyper-blame` or `git blame $BLACK_REV^ -- $FILE`. 2. Avoid leaving open pull requests. If you do, after landing the blackening commit, blacken all pull requests, too. They shouldn't conflict then. 3. Set up enforcement with pre-commit or CI (you can run `black --check` on Travis or similar). 4. Don't forget the repo badge ;-)
- davidfstr 8y agoLove the idea of eliminating formatting debates when writing Python. At the risk of being redundant, I also raise an eyebrow at the choice to prefer double quotes for strings. My company standardized on single quotes, mainly to be consistent with repr and also encourage the use of double quotes in messages displayed to the user. Everything else seems in order. I might increase the line width to 90 just to use an easier value to remember when configuring editors and other tools ;)
- G4BB3R 8y agoPaulo Torrens is crying.
- ianamartin 8y agoAfter testing this some tonight, I'm committed to my first-blush response. This is my standard from now on, and it is the standard for my team. Someone needs to ask a StackOverflow question about Python formatting and we need to answer it with "Just use Black." Upvote the fuck out of it, and be done with this forever.
- Southclaws 8y agoI've been long awaiting a Python equivalent of gofmt and prettier.js!
- quietbritishjim 8y agoThe problem with code formatters for Python is that you can't just break lines using whitespace; you need to insert symbols, ideally parentheses. For example, if you need to break this line of code: left[first][second] = right[first][second][third] Manual breaking looks like this: left[first][second] = ( right[first][second] [third] ) Code formatters will produce something like the following atrocity: left[first][second ] = right[first][second][ third] Comments and strings are also unwrappable if the formatter is afraid of inserting characters.
- ambivalence 8y agoDid you actually try Black on a line like this?
- quietbritishjim 8y agoI must admit I didn't. I felt confident it was restricted to adding and removing whitespace because the README says at the start: > Black ignores previous formatting and applies uniform horizontal and vertical whitespace to your code. I now see it does sometimes modify non-whitespace characters e.g. later in the README it mentions: > In [certain] cases, parentheses are removed when the entire statement fits in one line I'm not in a position to test black out right now (I can't run Python on the computer I'm posting this comment on). I'd be curious to know what it does on the code I posted, and on over-length comments and string literals.
- freyir 8y agoI tried it. Black doesn't seem to touch long strings or comments. It just leaves you with "line too long" errors that you can clean up yourself. For your code example, see my comment above.
- freyir 8y agoIn: left[a_rather_long_key][a_rather_long_key] = right[a_rather_long_key][a_rather_long_key][a_rather_long_key] Out: left[a_rather_long_key][a_rather_long_key] = right[a_rather_long_key][ a_rather_long_key ][a_rather_long_key]
- Fizzadar 8y agoThis is great - especially _removing_ hanging indents which is a real pet hate of mine! Only issue is the quotes - I'd love to see Black leave those as single if flake8 is configured to do so, for all the reasons mentioned in the comments.