## File: README.md

[](https://black.readthedocs.io/en/stable/)

<h2 align="center">The Uncompromising Code Formatter</h2>



> “Any color you like.”

_Black_ is the uncompromising Python code formatter. By using it, you agree to cede
control over minutiae of hand-formatting. In return, _Black_ gives you speed,
determinism, and freedom from `pycodestyle` nagging about formatting. You will save time
and mental energy for more important matters.

Blackened code looks the same regardless of the project you're reading. Formatting
becomes transparent after a while and you can focus on the content instead.

_Black_ makes code review faster by producing the smallest diffs possible.

Watch the [PyCon 2019 talk](https://youtu.be/esZLCuWs_2Y) to learn more.

---

**[Read the documentation on ReadTheDocs!](https://black.readthedocs.io/en/stable)**

---

## Installation and usage

### Installation

_Black_ can be installed by running `pip install black`. It requires Python 3.10+ to
run. If you want to format Jupyter Notebooks, install with
`pip install "black[jupyter]"`.

If you want to run _Black_ without installing Python, download one of the
PyInstaller-built standalone executables from the
[latest GitHub release](https://github.com/psf/black/releases/latest).

### Usage

To get started right away with sensible defaults:

```sh
black {source_file_or_directory}
```

You can run _Black_ as a package if running it as a script doesn't work:

```sh
python -m black {source_file_or_directory}
```

Further information can be found in our docs:

- [Usage and Configuration](https://black.readthedocs.io/en/stable/usage_and_configuration/index.html)

_Black_ is already [successfully used](https://github.com/psf/black#used-by) by many
projects, small and big. _Black_ has a comprehensive test suite, with efficient parallel
tests, and our own auto formatting and parallel Continuous Integration runner. Now that
we have become stable, you should not expect large formatting changes in the future.
Stylistic changes will mostly be responses to bug reports and support for new Python
syntax. For more information please refer to
[The Black Code Style](https://black.readthedocs.io/en/stable/the_black_code_style/index.html).

Also, as a safety measure which slows down processing, _Black_ will check that the
reformatted code still produces a valid AST that is effectively equivalent to the
original (see the
[Pragmatism](https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#ast-before-and-after-formatting)
section for details). If you're feeling confident, use `--fast`.

## The _Black_ code style

_Black_ is a PEP 8 compliant opinionated formatter. _Black_ reformats entire files in
place. Style configuration options are deliberately limited and rarely added. It doesn't
take previous formatting into account (see
[Pragmatism](https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#pragmatism)
for exceptions).

Our documentation covers the current _Black_ code style, but planned changes to it are
also documented. They're both worth taking a look at:

- [The _Black_ Code Style: Current style](https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html)
- [The _Black_ Code Style: Future style](https://black.readthedocs.io/en/stable/the_black_code_style/future_style.html)

Changes to the _Black_ code style are bound by the Stability Policy:

- [The _Black_ Code Style: Stability Policy](https://black.readthedocs.io/en/stable/the_black_code_style/index.html#stability-policy)

Please refer to this document before submitting an issue. What seems like a bug might be
intended behaviour.

### Pragmatism

Early versions of _Black_ used to be absolutist in some respects. They took after its
initial author. This was fine at the time as it made the implementation simpler and
there were not many users anyway. Not many edge cases were reported. As a mature tool,
_Black_ does make some exceptions to rules it otherwise holds.

- [The _Black_ code style: Pragmatism](https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#pragmatism)

Please refer to this document before submitting an issue just like with the document
above. What seems like a bug might be intended behaviour.

## Configuration

_Black_ is able to read project-specific default values for its command line options
from a `pyproject.toml` file. This is especially useful for specifying custom
`--include` and `--exclude`/`--force-exclude`/`--extend-exclude` patterns for your
project.

You can find more details in our documentation:

- [The basics: Configuration via a file](https://black.readthedocs.io/en/stable/usage_and_configuration/the_basics.html#configuration-via-a-file)

And if you're looking for more general configuration documentation:

- [Usage and Configuration](https://black.readthedocs.io/en/stable/usage_and_configuration/index.html)

**Pro-tip**: If you're asking yourself "Do I need to configure anything?" the answer is
"No". _Black_ is all about sensible defaults. Applying those defaults will have your
code in compliance with many other _Black_ formatted projects.

## Used by

The following notable open-source projects trust _Black_ with enforcing a consistent
code style: pytest, tox, Pyramid, Django, Django Channels, Hypothesis, attrs,
SQLAlchemy, Poetry, PyPA applications (Warehouse, Bandersnatch, Pipenv, virtualenv),
pandas, Pillow, Twisted, LocalStack, every Datadog Agent Integration, Home Assistant,
Zulip, Kedro, OpenOA, FLORIS, ORBIT, WOMBAT, and many more.

The following organizations use _Black_: Dropbox, KeepTruckin, Lyft, Mozilla, Quora,
Duolingo, QuantumBlack, Tesla, Archer Aviation.

Are we missing anyone? Let us know.

## Testimonials

**Mike Bayer**, creator of [`SQLAlchemy`](https://www.sqlalchemy.org/):

> I can't think of any single tool in my entire programming career that has given me a
> bigger productivity increase by its introduction. I can now do refactorings in about
> 1% of the keystrokes that it would have taken me previously when we had no way for
> code to format itself.

**Dusty Phillips**,
[writer](https://www.amazon.com/stores/Dusty-Phillips/author/B00HSYG5BO):

> _Black_ is opinionated so you don't have to be.

**Hynek Schlawack**, creator of [`attrs`](https://www.attrs.org/), core developer of
Twisted and CPython:

> An auto-formatter that doesn't suck is all I want for Xmas!

**Carl Meyer**, [Django](https://www.djangoproject.com/) core developer:

> At least the name is good.

**Kenneth Reitz**, creator of [`requests`](https://requests.readthedocs.io/en/stable/)
and [pipenv](https://pipenv.pypa.io/en/stable/):

> This vastly improves the formatting of our code. Thanks a ton!

## Show your style

Use the badge in your project's README.md:

```md
[](https://github.com/psf/black)
```

Using the badge in README.rst:

```rst
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
    :target: https://github.com/psf/black
```

Looks like this:
[](https://github.com/psf/black)

## License

MIT

## Contributing

Welcome! Happy to see you willing to make the project better. You can get started by
reading this:

- [Contributing: The basics](https://black.readthedocs.io/en/latest/contributing/the_basics.html)

You can also take a look at the rest of the contributing docs or talk with the
developers:

- [Contributing documentation](https://black.readthedocs.io/en/latest/contributing/index.html)
- [Chat on Discord](https://discord.gg/RtVdv86PrH)

## Change log

The log has become rather long. It moved to its own file.

See [CHANGES](https://black.readthedocs.io/en/latest/change_log.html).

## Authors

The author list is quite long nowadays, so it lives in its own file.

See [AUTHORS.md](./AUTHORS.md)

## Code of Conduct

Everyone participating in the _Black_ project, and in particular in the issue tracker,
pull requests, and social media activity, is expected to treat other people with respect
and more generally to follow the guidelines articulated in the
[Python Community Code of Conduct](https://www.python.org/psf/codeofconduct/).

At the same time, humor is encouraged. In fact, basic familiarity with Monty Python's
Flying Circus is expected. We are not savages.

And if you _really_ need to slap somebody, do it with a fish while dancing.

---

## File: docs/contributing/gauging_changes.md

# Gauging changes

A lot of the time, your change will affect formatting and/or performance. Quantifying
these changes is hard, so we have tooling to help make it easier.

It's recommended you evaluate the quantifiable changes your _Black_ formatting
modification causes before submitting a PR. Think about if the change seems disruptive
enough to cause frustration to projects that are already "Black-formatted".

## diff-shades

diff-shades is a tool that runs _Black_ across a list of open-source projects recording
the results. The main highlight feature of diff-shades is being able to compare two
revisions of _Black_. This is incredibly useful as it allows us to see what exact
changes will occur, say merging a certain PR.

For more information, please see the [diff-shades documentation][diff-shades].

### CI integration

diff-shades is also the tool behind the "diff-shades results comparing ..." comments on
PRs. The project has a GitHub Actions workflow that analyzes and compares two revisions
of _Black_ according to these rules:

|                       | Baseline revision               | Target revision              |
| --------------------- | ------------------------------- | ---------------------------- |
| On PRs                | latest commit on PR base branch | PR commit with `main` merged |
| On pushes (main only) | latest PyPI version             | the pushed commit            |

For pushes to main, there's only one analysis job named `preview-new-changes` where the
preview style is used for all projects.

For PRs they get one more analysis job: `assert-no-changes`. It's similar to
`preview-new-changes` but runs with the stable code style. It will fail if changes were
made. This makes sure code won't be reformatted again and again within the same year in
accordance to Black's stability policy.

Additionally for PRs, a PR comment will be posted embedding a summary previewing any
changes in both styles and links to further information. The next time the workflow is
triggered on the same PR, it'll update the pre-existing diff-shades comment.

```{note}
Jobs will only fail intentionally if a file failed to format while analyzing, or if
changes were made to the stable style. Otherwise a failure indicates a bug in the
workflow.
```

The workflow uploads several artifacts upon completion:

- HTML diffs (.html)
  - handy for pushes where there's no PR to post a comment
- The raw analyses (.json)
  - in case you want to do further analysis using the collected data locally
- `.preview.pr-comment.md` and `.stable.pr-comment.md` (if triggered by a PR)
  - used to generate the PR comment and shouldn't be downloaded

[diff-shades]: https://github.com/ichard26/diff-shades#readme

---

## File: docs/contributing/index.md

# Contributing

```{toctree}
---
hidden:
---

the_basics
gauging_changes
issue_triage
release_process
```

Welcome! Happy to see you willing to make the project better. Have you read the entire
[user documentation](https://black.readthedocs.io/en/latest/) yet?

```{rubric} Bird's eye view

```

In terms of inspiration, _Black_ is about as configurable as _gofmt_ (which is to say,
not very). This is deliberate. _Black_ aims to provide a consistent style and take away
opportunities for arguing about style.

Bug reports and fixes are always welcome! Please follow the
[issue templates on GitHub](https://github.com/psf/black/issues/new/choose) for best
results.

Before you suggest a new feature or configuration knob, ask yourself why you want it. If
it enables better integration with some workflow, fixes an inconsistency, speeds things
up, and so on - go for it! On the other hand, if your answer is "because I don't like a
particular formatting" then you're not ready to embrace _Black_ yet. Such changes are
unlikely to get accepted. You can still try but prepare to be disappointed.

```{rubric} Contents

```

This section covers the following topics:

- {doc}`the_basics`
- {doc}`gauging_changes`
- {doc}`release_process`

For an overview on contributing to the _Black_, please checkout {doc}`the_basics`.

---

## File: docs/contributing/issue_triage.md

# Issue triage

Currently, _Black_ uses the issue tracker for bugs, feature requests, proposed style
modifications, and general user support. Each of these issues have to be triaged so they
can be eventually be resolved somehow. This document outlines the triaging process and
also the current guidelines and recommendations.

```{tip}
If you're looking for a way to contribute without submitting patches, this might be the
area for you. Since _Black_ is a popular project, its issue tracker is quite busy and
always needs more attention than is available. While triage isn't the most glamorous or
technically challenging form of contribution, it's still important. For example, we
would love to know whether that old bug report is still reproducible!

You can get easily started by reading over this document and then responding to issues.

If you contribute enough and have stayed for long enough, you may even be given
Triage permissions!
```

## The basics

_Black_ gets a whole bunch of different issues, they range from bug reports to user
support issues. To triage is to identify, organize, and kickstart the issue's journey
through its lifecycle to resolution.

More specifically, to triage an issue means to:

- identify what type and categories the issue falls under
- confirm bugs
- ask questions / for further information if necessary
- link related issues
- provide the first initial feedback / support

Note that triage is typically the first response to an issue, so don't fret if the issue
doesn't make much progress after initial triage. The main goal of triaging to prepare
the issue for future more specific development or discussion, so _eventually_ it will be
resolved.

The lifecycle of a bug report or user support issue typically goes something like this:

1. _the issue is waiting for triage_
2. **identified** - has been marked with a type label and other relevant labels, more
   details or a functional reproduction may be still needed (and therefore should be
   marked with `S: needs repro` or `S: awaiting response`)
3. **confirmed** - the issue can reproduced and necessary details have been provided
4. **discussion** - initial triage has been done and now the general details on how the
   issue should be best resolved are being hashed out
5. **awaiting fix** - no further discussion on the issue is necessary and a resolving PR
   is the next step
6. **closed** - the issue has been resolved, reasons include:
   - the issue couldn't be reproduced
   - the issue has been fixed
   - duplicate of another pre-existing issue or is invalid

For enhancement, documentation, and style issues, the lifecycle looks very similar but
the details are different:

1. _the issue is waiting for triage_
2. **identified** - has been marked with a type label and other relevant labels
3. **discussion** - the merits of the suggested changes are currently being discussed, a
   PR would be acceptable but would be at significant risk of being rejected
4. **accepted & awaiting PR** - it's been determined the suggested changes are OK and a
   PR would be welcomed (`S: accepted`)
5. **closed**: - the issue has been resolved, reasons include:
   - the suggested changes were implemented
   - it was rejected (due to technical concerns, ethos conflicts, etc.)
   - duplicate of a pre-existing issue or is invalid

**Note**: documentation issues don't use the `S: accepted` label currently since they're
less likely to be rejected.

## Labelling

We use labels to organize, track progress, and help effectively divvy up work.

Our labels are divided up into several groups identified by their prefix:

- **T - Type**: the general flavor of issue / PR
- **C - Category**: areas of concerns, ranges from bug types to project maintenance
- **F - Formatting Area**: like C but for formatting specifically
- **S - Status**: what stage of resolution is this issue currently in?
- **R - Resolution**: how / why was the issue / PR resolved?

We also have a few standalone labels:

- **`good first issue`**: issues that are beginner-friendly (and will show up in GitHub
  banners for first-time visitors to the repository)
- **`help wanted`**: complex issues that need and are looking for a fair bit of work as
  to progress (will also show up in various GitHub pages)
- **`ci: skip news`**: for PRs that are trivial and don't need a CHANGELOG entry (and
  skips the CHANGELOG entry check)
- **`ci: build all wheels`**: when a full wheel build is needed, such as to debug
  platform-specific issues. Black does not build wheels for every platform on each pull
  request because the full build matrix is expensive. After the label is added, the
  workflow starts only when a new commit is pushed.

```{note}
We do use labels for PRs, in particular the `ci: skip news` label, but we aren't that
rigorous about it. Just follow your judgement on what labels make sense for the specific
PR (if any even make sense).
```

## Projects

For more general and broad goals we use projects to track work. Some may be long-term
projects with no true end (e.g. the "Amazing documentation" project) while others may be
more focused and have a definite end (like the "Getting to beta" project).

```{note}
To modify GitHub Projects you need the
[Write repository permission level or higher](https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-permission-levels-for-an-organization#repository-access-for-each-permission-level).
```

## Closing issues

Closing an issue signifies the issue has reached the end of its life, so closing issues
should be taken with care. The following is the general recommendation for each type of
issue. Note that these are only guidelines and if your judgement says something else
it's totally cool to go with it instead.

For most issues, closing the issue manually or automatically after a resolving PR is
ideal. For bug reports specifically, if the bug has already been fixed, try to check in
with the issue opener that their specific case has been resolved before closing. Note
that we close issues as soon as they're fixed in the `main` branch. This doesn't
necessarily mean they've been released yet.

Design and enhancement issues should be also closed when it's clear the proposed change
won't be implemented, whether that has been determined after a lot of discussion or just
simply goes against _Black_'s ethos. If such an issue turns heated, closing and locking
is acceptable if it's severe enough (although checking in with the core team is probably
a good idea).

User support issues are best closed by the author or when it's clear the issue has been
resolved in some sort of manner.

Duplicates and invalid issues should always be closed since they serve no purpose and
add noise to an already busy issue tracker. Although be careful to make sure it's truly
a duplicate and not just very similar before labelling and closing an issue as
duplicate.

## Common reports

Some issues are frequently opened, like issues about _Black_ formatted code causing E203
messages. Even though these issues are probably heavily duplicated, they still require
triage sucking up valuable time from other things (although they usually skip most of
their lifecycle since they're closed on triage).

Here's some of the most common issues and also pre-made responses you can use:

### "The trailing comma isn't being removed by Black!"

```text
Black used to remove the trailing comma if the expression fits in a single line, but this was changed by #826 and #1288. Now a trailing comma tells Black to always explode the expression. This change was made mostly for the cases where you _know_ a collection or whatever will grow in the future. Having it always exploded as one element per line reduces diff noise when adding elements. Before the "magic trailing comma" feature, you couldn't anticipate a collection's growth reliably since collections that fitted in one line were ruthlessly collapsed regardless of your intentions. One of Black's goals is reducing diff noise, so this was a good pragmatic change.

So no, this is not a bug, but an intended feature. Anyway, [here's the documentation](https://github.com/psf/black/blob/main/docs/the_black_code_style/current_style.md#the-magic-trailing-comma) on the "magic trailing comma", including the ability to skip this functionality with the `--skip-magic-trailing-comma` option. Hopefully that helps solve the possible confusion.
```

### "Black formatted code is violating Flake8's E203!"

```text
Hi,

This is expected behaviour, please see the documentation regarding this case (emphasis mine):

> PEP 8 recommends to treat : in slices as a binary operator with the lowest priority, and to leave an equal amount of space on either side, **except if a parameter is omitted (e.g. ham[1 + 1 :])**. It recommends no spaces around : operators for “simple expressions” (ham[lower:upper]), and **extra space for “complex expressions” (ham[lower : upper + offset])**. **Black treats anything more than variable names as “complex” (ham[lower : upper + 1]).** It also states that for extended slices, both : operators have to have the same amount of spacing, except if a parameter is omitted (ham[1 + 1 ::]). Black enforces these rules consistently.

> This behaviour may raise E203 whitespace before ':' warnings in style guide enforcement tools like Flake8. **Since E203 is not PEP 8 compliant, you should tell Flake8 to ignore these warnings**.

https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#slices

Have a good day!
```

---

## File: docs/contributing/release_process.md

# Release process

_Black_ has had a lot of work done into standardizing and automating its release
process. This document sets out to explain how everything works and how to release
_Black_ using said automation.

## Release cadence

**We aim to release whatever is on `main` every 1-2 months.** This ensures merged
improvements and bugfixes are shipped to users reasonably quickly, while not massively
fracturing the user-base with too many versions. This also keeps the workload on
maintainers consistent and predictable.

If there's not much new on `main` to justify a release, it's acceptable to skip a
month's release. Ideally January releases should not be skipped because as per our
[stability policy](labels/stability-policy), the first release in a new calendar year
may make changes to the _stable_ style. While the policy applies to the first release
(instead of only January releases), confining changes to the stable style to January
will keep things predictable (and nicer) for users.

Unless there is a serious regression or bug that requires immediate patching, **there
should not be more than one release per month**. While version numbers are cheap,
releases require a maintainer to both commit to do the actual cutting of a release, but
also to be able to deal with the potential fallout post-release. Releasing more
frequently than monthly nets rapidly diminishing returns.

## Cutting a release

**You must have `write` permissions for the _Black_ repository to cut a release.**

The 10,000 foot view of the release process is that you prepare a release PR and then
publish a [GitHub Release]. This triggers [release automation](#release-workflows) that
builds all release artifacts and publishes them to the various platforms we publish to.

We now have a `scripts/release.py` script to help with cutting the release PRs.

- `python3 scripts/release.py --help` is your friend.
  - `release.py` has only been tested in Python 3.12+ (so get with the times :D)

To cut a release:

1. Determine the release's version number
   - **_Black_ follows the [CalVer] versioning standard using the `YY.M.N` format**
     - So unless there already has been a release during this month, `N` should be `0`
   - Example: the first release in January, 2026 → `26.1.0`
   - `release.py` will calculate this and log it to stdout for your copy-paste pleasure
1. Double-check that no changelog entries since the last release were put in the wrong
   section (e.g., run `git diff origin/stable CHANGES.md`)
1. File a PR editing `CHANGES.md` and the docs to version the latest changes
   - Run `python3 scripts/release.py [--debug]` to generate most changes
1. If `release.py` fails manually edit; otherwise, yay, skip this step!
   1. Replace the `## Unreleased` header with the version number
   1. Remove any empty sections for the current release
   1. (_optional_) Read through and copy-edit the changelog (eg. by moving entries,
      fixing typos, or rephrasing entries)
1. Update references to the latest version in
   {doc}`/integrations/source_version_control` and
   {doc}`/usage_and_configuration/the_basics`
   - Example PR: [GH-4563]
1. Once the release PR is merged, wait until all CI passes
   - If CI does not pass, **stop** and investigate the failure(s) as generally we'd want
     to fix failing CI before cutting a release
1. [Draft a new GitHub Release][new-release]
   1. Click `Choose a tag` and type in the version number, then select the
      `Create new tag: YY.M.N on publish` option that appears
   1. Verify that the new tag targets the `main` branch
   1. Make sure the release title is set to the version (`YY.M.N`), as otherwise the
      default title is the last commit's title
   1. Copy and paste the _raw changelog Markdown_ for the current release into the
      description box
1. Publish the GitHub Release, triggering [release automation](#release-workflows) that
   will handle the rest
1. Once CI is done add + PR a new empty template for the next release to CHANGES.md
   _(Template is able to be copy pasted from release.py should we fail)_
   1. `python3 scripts/release.py --add-changes-template|-a [--debug]`
   1. Should that fail, please return to copy + paste
1. At this point, you're basically done. It's good practice to go and [watch and verify
   that all the release workflows pass][black-actions], although you will receive a
   GitHub notification should something fail.
   - If something fails, don't panic. Please go read the respective workflow's logs and
     configuration file to reverse-engineer your way to a fix/solution.

Congratulations! You've successfully cut a new release of _Black_. Go and stand up and
take a break, you deserve it.

```{important}
Once the release artifacts reach PyPI, you may see new issues being filed indicating
regressions. While regressions are not great, they don't automatically mean a hotfix
release is warranted. Unless the regressions are serious and impact many users, a hotfix
release is probably unnecessary.

In the end, use your best judgement and ask other maintainers for their thoughts.
```

## Release workflows

All of _Black_'s release automation uses [GitHub Actions]. All workflows are therefore
configured using YAML files in the `.github/workflows` directory of the _Black_
repository.

They are triggered by the publication of a [GitHub Release].

Below are descriptions of our release workflows.

### build and publish

This is our main workflow. It builds an [sdist] and [wheels] to upload to PyPI where the
vast majority of users will download Black from. It's divided into three job groups:

#### sdist + pure wheel

This single job builds the sdist and pure Python wheel (i.e., a wheel that only contains
Python code) using [Hatch]. These artifacts are general-purpose and can be used on
basically any platform supported by Python.

#### generate wheels matrix / mypyc wheels (…)

We use [mypyc] to compile _Black_ into a CPython C extension for significantly improved
performance. Wheels built with mypyc are platform and Python version specific.
[Supported platforms are documented in the FAQ](labels/mypyc-support).

These matrix jobs use [cibuildwheel] which handles the complicated task of building C
extensions for many environments for us. Since building these wheels is slow, there are
multiple mypyc wheels jobs (hence the term "matrix") that build for a specific platform
(as noted in the job name in parentheses).

#### publish-hatch / publish-mypyc

These jobs upload the built sdist and all wheels to PyPI using [Trusted
publishing][trusted-publishing].

### publish binaries

This workflow builds native executables for multiple platforms using [PyInstaller]. This
allows people to download the executable for their platform and run _Black_ without a
[Python runtime](https://wiki.python.org/moin/PythonImplementations) installed.

The created binaries are stored on the associated GitHub Release for download over _IPv4
only_ (GitHub still does not have IPv6 access 😢).

### docker

This workflow uses the QEMU powered `buildx` feature of Docker to upload an `arm64` and
`amd64`/`x86_64` build of the official _Black_ Docker image™.

- _Currently this workflow uses an API Token associated with @cooperlees account_

```{note}
This also runs on each push to `main`.
```

### post release

This workflow runs a few miscellaneous jobs related to repository maintenance.

#### update-stable

Updates the `stable` branch by force pushing it to the most recent tag. This saves us
from remembering to update the branch sometime after cutting the release.

#### new-changelog

Opens a new PR to add the "Unreleased" section back to the changelog. The PR is
intentionally not auto-merged, in case there's an issue and the release needs to be
re-cut.

[black-actions]: https://github.com/psf/black/actions
[calver]: https://calver.org
[cibuildwheel]: https://cibuildwheel.readthedocs.io/
[gh-4563]: https://github.com/psf/black/pull/4563
[github actions]: https://github.com/features/actions
[github release]: https://github.com/psf/black/releases
[hatch]: https://hatch.pypa.io/latest/
[mypyc]: https://mypyc.readthedocs.io/
[new-release]: https://github.com/psf/black/releases/new
[pyinstaller]: https://www.pyinstaller.org/
[sdist]:
  https://packaging.python.org/en/latest/glossary/#term-source-distribution-or-sdist
[trusted-publishing]: https://docs.pypi.org/trusted-publishers/
[wheels]: https://packaging.python.org/en/latest/glossary/#term-wheel

---

## File: docs/contributing/the_basics.md

# The basics

An overview on contributing to the _Black_ project.

## Technicalities

Development on the latest version of Python is preferred. You can use any operating
system.

First clone the _Black_ repository:

```console
$ git clone https://github.com/psf/black.git
$ cd black
```

Then install development dependencies inside a virtual environment of your choice, for
example:

```console
$ python3 -m venv .venv
$ source .venv/bin/activate # activation for linux and mac
$ .venv\Scripts\activate # activation for windows

(.venv)$ pip install --group dev
(.venv)$ pip install -e ".[d]"
(.venv)$ pre-commit install
```

Before submitting pull requests, run lints and tests with the following commands from
the root of the black repo:

```console
(.venv)$ pre-commit run -a # Linting
(.venv)$ tox -e py # Unit tests
(.venv)$ tox -e fuzz # Optional Fuzz testing
(.venv)$ tox -e run_self # Format Black itself
```

### Development

Further examples of invoking the tests

```console
(.venv)$ tox --parallel=auto # Run all the above in parallel
(.venv)$ tox -e py314 # Run tests on a specific python version
(.venv)$ pytest -k <test name> # Run an individual test
(.venv)$ tox -e py -- --no-cov # Pass arguments to pytest
```

### Testing

All aspects of the _Black_ style should be tested. Normally, tests should be created as
files in the `tests/data/cases` directory. These files consist of up to three parts:

- A line that starts with `# flags: ` followed by a set of command-line options. For
  example, if the line is `# flags: --preview --skip-magic-trailing-comma`, the test
  case will be run with preview mode on and the magic trailing comma off. The options
  accepted are mostly a subset of those of _Black_ itself, except for the
  `--minimum-version=` flag, which should be used when testing a grammar feature that
  works only in newer versions of Python. This flag ensures that we don't try to
  validate the AST on older versions and tests that we autodetect the Python version
  correctly when the feature is used. For the exact flags accepted, see the function
  `get_flags_parser` in `tests/util.py`. If this line is omitted, the default options
  are used.
- A block of Python code used as input for the formatter.
- The line `# output`, followed by the output of _Black_ when run on the previous block.
  If this is omitted, the test asserts that _Black_ will leave the input code unchanged.

_Black_ has two pytest command-line options affecting test files in `tests/data/` that
are split into an input part, and an output part, separated by a line with `# output`.
These can be passed to `pytest` through `tox`, or directly into pytest if not using
`tox`.

#### `--print-full-tree`

Upon a failing test, print the full concrete syntax tree (CST) as it is after processing
the input ("actual"), and the tree that's yielded after parsing the output ("expected").
Note that a test can fail with different output with the same CST. This used to be the
default, but now defaults to `False`.

```console
(.venv)$ tox -e py -- --print-full-tree
```

#### `--print-tree-diff`

Upon a failing test, print the diff of the trees as described above. This is the
default. To turn it off pass `--print-tree-diff=False`.

```console
(.venv)$ tox -e py -- --print-tree-diff=False
```

### News / Changelog Requirement

`Black` has CI that will check for an entry corresponding to your PR in `CHANGES.md`. If
you feel this PR does not require a changelog entry please state that in a comment and a
maintainer can add a `ci: skip news` label to make the CI pass. Otherwise, please ensure
you have a line in the following format added below the appropriate header:

```md
- `Black` is now more awesome (#X)
```

Note that X should be your PR number, not issue number! To workout X, please use
[Next PR Number](https://ichard26.github.io/next-pr-number/?owner=psf&name=black). This
is not perfect but saves a lot of release overhead as now the releaser does not need to
go back and workout what to add to the `CHANGES.md` for each release.

### Style Changes

Please familiarize yourself with our [stability policy](labels/stability-policy).
Therefore, most style changes must be added to the `--preview` style. Exceptions are
fixing crashes or changes that would not affect an already-formatted file.

If a change would affect the advertised code style, please modify the documentation (The
_Black_ code style) to reflect that change. Patches that fix unintended bugs in
formatting don't need to be mentioned separately.

If the change is implemented with the `--preview` flag, please include the change in the
Future Style document instead and write the changelog entry under the dedicated "Preview
style" heading.

### Docs Testing

If you make changes to docs, you can test they still build locally too.

```console
(.venv)$ pip install --group docs
(.venv)$ pip install -e ".[d]"
(.venv)$ sphinx-build -a -b html -W docs/ docs/_build/
```

## Hygiene

If you're fixing a bug, add a test. Run it first to confirm it fails, then fix the bug,
and run the test again to confirm it's really fixed.

If adding a new feature, add a test. In fact, always add a test. If adding a large
feature, please first open an issue to discuss it beforehand.

## Finally

Thanks again for your interest in improving the project! You're taking action when most
people decide to sit and watch.

---

## File: docs/guides/index.md

# Guides

```{toctree}
---
hidden:
---

introducing_black_to_your_project
using_black_with_other_tools
using_black_with_jupyter_notebooks
```

Wondering how to do something specific? You've found the right place! Listed below are
topic specific guides available:

- {doc}`introducing_black_to_your_project`
- {doc}`using_black_with_other_tools`
- {doc}`using_black_with_jupyter_notebooks`

---

## File: docs/guides/introducing_black_to_your_project.md

# Introducing _Black_ to your project

```{note}
This guide is incomplete. Contributions are welcomed and would be deeply appreciated!
```

## Avoiding ruining git blame

A long-standing argument against moving to automated code formatters like _Black_ is
that the migration will clutter up the output of `git blame`. This was a valid argument,
but since Git version 2.23, Git natively supports
[ignoring revisions in blame](https://git-scm.com/docs/git-blame#Documentation/git-blame.txt---ignore-revltrevgt)
with the `--ignore-rev` option. You can also pass a file listing the revisions to ignore
using the `--ignore-revs-file` option. The changes made by the revision will be ignored
when assigning blame. Lines modified by an ignored revision will be blamed on the
previous revision that modified those lines.

So when migrating your project's code style to _Black_, reformat everything and commit
the changes (preferably in one massive commit). Then put the full 40 characters commit
identifier(s) into a file usually called `.git-blame-ignore-revs` at the root of your
project directory.

```text
# Migrate code style to Black
5b4ab991dede475d393e9d69ec388fd6bd949699
```

Afterwards, you can pass that file to `git blame` and see clean and meaningful blame
information.

```console
$ git blame important.py --ignore-revs-file .git-blame-ignore-revs
7a1ae265 (John Smith 2019-04-15 15:55:13 -0400 1) def very_important_function(text, file):
abdfd8b0 (Alice Doe  2019-09-23 11:39:32 -0400 2)     text = text.lstrip()
7a1ae265 (John Smith 2019-04-15 15:55:13 -0400 3)     with open(file, "r+") as f:
7a1ae265 (John Smith 2019-04-15 15:55:13 -0400 4)         f.write(formatted)
```

You can even configure `git` to automatically ignore revisions listed in a file on every
call to `git blame`.

```console
$ git config blame.ignoreRevsFile .git-blame-ignore-revs
```

**The one caveat is that some online Git-repositories do not yet support ignoring
revisions using their native blame UI.** So blame information will be cluttered with a
reformatting commit on those platforms. However,
[GitHub](https://docs.github.com/en/repositories/working-with-files/using-files/viewing-a-file#ignore-commits-in-the-blame-view)
and
[GitLab (since version 17.10)](https://about.gitlab.com/releases/2025/03/20/gitlab-17-10-released/#ignore-specific-revisions-in-git-blame)
both support `.git-blame-ignore-revs` in blame views by default.

---

## File: docs/guides/using_black_with_other_tools.md

# Using _Black_ with other tools

## Black compatible configurations

All of Black's changes are harmless (or at least, they should be), but a few do conflict
against other tools. It is not uncommon to be using other tools alongside _Black_ like
linters and type checkers. Some of them need a bit of tweaking to resolve the conflicts.
Listed below are _Black_ compatible configurations in various formats for the common
tools out there.

**Please note** that _Black_ only supports the TOML file format for its configuration
(e.g. `pyproject.toml`). The provided examples are to only configure their corresponding
tools, using **their** supported file formats.

Compatible configuration files can be
[found here](https://github.com/psf/black/blob/main/docs/compatible_configs/).

### isort

[isort](https://isort.readthedocs.io/) helps to sort and format imports in your Python
code. _Black_ also formats imports, but in a different way from isort's defaults which
leads to conflicting changes.

#### Profile

Since version 5.0.0, isort supports
[profiles](https://isort.readthedocs.io/en/latest/configuration/profiles.html) to allow
easy interoperability with common code styles. You can set the black profile in any of
the
[config files](https://isort.readthedocs.io/en/latest/configuration/config_files.html)
supported by isort. Below, an example for `pyproject.toml`:

```toml
[tool.isort]
profile = "black"
```

#### Custom Configuration

If you're using an isort version that is older than 5.0.0 or you have some custom
configuration for _Black_, you can tweak your isort configuration to make it compatible
with _Black_. Below, an example for `.isort.cfg`:

```ini
multi_line_output = 3
include_trailing_comma = True
force_grid_wrap = 0
use_parentheses = True
ensure_newline_before_comments = True
line_length = 88
```

#### Why those options above?

_Black_ wraps imports that surpass `line-length` by moving identifiers onto separate
lines and by adding a trailing comma after each. A more detailed explanation of this
behaviour can be
[found here](../the_black_code_style/current_style.md#how-black-wraps-lines).

isort's default mode of wrapping imports that extend past the `line_length` limit is
"Grid".

```python
from third_party import (lib1, lib2, lib3,
                         lib4, lib5, ...)
```

This style is incompatible with _Black_, but isort can be configured to use a different
wrapping mode called "Vertical Hanging Indent" which looks like this:

```python
from third_party import (
    lib1,
    lib2,
    lib3,
    lib4,
)
```

This style is _Black_ compatible and can be achieved by `multi-line-output = 3`. Also,
as mentioned above, when wrapping long imports _Black_ puts a trailing comma and uses
parentheses. isort should follow the same behaviour and passing the options
`include_trailing_comma = True` and `use_parentheses = True` configures that.

The option `force_grid_wrap = 0` is just to tell isort to only wrap imports that surpass
the `line_length` limit.

Finally, isort should be told to wrap imports when they surpass _Black_'s default limit
of 88 characters via `line_length = 88` as well as
`ensure_newline_before_comments = True` to ensure spacing import sections with comments
works the same as with _Black_.

**Please note** `ensure_newline_before_comments = True` only works since isort >= 5 but
does not break older versions so you can keep it if you are running previous versions.

#### Formats


.isort.cfg

```ini
[settings]
profile = black
```




setup.cfg

```ini
[isort]
profile = black
```




pyproject.toml

```toml
[tool.isort]
profile = 'black'
```




.editorconfig

```ini
[*.py]
profile = black
```



### pycodestyle

[pycodestyle](https://pycodestyle.pycqa.org/en/stable/) is a code linter. It warns you
of syntax errors, possible bugs, stylistic errors, etc. For the most part, pycodestyle
follows [PEP 8](https://peps.python.org/pep-0008/) when warning about stylistic errors.
There are a few deviations that cause incompatibilities with _Black_.

#### Configuration

```ini
max-line-length = 88
ignore = E203,E701
```

(labels/why-pycodestyle-warnings)=

#### Why those options above?

##### `max-line-length`

As with isort, pycodestyle should be configured to allow lines up to the length limit of
`88`, _Black_'s default.

##### `E203`

In some cases, as determined by PEP 8, _Black_ will enforce an equal amount of
whitespace around slice operators. Due to this, pycodestyle will raise
`E203 whitespace before ':'` warnings. Since this warning is not PEP 8 compliant, it
should be disabled.

##### `E701` / `E704`

_Black_ will collapse implementations of classes and functions consisting solely of `..`
to a single line. This matches how such examples are formatted in PEP 8. It remains true
that in all other cases Black will prevent multiple statements on the same line, in
accordance with PEP 8 generally discouraging this.

However, `pycodestyle` does not mirror this logic and may raise
`E701 multiple statements on one line (colon)` in this situation. Its
disabled-by-default `E704 multiple statements on one line (def)` rule may also raise
warnings and should not be enabled.

##### `W503`

When breaking a line, _Black_ will break it before a binary operator. This is compliant
with PEP 8 as of
[April 2016](https://github.com/python/peps/commit/c59c4376ad233a62ca4b3a6060c81368bd21e85b#diff-64ec08cc46db7540f18f2af46037f599).
There's a disabled-by-default warning in Flake8 which goes against this PEP 8
recommendation called `W503 line break before binary operator`. It should not be enabled
in your configuration. You can use its counterpart
`W504 line break after binary operator` instead.

#### Formats


setup.cfg, .pycodestyle, tox.ini

```ini
[pycodestyle]
max-line-length = 88
ignore = E203,E701
```



### Flake8

[Flake8](https://flake8.pycqa.org/en/stable/) is a wrapper around multiple linters,
including pycodestyle. As such, it has many of the same issues.

#### Bugbear

It's recommended to use [the Bugbear plugin](https://github.com/PyCQA/flake8-bugbear)
and enable
[its B950 check](https://github.com/PyCQA/flake8-bugbear#opinionated-warnings#:~:text=you%20expect%20it.-,B950,-%3A%20Line%20too%20long)
instead of using Flake8's E501, because it aligns with
[Black's 10% rule](labels/line-length).

Install Bugbear and use the following config:

```ini
[flake8]
max-line-length = 80
extend-select = B950
extend-ignore = E203,E501,E701
```

#### Minimal Configuration

In cases where you can't or don't want to install Bugbear, you can use this minimally
compatible config:

```ini
[flake8]
max-line-length = 88
extend-ignore = E203,E701
```

#### Why those options above?

See [the pycodestyle section](labels/why-pycodestyle-warnings) above.

#### Formats


.flake8, setup.cfg, tox.ini

```ini
[flake8]
max-line-length = 88
extend-ignore = E203,E701
```



### Pylint

[Pylint](https://pylint.readthedocs.io/) is also a code linter like Flake8. It has many
of the same checks as Flake8 and more. It particularly has more formatting checks
regarding style conventions like variable naming.

#### Configuration

```ini
max-line-length = 88
```

#### Why those options above?

Pylint should be configured to only complain about lines that surpass `88` characters
via `max-line-length = 88`.

If using `pylint<2.6.0`, also disable `C0326` and `C0330` as these are incompatible with
_Black_ formatting and have since been removed.

#### Formats


pylintrc

```ini
[format]
max-line-length = 88
```




setup.cfg

```ini
[pylint]
max-line-length = 88
```




pyproject.toml

```toml
[tool.pylint.format]
max-line-length = "88"
```

---

## File: docs/integrations/editors.md

# Editor integration

## Emacs

Options include the following:

- [emacs-python-black](https://github.com/wbolster/emacs-python-black)
- [Blacken](https://github.com/pythonic-emacs/blacken)
- [Elpy](https://elpy.readthedocs.io/en/stable/).

## PyCharm/IntelliJ IDEA

There are several different ways you can use _Black_ from PyCharm:

1. Using the built-in _Black_ integration (PyCharm 2023.2 and later). This option is the
   simplest to set up.
1. As local server using the BlackConnect plugin. This option formats the fastest. It
   spins up {doc}`Black's HTTP server `, to
   avoid the startup cost on subsequent formats.
1. As external tool.
1. As file watcher.

### Built-in _Black_ integration

1. Install `black`.

   ```console
   $ pip install black
   ```

1. Go to `Preferences or Settings -> Tools -> Black` and configure _Black_ to your
   liking.

### As local server

1. Install _Black_ with the `d` extra.

   ```console
   $ pip install 'black[d]'
   ```

1. Install
   [BlackConnect IntelliJ IDEs plugin](https://plugins.jetbrains.com/plugin/14321-blackconnect).

1. Open plugin configuration in PyCharm/IntelliJ IDEA

   On macOS:

   `PyCharm -> Preferences -> Tools -> BlackConnect`

   On Windows / Linux / BSD:

   `File -> Settings -> Tools -> BlackConnect`

1. In `Local Instance (shared between projects)` section:
   1. Check `Start local blackd instance when plugin loads`.
   1. Press the `Detect` button near `Path` input. The plugin should detect the `blackd`
      executable.

1. In `Trigger Settings` section check `Trigger on code reformat` to enable code
   reformatting with _Black_.

1. Format the currently opened file by selecting `Code -> Reformat Code` or using a
   shortcut.

1. Optionally, to run _Black_ on every file save:
   - In `Trigger Settings` section of plugin configuration check
     `Trigger when saving changed files`.

### As external tool

1. Install `black`.

   ```console
   $ pip install black
   ```

1. Locate your `black` installation folder.

   On macOS / Linux / BSD:

   ```console
   $ which black
   /usr/local/bin/black  # possible location
   ```

   On Windows:

   ```console
   $ where black
   C:\Program Files\Python313\Scripts\black.exe  # possible location
   ```

   Note that if you are using a virtual environment detected by PyCharm, this is an
   unneeded step. In this case the path to `black` is `$PyInterpreterDirectory$/black`.

1. Open External tools in PyCharm/IntelliJ IDEA

   On macOS:

   `PyCharm -> Preferences -> Tools -> External Tools`

   On Windows / Linux / BSD:

   `File -> Settings -> Tools -> External Tools`

1. Click the + icon to add a new external tool with the following values:
   - Name: Black
   - Description: Black is the uncompromising Python code formatter.
   - Program: \
   - Arguments: `"$FilePath$"`

1. Format the currently opened file by selecting `Tools -> External Tools -> black`.
   - Alternatively, you can set a keyboard shortcut by navigating to
     `Preferences or Settings -> Keymap -> External Tools -> External Tools - Black`.

### As file watcher

1. Install `black`.

   ```console
   $ pip install black
   ```

1. Locate your `black` installation folder.

   On macOS / Linux / BSD:

   ```console
   $ which black
   /usr/local/bin/black  # possible location
   ```

   On Windows:

   ```console
   $ where black
   C:\Program Files\Python313\Scripts\black.exe  # possible location
   ```

   Note that if you are using a virtual environment detected by PyCharm, this is an
   unneeded step. In this case the path to `black` is `$PyInterpreterDirectory$/black`.

1. Make sure you have the
   [File Watchers](https://plugins.jetbrains.com/plugin/7177-file-watchers) plugin
   installed.
1. Go to `Preferences or Settings -> Tools -> File Watchers` and click `+` to add a new
   watcher:
   - Name: Black
   - File type: Python
   - Scope: Project Files
   - Program: \
   - Arguments: `$FilePath$`
   - Output paths to refresh: `$FilePath$`
   - Working directory: `$ProjectFileDir$`

- In Advanced Options
  - Uncheck "Auto-save edited files to trigger the watcher"
  - Uncheck "Trigger the watcher on external changes"

## Wing IDE

Wing IDE supports `black` via **Preference Settings** for system wide settings and
**Project Properties** for per-project or workspace specific settings, as explained in
the Wing documentation on
[Auto-Reformatting](https://wingware.com/doc/edit/auto-reformatting). The detailed
procedure is:

### Prerequisites

- Wing IDE version 8.0+

- Install `black`.

  ```console
  $ pip install black
  ```

- Make sure it runs from the command line, e.g.

  ```console
  $ black --help
  ```

### Preference Settings

If you want Wing IDE to always reformat with `black` for every project, follow these
steps:

1. In menubar navigate to `Edit -> Preferences -> Editor -> Reformatting`.

1. Set **Auto-Reformat** from `disable` (default) to `Line after edit` or
   `Whole files before save`.

1. Set **Reformatter** from `PEP8` (default) to `Black`.

### Project Properties

If you want to just reformat for a specific project and not intervene with Wing IDE
global setting, follow these steps:

1. In menubar navigate to `Project -> Project Properties -> Options`.

1. Set **Auto-Reformat** from `Use Preferences setting` (default) to `Line after edit`
   or `Whole files before save`.

1. Set **Reformatter** from `Use Preferences setting` (default) to `Black`.

## Vim

### Official plugin

Commands and shortcuts:

- `:Black` to format the entire file (ranges not supported);
  - you can optionally pass `target_version=<version>` with the same values as in the
    command line.
- `:BlackUpgrade` to upgrade _Black_ inside the virtualenv;
- `:BlackVersion` to get the current version of _Black_ in use.

Configuration:

- `g:black_fast` (defaults to `0`)
- `g:black_linelength` (defaults to `88`)
- `g:black_skip_string_normalization` (defaults to `0`)
- `g:black_skip_magic_trailing_comma` (defaults to `0`)
- `g:black_virtualenv` (defaults to `~/.vim/black` or `~/.local/share/nvim/black`)
- `g:black_use_virtualenv` (defaults to `1`)
- `g:black_target_version` (defaults to `""`)
- `g:black_quiet` (defaults to `0`)
- `g:black_preview` (defaults to `0`)

#### Installation

This plugin **requires Vim 7.0+ built with Python 3.10+ support**. It needs Python 3.10
to be able to run _Black_ inside the Vim process which is much faster than calling an
external command.

##### `vim-plug`

To install with [vim-plug](https://junegunn.github.io/vim-plug/):

_Black_'s `stable` branch tracks official version updates, and can be used to simply
follow the most recent stable version.

```vim
Plug 'psf/black', { 'branch': 'stable' }
```

Another option which is a bit more explicit and offers more control is to use
`vim-plug`'s `tag` option with a shell wildcard. This will resolve to the latest tag
which matches the given pattern.

The following matches all stable versions (see the
[Release Process](../contributing/release_process.md) section for documentation of
version scheme used by Black):

```vim
Plug 'psf/black', { 'tag': '*.*.*' }
```

and the following demonstrates pinning to a specific year's stable style (2026 in this
case):

```vim
Plug 'psf/black', { 'tag': '26.*.*' }
```

##### Vundle

or with [Vundle](https://github.com/VundleVim/Vundle.vim):

```vim
Plugin 'psf/black'
```

and execute the following in a terminal:

```console
$ cd ~/.vim/bundle/black
$ git checkout origin/stable -b stable
```

##### Arch Linux

On Arch Linux, the plugin is shipped with the
[`python-black`](https://archlinux.org/packages/extra/any/python-black/) package, so you
can start using it in Vim after install with no additional setup.

##### Vim 8 Native Plugin Management

or you can copy the plugin files from
[plugin/black.vim](https://github.com/psf/black/blob/stable/plugin/black.vim) and
[autoload/black.vim](https://github.com/psf/black/blob/stable/autoload/black.vim).

```sh
mkdir -p ~/.vim/pack/python/start/black/plugin
mkdir -p ~/.vim/pack/python/start/black/autoload
curl https://raw.githubusercontent.com/psf/black/stable/plugin/black.vim -o ~/.vim/pack/python/start/black/plugin/black.vim
curl https://raw.githubusercontent.com/psf/black/stable/autoload/black.vim -o ~/.vim/pack/python/start/black/autoload/black.vim
```

Let me know if this requires any changes to work with Vim 8's builtin `packadd`, or
Pathogen, and so on.

#### Usage

On first run, the plugin creates its own virtualenv using the right Python version and
automatically installs _Black_. You can upgrade it later by calling `:BlackUpgrade` and
restarting Vim.

If you need to do anything special to make your virtualenv work and install _Black_ (for
example you want to run a version from main), create a virtualenv manually and point
`g:black_virtualenv` to it. The plugin will use it.

If you would prefer to use the system installation of _Black_ rather than a virtualenv,
then add this to your vimrc:

```vim
let g:black_use_virtualenv = 0
```

Note that the `:BlackUpgrade` command is only usable and useful with a virtualenv, so
when the virtualenv is not in use, `:BlackUpgrade` is disabled. If you need to upgrade
the system installation of _Black_, then use your system package manager or pip--
whatever tool you used to install _Black_ originally.

To run _Black_ on save, add the following lines to `.vimrc` or `init.vim`:

```vim
augroup black_on_save
  autocmd!
  autocmd BufWritePre *.py Black
augroup end
```

To run _Black_ on a key press (e.g. F9 below), add this:

```vim
nnoremap <F9> :Black<CR>
```

### With ALE

1. Install [`ale`](https://github.com/dense-analysis/ale)

1. Install `black`

1. Add this to your vimrc:

   ```vim
   let g:ale_fixers = {}
   let g:ale_fixers.python = ['black']
   ```

### Vim indentation plugin

For insert-mode indentation that follows the same hanging-bracket style as _Black_, you
can also use the
[`vim-python-pep8-indent`](https://github.com/Vimjas/vim-python-pep8-indent) plugin. It
provides Vim's `indentexpr`; _Black_ remains responsible for formatting the file. For
example, with vim-plug:

```vim
Plug 'Vimjas/vim-python-pep8-indent'
```

With Vundle, use:

```vim
Plugin 'Vimjas/vim-python-pep8-indent'
```

## Neovim

### Via conform.nvim

[conform.nvim](https://github.com/stevearc/conform.nvim) is a lightweight formatter
plugin for Neovim. It supports _Black_ out of the box as long as `black` is available in
your `PATH`.

1. Install `black` (e.g. `pip install black` or `pipx install black`)

1. Install `conform.nvim` using your plugin manager and add the following to your Neovim
   configuration:

   ```lua
   require("conform").setup({
     formatters_by_ft = {
       python = { "black" },
     },
   })
   ```

1. To format on save, add:

   ```lua
   require("conform").setup({
     formatters_by_ft = {
       python = { "black" },
     },
     format_on_save = {
       timeout_ms = 500,
       lsp_format = "fallback",
     },
   })
   ```

### With ALE

[ALE](https://github.com/dense-analysis/ale) supports both Vim and Neovim. See the
[Vim section](#with-ale) above for setup instructions — the same configuration works for
Neovim.

### Simple command

You can invoke _Black_ on the current file directly from Neovim without any plugins:

```vim
:!black %
```

To create a convenient `:Black` command, add this to your `init.lua`:

```lua
vim.api.nvim_create_user_command(
  "Black",
  function()
    vim.cmd("!black " .. vim.fn.expand("%"))
  end,
  { nargs = 0 }
)
```

## Gedit

gedit is the default text editor of the GNOME, Unix like Operating Systems. Open gedit
as

```console
$ gedit <file_name>
```

1. `Go to edit > preferences > plugins`
1. Search for `external tools` and activate it.
1. In `Tools menu -> Manage external tools`
1. Add a new tool using `+` button.
1. Copy the below content to the code window.

```sh
#!/bin/bash
Name=$GEDIT_CURRENT_DOCUMENT_NAME
black $Name
```

- Set a keyboard shortcut if you like, Ex. `ctrl-B`
- Save: `Nothing`
- Input: `Nothing`
- Output: `Display in bottom pane` if you like.
- Change the name of the tool if you like.

Use your keyboard shortcut or `Tools -> External Tools` to use your new tool. When you
close and reopen your File, _Black_ will be done with its job.

## Visual Studio Code

- Use the
  [Python extension](https://marketplace.visualstudio.com/items?itemName=ms-python.python)
  ([instructions](https://code.visualstudio.com/docs/python/formatting)).

- Alternatively the pre-release
  [Black Formatter](https://marketplace.visualstudio.com/items?itemName=ms-python.black-formatter)
  extension can be used which runs a [Language Server Protocol](https://langserver.org/)
  server for Black. Formatting is much more responsive using this extension, **but the
  minimum supported version of Black is 22.3.0**.

## SublimeText

Use [LSP](#python-lsp-server) with the
[python-lsp-black](https://github.com/python-lsp/python-lsp-black) plugin as documented
below. This is the recommended approach for all versions of Sublime Text.

```{note}
The [sublack plugin](https://github.com/jgirardet/sublack) that was previously
recommended here is no longer maintained (the repository has been archived).
```

## Python LSP Server

If your editor supports the [Language Server Protocol](https://langserver.org/) (Atom,
Sublime Text, Visual Studio Code and many more), you can use the
[Python LSP Server](https://github.com/python-lsp/python-lsp-server) with the
[python-lsp-black](https://github.com/python-lsp/python-lsp-black) plugin.

## Gradle (the build tool)

Use the [Spotless](https://plugins.gradle.org/plugin/com.diffplug.spotless) plugin.

## Kakoune

Add the following hook to your kakrc, then run _Black_ with `:format`.

```
hook global WinSetOption filetype=python %{
    set-option window formatcmd 'black -q  -'
}
```

## Thonny

Use [Thonny-black-formatter](https://github.com/ettore-galli/thonny-black-formatter).