Compare commits
No commits in common. "main" and "21.5b0" have entirely different histories.
8
.coveragerc
Normal file
8
.coveragerc
Normal file
@ -0,0 +1,8 @@
|
||||
[report]
|
||||
omit =
|
||||
src/blib2to3/*
|
||||
tests/data/*
|
||||
*/site-packages/*
|
||||
|
||||
[run]
|
||||
relative_files = True
|
9
.flake8
9
.flake8
@ -1,8 +1,11 @@
|
||||
[flake8]
|
||||
# B905 should be enabled when we drop support for 3.9
|
||||
ignore = E203, E266, E501, E701, E704, W503, B905, B907
|
||||
extend-ignore = E203, E266, E501
|
||||
# line length is intentionally set to 80 here because black uses Bugbear
|
||||
# See https://black.readthedocs.io/en/stable/guides/using_black_with_other_tools.html#bugbear for more details
|
||||
# See https://github.com/psf/black/blob/master/docs/the_black_code_style.md#line-length for more details
|
||||
max-line-length = 80
|
||||
max-complexity = 18
|
||||
select = B,C,E,F,W,T4,B9
|
||||
# We need to configure the mypy.ini because the flake8-mypy's default
|
||||
# options don't properly override it, so if we don't specify it we get
|
||||
# half of the config from mypy.ini and half from flake8-mypy.
|
||||
mypy_config = mypy.ini
|
||||
|
@ -1,3 +0,0 @@
|
||||
node: $Format:%H$
|
||||
node-date: $Format:%cI$
|
||||
describe-name: $Format:%(describe:tags=true,match=[0-9]*)$
|
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -1,2 +0,0 @@
|
||||
.git_archival.txt export-subst
|
||||
*.py diff=python
|
78
.github/ISSUE_TEMPLATE/bug_report.md
vendored
78
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -1,66 +1,36 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve Black's quality
|
||||
about: Create a report to help us improve
|
||||
title: ""
|
||||
labels: "T: bug"
|
||||
labels: bug
|
||||
assignees: ""
|
||||
---
|
||||
|
||||
<!--
|
||||
Please make sure that the bug is not already fixed either in newer versions or the
|
||||
current development version. To confirm this, you have three options:
|
||||
**Describe the bug** A clear and concise description of what the bug is.
|
||||
|
||||
1. Update Black's version if a newer release exists: `pip install -U black`
|
||||
2. Use the online formatter at <https://black.vercel.app/?version=main>, which will use
|
||||
the latest main branch. Note that the online formatter currently runs on
|
||||
an older version of Python and may not support newer syntax, such as the
|
||||
extended f-string syntax added in Python 3.12.
|
||||
3. Or run _Black_ on your machine:
|
||||
**To Reproduce** Steps to reproduce the behavior:
|
||||
|
||||
1. Take this file '...'
|
||||
2. Run _Black_ on it with these arguments '....'
|
||||
3. See error
|
||||
|
||||
**Expected behavior** A clear and concise description of what you expected to happen.
|
||||
|
||||
**Environment (please complete the following information):**
|
||||
|
||||
- Version: [e.g. master]
|
||||
- OS and Python version: [e.g. Linux/Python 3.7.4rc1]
|
||||
|
||||
**Does this bug also happen on master?** To answer this, you have two options:
|
||||
|
||||
1. Use the online formatter at https://black.now.sh/?version=master, which will use the
|
||||
latest master branch.
|
||||
2. Or run _Black_ on your machine:
|
||||
- create a new virtualenv (make sure it's the same Python version);
|
||||
- clone this repository;
|
||||
- run `pip install -e .[d]`;
|
||||
- run `pip install -e .[d,python2]`;
|
||||
- run `pip install -r test_requirements.txt`
|
||||
- make sure it's sane by running `python -m pytest`; and
|
||||
- make sure it's sane by running `python -m unittest`; and
|
||||
- run `black` like you did last time.
|
||||
-->
|
||||
|
||||
**Describe the bug**
|
||||
|
||||
<!-- A clear and concise description of what the bug is. -->
|
||||
|
||||
**To Reproduce**
|
||||
|
||||
<!--
|
||||
Minimal steps to reproduce the behavior with source code and Black's configuration.
|
||||
-->
|
||||
|
||||
For example, take this code:
|
||||
|
||||
```python
|
||||
this = "code"
|
||||
```
|
||||
|
||||
And run it with these arguments:
|
||||
|
||||
```sh
|
||||
$ black file.py --target-version py39
|
||||
```
|
||||
|
||||
The resulting error is:
|
||||
|
||||
> cannot format file.py: INTERNAL ERROR: ...
|
||||
|
||||
**Expected behavior**
|
||||
|
||||
<!-- A clear and concise description of what you expected to happen. -->
|
||||
|
||||
**Environment**
|
||||
|
||||
<!-- Please complete the following information: -->
|
||||
|
||||
- Black's version: <!-- e.g. [main] -->
|
||||
- OS and Python version: <!-- e.g. [Linux/Python 3.7.4rc1] -->
|
||||
|
||||
**Additional context**
|
||||
|
||||
<!-- Add any other context about the problem here. -->
|
||||
**Additional context** Add any other context about the problem here.
|
||||
|
12
.github/ISSUE_TEMPLATE/config.yml
vendored
12
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -1,12 +0,0 @@
|
||||
# See also: https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository#configuring-the-template-chooser
|
||||
|
||||
# This is the default and blank issues are useful so let's keep 'em.
|
||||
blank_issues_enabled: true
|
||||
|
||||
contact_links:
|
||||
- name: Chat on Python Discord
|
||||
url: https://discord.gg/RtVdv86PrH
|
||||
about: |
|
||||
User support, questions, and other lightweight requests can be
|
||||
handled via the #black-formatter text channel we have on Python
|
||||
Discord.
|
27
.github/ISSUE_TEMPLATE/docs-issue.md
vendored
27
.github/ISSUE_TEMPLATE/docs-issue.md
vendored
@ -1,27 +0,0 @@
|
||||
---
|
||||
name: Documentation
|
||||
about: Report a problem with or suggest something for the documentation
|
||||
title: ""
|
||||
labels: "T: documentation"
|
||||
assignees: ""
|
||||
---
|
||||
|
||||
**Is this related to a problem? Please describe.**
|
||||
|
||||
<!-- A clear and concise description of what the problem is.
|
||||
e.g. I'm always frustrated when [...] / I wished that [...] -->
|
||||
|
||||
**Describe the solution you'd like**
|
||||
|
||||
<!-- A clear and concise description of what you want to
|
||||
happen or see changed. -->
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
|
||||
<!-- A clear and concise description of any
|
||||
alternative solutions or features you've considered. -->
|
||||
|
||||
**Additional context**
|
||||
|
||||
<!-- Add any other context or screenshots about the issue
|
||||
here. -->
|
26
.github/ISSUE_TEMPLATE/feature_request.md
vendored
26
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@ -2,26 +2,18 @@
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ""
|
||||
labels: "T: enhancement"
|
||||
labels: enhancement
|
||||
assignees: ""
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
**Is your feature request related to a problem? Please describe.** A clear and concise
|
||||
description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
<!-- A clear and concise description of what the problem is.
|
||||
e.g. I'm always frustrated when [...] -->
|
||||
**Describe the solution you'd like** A clear and concise description of what you want to
|
||||
happen.
|
||||
|
||||
**Describe the solution you'd like**
|
||||
**Describe alternatives you've considered** A clear and concise description of any
|
||||
alternative solutions or features you've considered.
|
||||
|
||||
<!-- A clear and concise description of what you want to
|
||||
happen. -->
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
|
||||
<!-- A clear and concise description of any
|
||||
alternative solutions or features you've considered. -->
|
||||
|
||||
**Additional context**
|
||||
|
||||
<!-- Add any other context or screenshots about the feature request
|
||||
here. -->
|
||||
**Additional context** Add any other context or screenshots about the feature request
|
||||
here.
|
||||
|
26
.github/ISSUE_TEMPLATE/style_issue.md
vendored
26
.github/ISSUE_TEMPLATE/style_issue.md
vendored
@ -1,20 +1,16 @@
|
||||
---
|
||||
name: Code style issue
|
||||
about: Help us improve the Black code style
|
||||
name: Style issue
|
||||
about: Help us improve the Black style
|
||||
title: ""
|
||||
labels: "T: style"
|
||||
labels: design
|
||||
assignees: ""
|
||||
---
|
||||
|
||||
**Describe the style change**
|
||||
**Describe the style change** A clear and concise description of how the style can be
|
||||
improved.
|
||||
|
||||
<!-- A clear and concise description of how the style can be
|
||||
improved. -->
|
||||
|
||||
**Examples in the current _Black_ style**
|
||||
|
||||
<!-- Think of some short code snippets that show
|
||||
how the current _Black_ style is not great: -->
|
||||
**Examples in the current _Black_ style** Think of some short code snippets that show
|
||||
how the current _Black_ style is not great:
|
||||
|
||||
```python
|
||||
def f():
|
||||
@ -22,9 +18,7 @@ def f():
|
||||
pass
|
||||
```
|
||||
|
||||
**Desired style**
|
||||
|
||||
<!-- How do you think _Black_ should format the above snippets: -->
|
||||
**Desired style** How do you think _Black_ should format the above snippets:
|
||||
|
||||
```python
|
||||
def f(
|
||||
@ -32,6 +26,4 @@ def f(
|
||||
pass
|
||||
```
|
||||
|
||||
**Additional context**
|
||||
|
||||
<!-- Add any other context about the problem here. -->
|
||||
**Additional context** Add any other context about the problem here.
|
||||
|
36
.github/PULL_REQUEST_TEMPLATE.md
vendored
36
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,36 +0,0 @@
|
||||
<!-- Hello! Thanks for submitting a PR. To help make things go a bit more
|
||||
smoothly we would appreciate that you go through this template. -->
|
||||
|
||||
### Description
|
||||
|
||||
<!-- Good things to put here include: reasoning for the change (please link
|
||||
any relevant issues!), any noteworthy (or hacky) choices to be aware of,
|
||||
or what the problem resolved here looked like ... we won't mind a ranty
|
||||
story :) -->
|
||||
|
||||
### Checklist - did you ...
|
||||
|
||||
<!-- If any of the following items aren't relevant for your contribution
|
||||
please still tick them so we know you've gone through the checklist.
|
||||
|
||||
All user-facing changes should get an entry. Otherwise, signal to us
|
||||
this should get the magical label to silence the CHANGELOG entry check.
|
||||
Tests are required for bugfixes and new features. Documentation changes
|
||||
are necessary for formatting and most enhancement changes. -->
|
||||
|
||||
- [ ] Add an entry in `CHANGES.md` if necessary?
|
||||
- [ ] Add / update tests if necessary?
|
||||
- [ ] Add new / update outdated documentation?
|
||||
|
||||
<!-- Just as a reminder, everyone in all psf/black spaces including PRs
|
||||
must follow the PSF Code of Conduct (link below).
|
||||
|
||||
Finally, once again thanks for your time and effort. If you have any
|
||||
feedback in regards to your experience contributing here, please
|
||||
let us know!
|
||||
|
||||
Helpful links:
|
||||
|
||||
PSF COC: https://www.python.org/psf/conduct/
|
||||
Contributing docs: https://black.readthedocs.io/en/latest/contributing/index.html
|
||||
Chat on Python Discord: https://discord.gg/RtVdv86PrH -->
|
16
.github/dependabot.yml
vendored
16
.github/dependabot.yml
vendored
@ -1,16 +0,0 @@
|
||||
# https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
# Workflow files in .github/workflows will be checked
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
labels: ["skip news", "C: dependencies"]
|
||||
|
||||
- package-ecosystem: "pip"
|
||||
directory: "docs/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
labels: ["skip news", "C: dependencies", "T: documentation"]
|
7
.github/workflows/changelog.yml
vendored
7
.github/workflows/changelog.yml
vendored
@ -4,9 +4,6 @@ on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, labeled, unlabeled, reopened]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Changelog Entry Check
|
||||
@ -14,11 +11,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Grep CHANGES.md for PR number
|
||||
if: contains(github.event.pull_request.labels.*.name, 'skip news') != true
|
||||
run: |
|
||||
grep -Pz "\((\n\s*)?#${{ github.event.pull_request.number }}(\n\s*)?\)" CHANGES.md || \
|
||||
(echo "Please add '(#${{ github.event.pull_request.number }})' change line to CHANGES.md (or if appropriate, ask a maintainer to add the 'skip news' label)" && \
|
||||
(echo "Please add '(#${{ github.event.pull_request.number }})' change line to CHANGES.md" && \
|
||||
exit 1)
|
||||
|
155
.github/workflows/diff_shades.yml
vendored
155
.github/workflows/diff_shades.yml
vendored
@ -1,155 +0,0 @@
|
||||
name: diff-shades
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths: ["src/**", "pyproject.toml", ".github/workflows/*"]
|
||||
|
||||
pull_request:
|
||||
paths: ["src/**", "pyproject.toml", ".github/workflows/*"]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
configure:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix: ${{ steps.set-config.outputs.matrix }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.11"
|
||||
|
||||
- name: Install diff-shades and support dependencies
|
||||
run: |
|
||||
python -m pip install 'click>=8.1.7' packaging urllib3
|
||||
python -m pip install https://github.com/ichard26/diff-shades/archive/stable.zip
|
||||
|
||||
- name: Calculate run configuration & metadata
|
||||
id: set-config
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
run: >
|
||||
python scripts/diff_shades_gha_helper.py config ${{ github.event_name }}
|
||||
${{ matrix.mode }}
|
||||
|
||||
analysis:
|
||||
name: analysis / ${{ matrix.mode }}
|
||||
needs: configure
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
HATCH_BUILD_HOOKS_ENABLE: "1"
|
||||
# Clang is less picky with the C code it's given than gcc (and may
|
||||
# generate faster binaries too).
|
||||
CC: clang-18
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include: ${{ fromJson(needs.configure.outputs.matrix) }}
|
||||
|
||||
steps:
|
||||
- name: Checkout this repository (full clone)
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
# The baseline revision could be rather old so a full clone is ideal.
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.11"
|
||||
|
||||
- name: Install diff-shades and support dependencies
|
||||
run: |
|
||||
python -m pip install https://github.com/ichard26/diff-shades/archive/stable.zip
|
||||
python -m pip install 'click>=8.1.7' packaging urllib3
|
||||
# After checking out old revisions, this might not exist so we'll use a copy.
|
||||
cat scripts/diff_shades_gha_helper.py > helper.py
|
||||
git config user.name "diff-shades-gha"
|
||||
git config user.email "diff-shades-gha@example.com"
|
||||
|
||||
- name: Attempt to use cached baseline analysis
|
||||
id: baseline-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ matrix.baseline-analysis }}
|
||||
key: ${{ matrix.baseline-cache-key }}
|
||||
|
||||
- name: Build and install baseline revision
|
||||
if: steps.baseline-cache.outputs.cache-hit != 'true'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
run: >
|
||||
${{ matrix.baseline-setup-cmd }}
|
||||
&& python -m pip install .
|
||||
|
||||
- name: Analyze baseline revision
|
||||
if: steps.baseline-cache.outputs.cache-hit != 'true'
|
||||
run: >
|
||||
diff-shades analyze -v --work-dir projects-cache/
|
||||
${{ matrix.baseline-analysis }} ${{ matrix.force-flag }}
|
||||
|
||||
- name: Build and install target revision
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
run: >
|
||||
${{ matrix.target-setup-cmd }}
|
||||
&& python -m pip install .
|
||||
|
||||
- name: Analyze target revision
|
||||
run: >
|
||||
diff-shades analyze -v --work-dir projects-cache/
|
||||
${{ matrix.target-analysis }} --repeat-projects-from
|
||||
${{ matrix.baseline-analysis }} ${{ matrix.force-flag }}
|
||||
|
||||
- name: Generate HTML diff report
|
||||
run: >
|
||||
diff-shades --dump-html diff.html compare --diff
|
||||
${{ matrix.baseline-analysis }} ${{ matrix.target-analysis }}
|
||||
|
||||
- name: Upload diff report
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.mode }}-diff.html
|
||||
path: diff.html
|
||||
|
||||
- name: Upload baseline analysis
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.baseline-analysis }}
|
||||
path: ${{ matrix.baseline-analysis }}
|
||||
|
||||
- name: Upload target analysis
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.target-analysis }}
|
||||
path: ${{ matrix.target-analysis }}
|
||||
|
||||
- name: Generate summary file (PR only)
|
||||
if: github.event_name == 'pull_request' && matrix.mode == 'preview-changes'
|
||||
run: >
|
||||
python helper.py comment-body ${{ matrix.baseline-analysis }}
|
||||
${{ matrix.target-analysis }} ${{ matrix.baseline-sha }}
|
||||
${{ matrix.target-sha }} ${{ github.event.pull_request.number }}
|
||||
|
||||
- name: Upload summary file (PR only)
|
||||
if: github.event_name == 'pull_request' && matrix.mode == 'preview-changes'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: .pr-comment.json
|
||||
path: .pr-comment.json
|
||||
|
||||
- name: Verify zero changes (PR only)
|
||||
if: matrix.mode == 'assert-no-changes'
|
||||
run: >
|
||||
diff-shades compare --check ${{ matrix.baseline-analysis }} ${{ matrix.target-analysis }}
|
||||
|| (echo "Please verify you didn't change the stable code style unintentionally!" && exit 1)
|
||||
|
||||
- name: Check for failed files for target revision
|
||||
# Even if the previous step failed, we should still check for failed files.
|
||||
if: always()
|
||||
run: >
|
||||
diff-shades show-failed --check --show-log ${{ matrix.target-analysis }}
|
49
.github/workflows/diff_shades_comment.yml
vendored
49
.github/workflows/diff_shades_comment.yml
vendored
@ -1,49 +0,0 @@
|
||||
name: diff-shades-comment
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [diff-shades]
|
||||
types: [completed]
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
comment:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "*"
|
||||
|
||||
- name: Install support dependencies
|
||||
run: |
|
||||
python -m pip install pip --upgrade
|
||||
python -m pip install click packaging urllib3
|
||||
|
||||
- name: Get details from initial workflow run
|
||||
id: metadata
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
run: >
|
||||
python scripts/diff_shades_gha_helper.py comment-details
|
||||
${{github.event.workflow_run.id }}
|
||||
|
||||
- name: Try to find pre-existing PR comment
|
||||
if: steps.metadata.outputs.needs-comment == 'true'
|
||||
id: find-comment
|
||||
uses: peter-evans/find-comment@3eae4d37986fb5a8592848f6a574fdf654e61f9e
|
||||
with:
|
||||
issue-number: ${{ steps.metadata.outputs.pr-number }}
|
||||
comment-author: "github-actions[bot]"
|
||||
body-includes: "diff-shades"
|
||||
|
||||
- name: Create or update PR comment
|
||||
if: steps.metadata.outputs.needs-comment == 'true'
|
||||
uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043
|
||||
with:
|
||||
comment-id: ${{ steps.find-comment.outputs.comment-id }}
|
||||
issue-number: ${{ steps.metadata.outputs.pr-number }}
|
||||
body: ${{ steps.metadata.outputs.comment-body }}
|
||||
edit-mode: replace
|
44
.github/workflows/doc.yml
vendored
44
.github/workflows/doc.yml
vendored
@ -1,9 +1,18 @@
|
||||
name: Documentation
|
||||
name: Documentation Build
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- "docs/**"
|
||||
- "README.md"
|
||||
- "CHANGES.md"
|
||||
- "CONTRIBUTING.md"
|
||||
pull_request:
|
||||
paths:
|
||||
- "docs/**"
|
||||
- "README.md"
|
||||
- "CHANGES.md"
|
||||
- "CONTRIBUTING.md"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@ -14,27 +23,20 @@ jobs:
|
||||
github.event_name == 'push' || github.event.pull_request.head.repo.full_name !=
|
||||
github.repository
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up latest Python
|
||||
uses: actions/setup-python@v5
|
||||
- name: Set up Python 3.9
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: "3.13"
|
||||
allow-prereleases: true
|
||||
python-version: 3.9
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install uv
|
||||
python -m uv venv
|
||||
python -m uv pip install -e ".[d]"
|
||||
python -m uv pip install -r "docs/requirements.txt"
|
||||
python -m pip install --upgrade pip setuptools wheel
|
||||
python -m pip install -e "."
|
||||
python -m pip install -r "docs/requirements.txt"
|
||||
|
||||
- name: Build documentation
|
||||
run: sphinx-build -a -b html -W --keep-going docs/ docs/_build
|
||||
run: sphinx-build -a -b html -W docs/ docs/_build/
|
||||
|
40
.github/workflows/docker.yml
vendored
40
.github/workflows/docker.yml
vendored
@ -3,29 +3,25 @@ name: docker
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
- "master"
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
types: created
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
if: github.repository == 'psf/black'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
uses: docker/setup-qemu-action@v1
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
@ -36,34 +32,12 @@ jobs:
|
||||
latest_non_release)" >> $GITHUB_ENV
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: pyfound/black:latest,pyfound/black:${{ env.GIT_TAG }}
|
||||
|
||||
- name: Build and push latest_release tag
|
||||
if:
|
||||
${{ github.event_name == 'release' && github.event.action == 'published' &&
|
||||
!github.event.release.prerelease }}
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: pyfound/black:latest_release
|
||||
|
||||
- name: Build and push latest_prerelease tag
|
||||
if:
|
||||
${{ github.event_name == 'release' && github.event.action == 'published' &&
|
||||
github.event.release.prerelease }}
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: pyfound/black:latest_prerelease
|
||||
|
||||
- name: Image digest
|
||||
run: echo ${{ steps.docker_build.outputs.digest }}
|
||||
|
14
.github/workflows/fuzz.yml
vendored
14
.github/workflows/fuzz.yml
vendored
@ -2,13 +2,6 @@ name: Fuzz
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
# We want to run on external PRs, but not on our own internal PRs as they'll be run
|
||||
@ -22,16 +15,15 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ["3.9", "3.10", "3.11", "3.12.4", "3.13"]
|
||||
python-version: [3.6, 3.7, 3.8, 3.9]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
allow-prereleases: true
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
|
34
.github/workflows/lint.yml
vendored
34
.github/workflows/lint.yml
vendored
@ -1,4 +1,4 @@
|
||||
name: Lint + format ourselves
|
||||
name: Lint
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
@ -14,35 +14,15 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Assert PR target is main
|
||||
if: github.event_name == 'pull_request' && github.repository == 'psf/black'
|
||||
run: |
|
||||
if [ "$GITHUB_BASE_REF" != "main" ]; then
|
||||
echo "::error::PR targeting '$GITHUB_BASE_REF', please refile targeting 'main'." && exit 1
|
||||
fi
|
||||
|
||||
- name: Set up latest Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.13"
|
||||
allow-prereleases: true
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install -e '.'
|
||||
python -m pip install tox
|
||||
python -m pip install -e '.[d]'
|
||||
|
||||
- name: Run pre-commit hooks
|
||||
uses: pre-commit/action@v3.0.1
|
||||
|
||||
- name: Format ourselves
|
||||
run: |
|
||||
tox -e run_self
|
||||
|
||||
- name: Regenerate schema
|
||||
run: |
|
||||
tox -e generate_schema
|
||||
git diff --exit-code
|
||||
- name: Lint
|
||||
uses: pre-commit/action@v2.0.2
|
||||
|
38
.github/workflows/primer.yml
vendored
Normal file
38
.github/workflows/primer.yml
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
name: Primer
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
# We want to run on external PRs, but not on our own internal PRs as they'll be run
|
||||
# by the push to the branch. Without this if check, checks are duplicated since
|
||||
# internal PRs match both the push and pull_request events.
|
||||
if:
|
||||
github.event_name == 'push' || github.event.pull_request.head.repo.full_name !=
|
||||
github.repository
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: [3.6, 3.7, 3.8, 3.9]
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install -e ".[d]"
|
||||
|
||||
- name: Primer run
|
||||
env:
|
||||
pythonioencoding: utf-8
|
||||
run: |
|
||||
black-primer
|
129
.github/workflows/pypi_upload.yml
vendored
129
.github/workflows/pypi_upload.yml
vendored
@ -1,130 +1,31 @@
|
||||
name: Build and publish
|
||||
name: pypi_upload
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
types: created
|
||||
|
||||
jobs:
|
||||
main:
|
||||
name: sdist + pure wheel
|
||||
build:
|
||||
name: PyPI Upload
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'release'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up latest Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.13"
|
||||
allow-prereleases: true
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
|
||||
- name: Install latest pip, build, twine
|
||||
- name: Install latest pip, setuptools, twine + wheel
|
||||
run: |
|
||||
python -m pip install --upgrade --disable-pip-version-check pip
|
||||
python -m pip install --upgrade build twine
|
||||
python -m pip install --upgrade pip setuptools twine wheel
|
||||
|
||||
- name: Build wheel and source distributions
|
||||
run: python -m build
|
||||
- name: Build wheels
|
||||
run: |
|
||||
python setup.py bdist_wheel
|
||||
python setup.py sdist
|
||||
|
||||
- if: github.event_name == 'release'
|
||||
name: Upload to PyPI via Twine
|
||||
- name: Upload to PyPI via Twine
|
||||
env:
|
||||
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
|
||||
run: twine upload --verbose -u '__token__' dist/*
|
||||
|
||||
generate_wheels_matrix:
|
||||
name: generate wheels matrix
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
include: ${{ steps.set-matrix.outputs.include }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# Keep cibuildwheel version in sync with below
|
||||
- name: Install cibuildwheel and pypyp
|
||||
run: |
|
||||
pipx install cibuildwheel==2.22.0
|
||||
pipx install pypyp==1.3.0
|
||||
- name: generate matrix
|
||||
if: github.event_name != 'pull_request'
|
||||
run: |
|
||||
{
|
||||
cibuildwheel --print-build-identifiers --platform linux \
|
||||
| pyp 'json.dumps({"only": x, "os": "ubuntu-latest"})' \
|
||||
&& cibuildwheel --print-build-identifiers --platform macos \
|
||||
| pyp 'json.dumps({"only": x, "os": "macos-latest"})' \
|
||||
&& cibuildwheel --print-build-identifiers --platform windows \
|
||||
| pyp 'json.dumps({"only": x, "os": "windows-latest"})'
|
||||
} | pyp 'json.dumps(list(map(json.loads, lines)))' > /tmp/matrix
|
||||
env:
|
||||
CIBW_ARCHS_LINUX: x86_64
|
||||
CIBW_ARCHS_MACOS: x86_64 arm64
|
||||
CIBW_ARCHS_WINDOWS: AMD64
|
||||
- name: generate matrix (PR)
|
||||
if: github.event_name == 'pull_request'
|
||||
run: |
|
||||
{
|
||||
cibuildwheel --print-build-identifiers --platform linux \
|
||||
| pyp 'json.dumps({"only": x, "os": "ubuntu-latest"})'
|
||||
} | pyp 'json.dumps(list(map(json.loads, lines)))' > /tmp/matrix
|
||||
env:
|
||||
CIBW_BUILD: "cp39-* cp313-*"
|
||||
CIBW_ARCHS_LINUX: x86_64
|
||||
- id: set-matrix
|
||||
run: echo "include=$(cat /tmp/matrix)" | tee -a $GITHUB_OUTPUT
|
||||
|
||||
mypyc:
|
||||
name: mypyc wheels ${{ matrix.only }}
|
||||
needs: generate_wheels_matrix
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include: ${{ fromJson(needs.generate_wheels_matrix.outputs.include) }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# Keep cibuildwheel version in sync with above
|
||||
- uses: pypa/cibuildwheel@v2.23.3
|
||||
with:
|
||||
only: ${{ matrix.only }}
|
||||
|
||||
- name: Upload wheels as workflow artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.only }}-mypyc-wheels
|
||||
path: ./wheelhouse/*.whl
|
||||
|
||||
- if: github.event_name == 'release'
|
||||
name: Upload wheels to PyPI via Twine
|
||||
env:
|
||||
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
|
||||
run: pipx run twine upload --verbose -u '__token__' wheelhouse/*.whl
|
||||
|
||||
update-stable-branch:
|
||||
name: Update stable branch
|
||||
needs: [main, mypyc]
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'release'
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
steps:
|
||||
- name: Checkout stable branch
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: stable
|
||||
fetch-depth: 0
|
||||
|
||||
- if: github.event_name == 'release'
|
||||
name: Update stable branch to release tag & push
|
||||
run: |
|
||||
git reset --hard ${{ github.event.release.tag_name }}
|
||||
git push
|
||||
twine upload --verbose -u '__token__' dist/*
|
||||
|
56
.github/workflows/release_tests.yml
vendored
56
.github/workflows/release_tests.yml
vendored
@ -1,56 +0,0 @@
|
||||
name: Release tool CI
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- .github/workflows/release_tests.yml
|
||||
- release.py
|
||||
- release_tests.py
|
||||
pull_request:
|
||||
paths:
|
||||
- .github/workflows/release_tests.yml
|
||||
- release.py
|
||||
- release_tests.py
|
||||
|
||||
jobs:
|
||||
build:
|
||||
# We want to run on external PRs, but not on our own internal PRs as they'll be run
|
||||
# by the push to the branch. Without this if check, checks are duplicated since
|
||||
# internal PRs match both the push and pull_request events.
|
||||
if:
|
||||
github.event_name == 'push' || github.event.pull_request.head.repo.full_name !=
|
||||
github.repository
|
||||
|
||||
name: Running python ${{ matrix.python-version }} on ${{matrix.os}}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.13"]
|
||||
os: [macOS-latest, ubuntu-latest, windows-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
# Give us all history, branches and tags
|
||||
fetch-depth: 0
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
allow-prereleases: true
|
||||
|
||||
- name: Print Python Version
|
||||
run: python --version --version && which python
|
||||
|
||||
- name: Print Git Version
|
||||
run: git --version && which git
|
||||
|
||||
- name: Update pip, setuptools + wheels
|
||||
run: |
|
||||
python -m pip install --upgrade pip setuptools wheel
|
||||
|
||||
- name: Run unit tests via coverage + print report
|
||||
run: |
|
||||
python -m pip install coverage
|
||||
coverage run scripts/release_tests.py
|
||||
coverage report --show-missing
|
89
.github/workflows/test.yml
vendored
89
.github/workflows/test.yml
vendored
@ -1,25 +1,9 @@
|
||||
name: Test
|
||||
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- "docs/**"
|
||||
- "*.md"
|
||||
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- "docs/**"
|
||||
- "*.md"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
main:
|
||||
build:
|
||||
# We want to run on external PRs, but not on our own internal PRs as they'll be run
|
||||
# by the push to the branch. Without this if check, checks are duplicated since
|
||||
# internal PRs match both the push and pull_request events.
|
||||
@ -31,39 +15,35 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ["3.9", "3.10", "3.11", "3.12.4", "3.13", "pypy-3.9"]
|
||||
python-version: [3.6, 3.7, 3.8, 3.9]
|
||||
os: [ubuntu-latest, macOS-latest, windows-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
allow-prereleases: true
|
||||
|
||||
- name: Install tox
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install --upgrade tox
|
||||
|
||||
- name: Unit tests
|
||||
if: "!startsWith(matrix.python-version, 'pypy')"
|
||||
run:
|
||||
tox -e ci-py$(echo ${{ matrix.python-version }} | tr -d '.') -- -v --color=yes
|
||||
run: |
|
||||
tox -e py
|
||||
|
||||
- name: Unit tests (pypy)
|
||||
if: "startsWith(matrix.python-version, 'pypy')"
|
||||
run: tox -e ci-pypy3 -- -v --color=yes
|
||||
|
||||
- name: Upload coverage to Coveralls
|
||||
# Upload coverage if we are on the main repository and
|
||||
- name: Publish coverage to Coveralls
|
||||
# If pushed / is a pull request against main repo AND
|
||||
# we're running on Linux (this action only supports Linux)
|
||||
if:
|
||||
github.repository == 'psf/black' && matrix.os == 'ubuntu-latest' &&
|
||||
!startsWith(matrix.python-version, 'pypy')
|
||||
uses: AndreMiras/coveralls-python-action@ac868b9540fad490f7ca82b8ca00480fd751ed19
|
||||
((github.event_name == 'push' && github.repository == 'psf/black') ||
|
||||
github.event.pull_request.base.repo.full_name == 'psf/black') && matrix.os ==
|
||||
'ubuntu-latest'
|
||||
|
||||
uses: AndreMiras/coveralls-python-action@v20201129
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
parallel: true
|
||||
@ -71,40 +51,17 @@ jobs:
|
||||
debug: true
|
||||
|
||||
coveralls-finish:
|
||||
needs: main
|
||||
if: github.repository == 'psf/black'
|
||||
needs: build
|
||||
# If pushed / is a pull request against main repo
|
||||
if:
|
||||
(github.event_name == 'push' && github.repository == 'psf/black') ||
|
||||
github.event.pull_request.base.repo.full_name == 'psf/black'
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Send finished signal to Coveralls
|
||||
uses: AndreMiras/coveralls-python-action@ac868b9540fad490f7ca82b8ca00480fd751ed19
|
||||
- uses: actions/checkout@v2
|
||||
- name: Coveralls finished
|
||||
uses: AndreMiras/coveralls-python-action@v20201129
|
||||
with:
|
||||
parallel-finished: true
|
||||
debug: true
|
||||
|
||||
uvloop:
|
||||
if:
|
||||
github.event_name == 'push' || github.event.pull_request.head.repo.full_name !=
|
||||
github.repository
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macOS-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up latest Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.12.4"
|
||||
|
||||
- name: Install black with uvloop
|
||||
run: |
|
||||
python -m pip install pip --upgrade --disable-pip-version-check
|
||||
python -m pip install -e ".[uvloop]"
|
||||
|
||||
- name: Format ourselves
|
||||
run: python -m black --check src/ tests/
|
||||
|
46
.github/workflows/upload_binary.yml
vendored
46
.github/workflows/upload_binary.yml
vendored
@ -1,56 +1,44 @@
|
||||
name: Publish executables
|
||||
name: Upload self-contained binaries
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
permissions:
|
||||
contents: write # actions/upload-release-asset needs this.
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [windows-2019, ubuntu-22.04, macos-latest]
|
||||
python-version: [3.7]
|
||||
os: [ubuntu-16.04, windows-2019]
|
||||
include:
|
||||
- os: windows-2019
|
||||
pathsep: ";"
|
||||
asset_name: black_windows.exe
|
||||
executable_suffix: ".exe"
|
||||
executable_mime: "application/vnd.microsoft.portable-executable"
|
||||
- os: ubuntu-22.04
|
||||
- os: ubuntu-16.04
|
||||
pathsep: ":"
|
||||
asset_name: black_linux
|
||||
executable_suffix: ".elf"
|
||||
executable_mime: "application/x-executable"
|
||||
- os: macos-latest
|
||||
pathsep: ":"
|
||||
asset_name: black_macos
|
||||
executable_mime: "application/x-mach-binary"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up latest Python
|
||||
uses: actions/setup-python@v5
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: "3.12.4"
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Install Black and PyInstaller
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip wheel
|
||||
python -m pip install .[colorama]
|
||||
python -m pip install --upgrade pip wheel setuptools
|
||||
python -m pip install .
|
||||
python -m pip install pyinstaller
|
||||
|
||||
- name: Build executable with PyInstaller
|
||||
run: >
|
||||
python -m PyInstaller -F --name ${{ matrix.asset_name }} --add-data
|
||||
'src/blib2to3${{ matrix.pathsep }}blib2to3' src/black/__main__.py
|
||||
|
||||
- name: Quickly test executable
|
||||
- name: Build binary
|
||||
run: |
|
||||
./dist/${{ matrix.asset_name }} --version
|
||||
./dist/${{ matrix.asset_name }} src --verbose
|
||||
python -m PyInstaller -F --name black${{ matrix.executable_suffix }} --add-data 'src/blib2to3${{ matrix.pathsep }}blib2to3' src/black/__main__.py
|
||||
|
||||
- name: Upload binary as release asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
@ -58,6 +46,6 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ github.event.release.upload_url }}
|
||||
asset_path: dist/${{ matrix.asset_name }}
|
||||
asset_name: ${{ matrix.asset_name }}
|
||||
asset_path: dist/black${{ matrix.executable_suffix }}
|
||||
asset_name: black${{ matrix.executable_suffix }}
|
||||
asset_content_type: ${{ matrix.executable_mime }}
|
||||
|
13
.gitignore
vendored
13
.gitignore
vendored
@ -1,28 +1,19 @@
|
||||
.venv
|
||||
.coverage
|
||||
.coverage.*
|
||||
_build
|
||||
.DS_Store
|
||||
.vscode
|
||||
.python-version
|
||||
docs/_static/pypi.svg
|
||||
.tox
|
||||
__pycache__
|
||||
|
||||
# Packaging artifacts
|
||||
black.egg-info
|
||||
black.dist-info
|
||||
build/
|
||||
dist/
|
||||
pip-wheel-metadata/
|
||||
.eggs
|
||||
|
||||
src/_black_version.py
|
||||
.idea
|
||||
|
||||
.eggs
|
||||
.dmypy.json
|
||||
*.swp
|
||||
.hypothesis/
|
||||
venv/
|
||||
.ipynb_checkpoints/
|
||||
node_modules/
|
||||
venv/
|
@ -1,83 +1,31 @@
|
||||
# Note: don't use this config for your own repositories. Instead, see
|
||||
# "Version control integration" in docs/integrations/source_version_control.md
|
||||
exclude: ^(profiling/|tests/data/)
|
||||
# "Version control integration" in README.md.
|
||||
exclude: ^(src/blib2to3/|profiling/|tests/data/)
|
||||
repos:
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: check-pre-commit-rev-in-example
|
||||
name: Check pre-commit rev in example
|
||||
language: python
|
||||
entry: python -m scripts.check_pre_commit_rev_in_example
|
||||
files: '(CHANGES\.md|source_version_control\.md)$'
|
||||
additional_dependencies:
|
||||
&version_check_dependencies [
|
||||
commonmark==0.9.1,
|
||||
pyyaml==6.0.1,
|
||||
beautifulsoup4==4.9.3,
|
||||
]
|
||||
- id: black
|
||||
name: black
|
||||
language: system
|
||||
entry: black
|
||||
minimum_pre_commit_version: 2.9.2
|
||||
require_serial: true
|
||||
types_or: [python, pyi]
|
||||
|
||||
- id: check-version-in-the-basics-example
|
||||
name: Check black version in the basics example
|
||||
language: python
|
||||
entry: python -m scripts.check_version_in_basics_example
|
||||
files: '(CHANGES\.md|the_basics\.md)$'
|
||||
additional_dependencies: *version_check_dependencies
|
||||
|
||||
- repo: https://github.com/pycqa/isort
|
||||
rev: 6.0.1
|
||||
hooks:
|
||||
- id: isort
|
||||
|
||||
- repo: https://github.com/pycqa/flake8
|
||||
rev: 7.2.0
|
||||
- repo: https://gitlab.com/pycqa/flake8
|
||||
rev: 3.9.0
|
||||
hooks:
|
||||
- id: flake8
|
||||
additional_dependencies:
|
||||
- flake8-bugbear==24.2.6
|
||||
- flake8-comprehensions
|
||||
- flake8-simplify
|
||||
exclude: ^src/blib2to3/
|
||||
additional_dependencies: [flake8-bugbear]
|
||||
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v1.15.0
|
||||
rev: v0.812
|
||||
hooks:
|
||||
- id: mypy
|
||||
exclude: ^(docs/conf.py|scripts/generate_schema.py)$
|
||||
args: []
|
||||
additional_dependencies: &mypy_deps
|
||||
- types-PyYAML
|
||||
- types-atheris
|
||||
- tomli >= 0.2.6, < 2.0.0
|
||||
- click >= 8.2.0
|
||||
# Click is intentionally out-of-sync with pyproject.toml
|
||||
# v8.2 has breaking changes. We work around them at runtime, but we need the newer stubs.
|
||||
- packaging >= 22.0
|
||||
- platformdirs >= 2.1.0
|
||||
- pytokens >= 0.1.10
|
||||
- pytest
|
||||
- hypothesis
|
||||
- aiohttp >= 3.7.4
|
||||
- types-commonmark
|
||||
- urllib3
|
||||
- hypothesmith
|
||||
- id: mypy
|
||||
name: mypy (Python 3.10)
|
||||
files: scripts/generate_schema.py
|
||||
args: ["--python-version=3.10"]
|
||||
additional_dependencies: *mypy_deps
|
||||
exclude: ^docs/conf.py
|
||||
|
||||
- repo: https://github.com/rbubley/mirrors-prettier
|
||||
rev: v3.5.3
|
||||
- repo: https://github.com/pre-commit/mirrors-prettier
|
||||
rev: v2.2.1
|
||||
hooks:
|
||||
- id: prettier
|
||||
types_or: [markdown, yaml, json]
|
||||
exclude: \.github/workflows/diff_shades\.yml
|
||||
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v5.0.0
|
||||
hooks:
|
||||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
|
||||
ci:
|
||||
autoupdate_schedule: quarterly
|
||||
args: [--prose-wrap=always, --print-width=88]
|
||||
|
@ -1,20 +1,9 @@
|
||||
# Note that we recommend using https://github.com/psf/black-pre-commit-mirror instead
|
||||
# This will work about 2x as fast as using the hooks in this repository
|
||||
- id: black
|
||||
name: black
|
||||
description: "Black: The uncompromising Python code formatter"
|
||||
entry: black
|
||||
language: python
|
||||
language_version: python3
|
||||
minimum_pre_commit_version: 2.9.2
|
||||
require_serial: true
|
||||
types_or: [python, pyi]
|
||||
- id: black-jupyter
|
||||
name: black-jupyter
|
||||
description:
|
||||
"Black: The uncompromising Python code formatter (with Jupyter Notebook support)"
|
||||
entry: black
|
||||
language: python
|
||||
minimum_pre_commit_version: 2.9.2
|
||||
require_serial: true
|
||||
types_or: [python, pyi, jupyter]
|
||||
additional_dependencies: [".[jupyter]"]
|
||||
|
@ -1,3 +0,0 @@
|
||||
proseWrap: always
|
||||
printWidth: 88
|
||||
endOfLine: auto
|
@ -1,21 +0,0 @@
|
||||
version: 2
|
||||
|
||||
formats:
|
||||
- htmlzip
|
||||
|
||||
build:
|
||||
os: ubuntu-22.04
|
||||
tools:
|
||||
python: "3.11"
|
||||
|
||||
python:
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
||||
|
||||
- method: pip
|
||||
path: .
|
||||
extra_requirements:
|
||||
- d
|
||||
|
||||
sphinx:
|
||||
configuration: docs/conf.py
|
197
AUTHORS.md
197
AUTHORS.md
@ -1,197 +0,0 @@
|
||||
# Authors
|
||||
|
||||
Glued together by [Łukasz Langa](mailto:lukasz@langa.pl).
|
||||
|
||||
Maintained with:
|
||||
|
||||
- [Carol Willing](mailto:carolcode@willingconsulting.com)
|
||||
- [Carl Meyer](mailto:carl@oddbird.net)
|
||||
- [Jelle Zijlstra](mailto:jelle.zijlstra@gmail.com)
|
||||
- [Mika Naylor](mailto:mail@autophagy.io)
|
||||
- [Zsolt Dollenstein](mailto:zsol.zsol@gmail.com)
|
||||
- [Cooper Lees](mailto:me@cooperlees.com)
|
||||
- [Richard Si](mailto:sichard26@gmail.com)
|
||||
- [Felix Hildén](mailto:felix.hilden@gmail.com)
|
||||
- [Batuhan Taskaya](mailto:batuhan@python.org)
|
||||
- [Shantanu Jain](mailto:hauntsaninja@gmail.com)
|
||||
|
||||
Multiple contributions by:
|
||||
|
||||
- [Abdur-Rahmaan Janhangeer](mailto:arj.python@gmail.com)
|
||||
- [Adam Johnson](mailto:me@adamj.eu)
|
||||
- [Adam Williamson](mailto:adamw@happyassassin.net)
|
||||
- [Alexander Huynh](mailto:ahrex-gh-psf-black@e.sc)
|
||||
- [Alexandr Artemyev](mailto:mogost@gmail.com)
|
||||
- [Alex Vandiver](mailto:github@chmrr.net)
|
||||
- [Allan Simon](mailto:allan.simon@supinfo.com)
|
||||
- Anders-Petter Ljungquist
|
||||
- [Amethyst Reese](mailto:amy@n7.gg)
|
||||
- [Andrew Thorp](mailto:andrew.thorp.dev@gmail.com)
|
||||
- [Andrew Zhou](mailto:andrewfzhou@gmail.com)
|
||||
- [Andrey](mailto:dyuuus@yandex.ru)
|
||||
- [Andy Freeland](mailto:andy@andyfreeland.net)
|
||||
- [Anthony Sottile](mailto:asottile@umich.edu)
|
||||
- [Antonio Ossa Guerra](mailto:aaossa+black@uc.cl)
|
||||
- [Arjaan Buijk](mailto:arjaan.buijk@gmail.com)
|
||||
- [Arnav Borbornah](mailto:arnavborborah11@gmail.com)
|
||||
- [Artem Malyshev](mailto:proofit404@gmail.com)
|
||||
- [Asger Hautop Drewsen](mailto:asgerdrewsen@gmail.com)
|
||||
- [Augie Fackler](mailto:raf@durin42.com)
|
||||
- [Aviskar KC](mailto:aviskarkc10@gmail.com)
|
||||
- Batuhan Taşkaya
|
||||
- [Benjamin Wohlwend](mailto:bw@piquadrat.ch)
|
||||
- [Benjamin Woodruff](mailto:github@benjam.info)
|
||||
- [Bharat Raghunathan](mailto:bharatraghunthan9767@gmail.com)
|
||||
- [Brandt Bucher](mailto:brandtbucher@gmail.com)
|
||||
- [Brett Cannon](mailto:brett@python.org)
|
||||
- [Bryan Bugyi](mailto:bryan.bugyi@rutgers.edu)
|
||||
- [Bryan Forbes](mailto:bryan@reigndropsfall.net)
|
||||
- [Calum Lind](mailto:calumlind@gmail.com)
|
||||
- [Charles](mailto:peacech@gmail.com)
|
||||
- Charles Reid
|
||||
- [Christian Clauss](mailto:cclauss@bluewin.ch)
|
||||
- [Christian Heimes](mailto:christian@python.org)
|
||||
- [Chuck Wooters](mailto:chuck.wooters@microsoft.com)
|
||||
- [Chris Rose](mailto:offline@offby1.net)
|
||||
- Codey Oxley
|
||||
- [Cong](mailto:congusbongus@gmail.com)
|
||||
- [Cooper Ry Lees](mailto:me@cooperlees.com)
|
||||
- [Dan Davison](mailto:dandavison7@gmail.com)
|
||||
- [Daniel Hahler](mailto:github@thequod.de)
|
||||
- [Daniel M. Capella](mailto:polycitizen@gmail.com)
|
||||
- Daniele Esposti
|
||||
- [David Hotham](mailto:david.hotham@metaswitch.com)
|
||||
- [David Lukes](mailto:dafydd.lukes@gmail.com)
|
||||
- [David Szotten](mailto:davidszotten@gmail.com)
|
||||
- [Denis Laxalde](mailto:denis@laxalde.org)
|
||||
- [Douglas Thor](mailto:dthor@transphormusa.com)
|
||||
- dylanjblack
|
||||
- [Eli Treuherz](mailto:eli@treuherz.com)
|
||||
- [Emil Hessman](mailto:emil@hessman.se)
|
||||
- [Felix Kohlgrüber](mailto:felix.kohlgrueber@gmail.com)
|
||||
- [Florent Thiery](mailto:fthiery@gmail.com)
|
||||
- Francisco
|
||||
- [Giacomo Tagliabue](mailto:giacomo.tag@gmail.com)
|
||||
- [Greg Gandenberger](mailto:ggandenberger@shoprunner.com)
|
||||
- [Gregory P. Smith](mailto:greg@krypto.org)
|
||||
- Gustavo Camargo
|
||||
- hauntsaninja
|
||||
- [Hadi Alqattan](mailto:alqattanhadizaki@gmail.com)
|
||||
- [Hassan Abouelela](mailto:hassan@hassanamr.com)
|
||||
- [Heaford](mailto:dan@heaford.com)
|
||||
- [Hugo Barrera](mailto::hugo@barrera.io)
|
||||
- Hugo van Kemenade
|
||||
- [Hynek Schlawack](mailto:hs@ox.cx)
|
||||
- [Ionite](mailto:dev@ionite.io)
|
||||
- [Ivan Katanić](mailto:ivan.katanic@gmail.com)
|
||||
- [Jakub Kadlubiec](mailto:jakub.kadlubiec@skyscanner.net)
|
||||
- [Jakub Warczarek](mailto:jakub.warczarek@gmail.com)
|
||||
- [Jan Hnátek](mailto:jan.hnatek@gmail.com)
|
||||
- [Jason Fried](mailto:me@jasonfried.info)
|
||||
- [Jason Friedland](mailto:jason@friedland.id.au)
|
||||
- [jgirardet](mailto:ijkl@netc.fr)
|
||||
- Jim Brännlund
|
||||
- [Jimmy Jia](mailto:tesrin@gmail.com)
|
||||
- [Joe Antonakakis](mailto:jma353@cornell.edu)
|
||||
- [Jon Dufresne](mailto:jon.dufresne@gmail.com)
|
||||
- [Jonas Obrist](mailto:ojiidotch@gmail.com)
|
||||
- [Jonty Wareing](mailto:jonty@jonty.co.uk)
|
||||
- [Jose Nazario](mailto:jose.monkey.org@gmail.com)
|
||||
- [Joseph Larson](mailto:larson.joseph@gmail.com)
|
||||
- [Josh Bode](mailto:joshbode@fastmail.com)
|
||||
- [Josh Holland](mailto:anowlcalledjosh@gmail.com)
|
||||
- [Joshua Cannon](mailto:joshdcannon@gmail.com)
|
||||
- [José Padilla](mailto:jpadilla@webapplicate.com)
|
||||
- [Juan Luis Cano Rodríguez](mailto:hello@juanlu.space)
|
||||
- [kaiix](mailto:kvn.hou@gmail.com)
|
||||
- [Katie McLaughlin](mailto:katie@glasnt.com)
|
||||
- Katrin Leinweber
|
||||
- [Keith Smiley](mailto:keithbsmiley@gmail.com)
|
||||
- [Kenyon Ralph](mailto:kenyon@kenyonralph.com)
|
||||
- [Kevin Kirsche](mailto:Kev.Kirsche+GitHub@gmail.com)
|
||||
- [Kyle Hausmann](mailto:kyle.hausmann@gmail.com)
|
||||
- [Kyle Sunden](mailto:sunden@wisc.edu)
|
||||
- Lawrence Chan
|
||||
- [Linus Groh](mailto:mail@linusgroh.de)
|
||||
- [Loren Carvalho](mailto:comradeloren@gmail.com)
|
||||
- [Luka Sterbic](mailto:luka.sterbic@gmail.com)
|
||||
- [LukasDrude](mailto:mail@lukas-drude.de)
|
||||
- Mahmoud Hossam
|
||||
- Mariatta
|
||||
- [Matt VanEseltine](mailto:vaneseltine@gmail.com)
|
||||
- [Matthew Clapp](mailto:itsayellow+dev@gmail.com)
|
||||
- [Matthew Walster](mailto:matthew@walster.org)
|
||||
- Max Smolens
|
||||
- [Michael Aquilina](mailto:michaelaquilina@gmail.com)
|
||||
- [Michael Flaxman](mailto:michael.flaxman@gmail.com)
|
||||
- [Michael J. Sullivan](mailto:sully@msully.net)
|
||||
- [Michael McClimon](mailto:michael@mcclimon.org)
|
||||
- [Miguel Gaiowski](mailto:miggaiowski@gmail.com)
|
||||
- [Mike](mailto:roshi@fedoraproject.org)
|
||||
- [mikehoyio](mailto:mikehoy@gmail.com)
|
||||
- [Min ho Kim](mailto:minho42@gmail.com)
|
||||
- [Miroslav Shubernetskiy](mailto:miroslav@miki725.com)
|
||||
- MomIsBestFriend
|
||||
- [Nathan Goldbaum](mailto:ngoldbau@illinois.edu)
|
||||
- [Nathan Hunt](mailto:neighthan.hunt@gmail.com)
|
||||
- [Neraste](mailto:neraste.herr10@gmail.com)
|
||||
- [Nikolaus Waxweiler](mailto:madigens@gmail.com)
|
||||
- [Ofek Lev](mailto:ofekmeister@gmail.com)
|
||||
- [Osaetin Daniel](mailto:osaetindaniel@gmail.com)
|
||||
- [otstrel](mailto:otstrel@gmail.com)
|
||||
- [Pablo Galindo](mailto:Pablogsal@gmail.com)
|
||||
- [Paul Ganssle](mailto:p.ganssle@gmail.com)
|
||||
- [Paul Meinhardt](mailto:mnhrdt@gmail.com)
|
||||
- [Peter Bengtsson](mailto:mail@peterbe.com)
|
||||
- [Peter Grayson](mailto:pete@jpgrayson.net)
|
||||
- [Peter Stensmyr](mailto:peter.stensmyr@gmail.com)
|
||||
- pmacosta
|
||||
- [Quentin Pradet](mailto:quentin@pradet.me)
|
||||
- [Ralf Schmitt](mailto:ralf@systemexit.de)
|
||||
- [Ramón Valles](mailto:mroutis@protonmail.com)
|
||||
- [Richard Fearn](mailto:richardfearn@gmail.com)
|
||||
- [Rishikesh Jha](mailto:rishijha424@gmail.com)
|
||||
- [Rupert Bedford](mailto:rupert@rupertb.com)
|
||||
- Russell Davis
|
||||
- [Sagi Shadur](mailto:saroad2@gmail.com)
|
||||
- [Rémi Verschelde](mailto:rverschelde@gmail.com)
|
||||
- [Sami Salonen](mailto:sakki@iki.fi)
|
||||
- [Samuel Cormier-Iijima](mailto:samuel@cormier-iijima.com)
|
||||
- [Sanket Dasgupta](mailto:sanketdasgupta@gmail.com)
|
||||
- Sergi
|
||||
- [Scott Stevenson](mailto:scott@stevenson.io)
|
||||
- Shantanu
|
||||
- [shaoran](mailto:shaoran@sakuranohana.org)
|
||||
- [Shinya Fujino](mailto:shf0811@gmail.com)
|
||||
- springstan
|
||||
- [Stavros Korokithakis](mailto:hi@stavros.io)
|
||||
- [Stephen Rosen](mailto:sirosen@globus.org)
|
||||
- [Steven M. Vascellaro](mailto:S.Vascellaro@gmail.com)
|
||||
- [Sunil Kapil](mailto:snlkapil@gmail.com)
|
||||
- [Sébastien Eustace](mailto:sebastien.eustace@gmail.com)
|
||||
- [Tal Amuyal](mailto:TalAmuyal@gmail.com)
|
||||
- [Terrance](mailto:git@terrance.allofti.me)
|
||||
- [Thom Lu](mailto:thomas.c.lu@gmail.com)
|
||||
- [Thomas Grainger](mailto:tagrain@gmail.com)
|
||||
- [Tim Gates](mailto:tim.gates@iress.com)
|
||||
- [Tim Swast](mailto:swast@google.com)
|
||||
- [Timo](mailto:timo_tk@hotmail.com)
|
||||
- Toby Fleming
|
||||
- [Tom Christie](mailto:tom@tomchristie.com)
|
||||
- [Tony Narlock](mailto:tony@git-pull.com)
|
||||
- [Tsuyoshi Hombashi](mailto:tsuyoshi.hombashi@gmail.com)
|
||||
- [Tushar Chandra](mailto:tusharchandra2018@u.northwestern.edu)
|
||||
- [Tushar Sadhwani](mailto:tushar.sadhwani000@gmail.com)
|
||||
- [Tzu-ping Chung](mailto:uranusjr@gmail.com)
|
||||
- [Utsav Shah](mailto:ukshah2@illinois.edu)
|
||||
- utsav-dbx
|
||||
- vezeli
|
||||
- [Ville Skyttä](mailto:ville.skytta@iki.fi)
|
||||
- [Vishwas B Sharma](mailto:sharma.vishwas88@gmail.com)
|
||||
- [Vlad Emelianov](mailto:volshebnyi@gmail.com)
|
||||
- [williamfzc](mailto:178894043@qq.com)
|
||||
- [wouter bolsterlee](mailto:wouter@bolsterl.ee)
|
||||
- Yazdan
|
||||
- [Yngve Høiseth](mailto:yngve@hoiseth.net)
|
||||
- [Yurii Karabas](mailto:1998uriyyo@gmail.com)
|
||||
- [Zac Hatfield-Dodds](mailto:zac@zhd.dev)
|
1470
CHANGES.md
1470
CHANGES.md
File diff suppressed because it is too large
Load Diff
22
CITATION.cff
22
CITATION.cff
@ -1,22 +0,0 @@
|
||||
cff-version: 1.2.0
|
||||
title: "Black: The uncompromising Python code formatter"
|
||||
message: >-
|
||||
If you use this software, please cite it using the metadata from this file.
|
||||
type: software
|
||||
authors:
|
||||
- family-names: Langa
|
||||
given-names: Łukasz
|
||||
- name: "contributors to Black"
|
||||
repository-code: "https://github.com/psf/black"
|
||||
url: "https://black.readthedocs.io/en/stable/"
|
||||
abstract: >-
|
||||
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.
|
||||
license: MIT
|
119
CONTRIBUTING.md
119
CONTRIBUTING.md
@ -1,13 +1,116 @@
|
||||
# Contributing to _Black_
|
||||
|
||||
Welcome future contributor! We're happy to see you willing to make the project better.
|
||||
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?
|
||||
|
||||
If you aren't familiar with _Black_, or are looking for documentation on something
|
||||
specific, the [user documentation](https://black.readthedocs.io/en/latest/) is the best
|
||||
place to look.
|
||||
## Bird's eye view
|
||||
|
||||
For getting started on contributing, please read the
|
||||
[contributing documentation](https://black.readthedocs.org/en/latest/contributing/) for
|
||||
all you need to know.
|
||||
In terms of inspiration, _Black_ is about as configurable as _gofmt_. This is
|
||||
deliberate.
|
||||
|
||||
Thank you, and we look forward to your contributions!
|
||||
Bug reports and fixes are always welcome! Please follow the
|
||||
[issue template on GitHub](https://github.com/psf/black/issues/new) 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.
|
||||
|
||||
## Technicalities
|
||||
|
||||
Development on the latest version of Python is preferred. As of this writing it's 3.9.
|
||||
You can use any operating system. I am using macOS myself and CentOS at work.
|
||||
|
||||
Install all development dependencies using:
|
||||
|
||||
```console
|
||||
$ pipenv install --dev
|
||||
$ pipenv shell
|
||||
$ pre-commit install
|
||||
```
|
||||
|
||||
If you haven't used `pipenv` before but are comfortable with virtualenvs, just run
|
||||
`pip install pipenv` in the virtualenv you're already using and invoke the command above
|
||||
from the cloned _Black_ repo. It will do the correct thing.
|
||||
|
||||
Non pipenv install works too:
|
||||
|
||||
```console
|
||||
$ pip install -r test_requirements
|
||||
$ pip install -e .[d]
|
||||
```
|
||||
|
||||
Before submitting pull requests, run lints and tests with the following commands from
|
||||
the root of the black repo:
|
||||
|
||||
```console
|
||||
# Linting
|
||||
$ pre-commit run -a
|
||||
|
||||
# Unit tests
|
||||
$ tox -e py
|
||||
|
||||
# Optional Fuzz testing
|
||||
$ tox -e fuzz
|
||||
|
||||
# Optional CI run to test your changes on many popular python projects
|
||||
$ black-primer [-k -w /tmp/black_test_repos]
|
||||
```
|
||||
|
||||
### News / Changelog Requirement
|
||||
|
||||
`Black` has CI that will check for an entry corresponding to your PR in `CHANGES.md`. If
|
||||
you feel this PR not require a changelog entry please state that in a comment and a
|
||||
maintainer can add a `skip news` label to make the CI pass. Otherwise, please ensure you
|
||||
have a line in the following format:
|
||||
|
||||
```md
|
||||
- `Black` is now more awesome (#X)
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
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 though.
|
||||
|
||||
### Docs Testing
|
||||
|
||||
If you make changes to docs, you can test they still build locally too.
|
||||
|
||||
```console
|
||||
$ pip install -r docs/requirements.txt
|
||||
$ pip install [-e] .[d]
|
||||
$ sphinx-build -a -b html -W docs/ docs/_build/
|
||||
```
|
||||
|
||||
## black-primer
|
||||
|
||||
`black-primer` is used by CI to pull down well-known _Black_ formatted projects and see
|
||||
if we get source code changes. It will error on formatting changes or errors. Please run
|
||||
before pushing your PR to see if you get the actions you would expect from _Black_ with
|
||||
your PR. You may need to change
|
||||
[primer.json](https://github.com/psf/black/blob/master/src/black_primer/primer.json)
|
||||
configuration for it to pass.
|
||||
|
||||
For more `black-primer` information visit the
|
||||
[documentation](https://github.com/psf/black/blob/master/docs/black_primer.md).
|
||||
|
||||
## Hygiene
|
||||
|
||||
If you're fixing a bug, add a test. Run it first to confirm it fails, then fix the bug,
|
||||
run it again to confirm it's really fixed.
|
||||
|
||||
If adding a new feature, add a test. In fact, always add a test. But wait, before adding
|
||||
any large feature, first open an issue for us to discuss the idea first.
|
||||
|
||||
## Finally
|
||||
|
||||
Thanks again for your interest in improving the project! You're taking action when most
|
||||
people decide to sit and watch.
|
||||
|
28
Dockerfile
28
Dockerfile
@ -1,22 +1,14 @@
|
||||
FROM python:3.12-slim AS builder
|
||||
FROM python:3-slim
|
||||
|
||||
RUN mkdir /src
|
||||
COPY . /src/
|
||||
ENV VIRTUAL_ENV=/opt/venv
|
||||
ENV HATCH_BUILD_HOOKS_ENABLE=1
|
||||
# Install build tools to compile black + dependencies
|
||||
RUN apt update && apt install -y build-essential git python3-dev
|
||||
RUN python -m venv $VIRTUAL_ENV
|
||||
RUN python -m pip install --no-cache-dir hatch hatch-fancy-pypi-readme hatch-vcs
|
||||
RUN . /opt/venv/bin/activate && pip install --no-cache-dir --upgrade pip setuptools \
|
||||
&& cd /src && hatch build -t wheel \
|
||||
&& pip install --no-cache-dir dist/*-cp* \
|
||||
&& pip install black[colorama,d,uvloop]
|
||||
RUN pip install --no-cache-dir --upgrade pip setuptools wheel \
|
||||
&& apt update && apt install -y git \
|
||||
&& cd /src \
|
||||
&& pip install --no-cache-dir .[colorama,d] \
|
||||
&& rm -rf /src \
|
||||
&& apt remove -y git \
|
||||
&& apt autoremove -y \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
FROM python:3.12-slim
|
||||
|
||||
# copy only Python packages to limit the image size
|
||||
COPY --from=builder /opt/venv /opt/venv
|
||||
ENV PATH="/opt/venv/bin:$PATH"
|
||||
|
||||
CMD ["/opt/venv/bin/black"]
|
||||
CMD ["black"]
|
||||
|
34
Pipfile
Normal file
34
Pipfile
Normal file
@ -0,0 +1,34 @@
|
||||
[[source]]
|
||||
name = "pypi"
|
||||
url = "https://pypi.python.org/simple"
|
||||
verify_ssl = true
|
||||
|
||||
[dev-packages]
|
||||
Sphinx = ">=3.1.2"
|
||||
coverage = "*"
|
||||
docutils = "==0.15" # not a direct dependency, see https://github.com/pypa/pipenv/issues/3865
|
||||
flake8 = "*"
|
||||
flake8-bugbear = "*"
|
||||
mypy = ">=0.812"
|
||||
pre-commit = "*"
|
||||
readme_renderer = "*"
|
||||
recommonmark = "*"
|
||||
setuptools = ">=39.2.0"
|
||||
setuptools-scm = "*"
|
||||
twine = ">=1.11.0"
|
||||
wheel = ">=0.31.1"
|
||||
black = {editable = true, extras = ["d"], path = "."}
|
||||
|
||||
[packages]
|
||||
aiohttp = ">=3.3.2"
|
||||
aiohttp-cors = "*"
|
||||
appdirs = "*"
|
||||
click = ">=7.1.2"
|
||||
mypy_extensions = ">=0.4.3"
|
||||
pathspec = ">=0.8.1"
|
||||
regex = ">=2020.1.8"
|
||||
toml = ">=0.10.1"
|
||||
typed-ast = "==1.4.2"
|
||||
typing_extensions = {"python_version <" = "3.8","version >=" = "3.7.4"}
|
||||
black = {editable = true,extras = ["d"],path = "."}
|
||||
dataclasses = {"python_version <" = "3.7","version >" = "0.6"}
|
1217
Pipfile.lock
generated
Normal file
1217
Pipfile.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
663
README.md
663
README.md
@ -1,14 +1,15 @@
|
||||
[](https://black.readthedocs.io/en/stable/)
|
||||

|
||||
|
||||
<h2 align="center">The Uncompromising Code Formatter</h2>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/psf/black/actions"><img alt="Actions Status" src="https://github.com/psf/black/workflows/Test/badge.svg"></a>
|
||||
<a href="https://github.com/psf/black/actions"><img alt="Actions Status" src="https://github.com/psf/black/workflows/Primer/badge.svg"></a>
|
||||
<a href="https://black.readthedocs.io/en/stable/?badge=stable"><img alt="Documentation Status" src="https://readthedocs.org/projects/black/badge/?version=stable"></a>
|
||||
<a href="https://coveralls.io/github/psf/black?branch=main"><img alt="Coverage Status" src="https://coveralls.io/repos/github/psf/black/badge.svg?branch=main"></a>
|
||||
<a href="https://github.com/psf/black/blob/main/LICENSE"><img alt="License: MIT" src="https://black.readthedocs.io/en/stable/_static/license.svg"></a>
|
||||
<a href="https://coveralls.io/github/psf/black?branch=master"><img alt="Coverage Status" src="https://coveralls.io/repos/github/psf/black/badge.svg?branch=master"></a>
|
||||
<a href="https://github.com/psf/black/blob/master/LICENSE"><img alt="License: MIT" src="https://black.readthedocs.io/en/stable/_static/license.svg"></a>
|
||||
<a href="https://pypi.org/project/black/"><img alt="PyPI" src="https://img.shields.io/pypi/v/black"></a>
|
||||
<a href="https://pepy.tech/project/black"><img alt="Downloads" src="https://static.pepy.tech/badge/black"></a>
|
||||
<a href="https://pepy.tech/project/black"><img alt="Downloads" src="https://pepy.tech/badge/black"></a>
|
||||
<a href="https://anaconda.org/conda-forge/black/"><img alt="conda-forge" src="https://img.shields.io/conda/dn/conda-forge/black.svg?label=conda-forge"></a>
|
||||
<a href="https://github.com/psf/black"><img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg"></a>
|
||||
</p>
|
||||
@ -25,12 +26,21 @@ becomes transparent after a while and you can focus on the content instead.
|
||||
|
||||
_Black_ makes code review faster by producing the smallest diffs possible.
|
||||
|
||||
Try it out now using the [Black Playground](https://black.vercel.app). Watch the
|
||||
Try it out now using the [Black Playground](https://black.now.sh). Watch the
|
||||
[PyCon 2019 talk](https://youtu.be/esZLCuWs_2Y) to learn more.
|
||||
|
||||
---
|
||||
|
||||
**[Read the documentation on ReadTheDocs!](https://black.readthedocs.io/en/stable)**
|
||||
_Contents:_ **[Installation and usage](#installation-and-usage)** |
|
||||
**[Code style](#the-black-code-style)** | **[Pragmatism](#pragmatism)** |
|
||||
**[pyproject.toml](#pyprojecttoml)** | **[Editor integration](#editor-integration)** |
|
||||
**[blackd](#blackd)** | **[black-primer](#black-primer)** |
|
||||
**[Version control integration](#version-control-integration)** |
|
||||
**[GitHub Actions](#github-actions)** |
|
||||
**[Ignoring unmodified files](#ignoring-unmodified-files)** | **[Used by](#used-by)** |
|
||||
**[Testimonials](#testimonials)** | **[Show your style](#show-your-style)** |
|
||||
**[Contributing](#contributing-to-black)** | **[Change log](#change-log)** |
|
||||
**[Authors](#authors)**
|
||||
|
||||
---
|
||||
|
||||
@ -38,12 +48,15 @@ Try it out now using the [Black Playground](https://black.vercel.app). Watch the
|
||||
|
||||
### Installation
|
||||
|
||||
_Black_ can be installed by running `pip install black`. It requires Python 3.9+ to run.
|
||||
If you want to format Jupyter Notebooks, install with `pip install "black[jupyter]"`.
|
||||
_Black_ can be installed by running `pip install black`. It requires Python 3.6.2+ to
|
||||
run. If you want to format Python 2 code as well, install with
|
||||
`pip install black[python2]`.
|
||||
|
||||
#### Install from GitHub
|
||||
|
||||
If you can't wait for the latest _hotness_ and want to install from GitHub, use:
|
||||
|
||||
`pip install git+https://github.com/psf/black`
|
||||
`pip install git+git://github.com/psf/black`
|
||||
|
||||
### Usage
|
||||
|
||||
@ -59,98 +72,404 @@ You can run _Black_ as a package if running it as a script doesn't work:
|
||||
python -m black {source_file_or_directory}
|
||||
```
|
||||
|
||||
Further information can be found in our docs:
|
||||
### Command line options
|
||||
|
||||
- [Usage and Configuration](https://black.readthedocs.io/en/stable/usage_and_configuration/index.html)
|
||||
_Black_ doesn't provide many options. You can list them by running `black --help`:
|
||||
|
||||
```text
|
||||
Usage: black [OPTIONS] [SRC]...
|
||||
|
||||
The uncompromising code formatter.
|
||||
|
||||
Options:
|
||||
-c, --code TEXT Format the code passed in as a string.
|
||||
-l, --line-length INTEGER How many characters per line to allow.
|
||||
[default: 88]
|
||||
|
||||
-t, --target-version [py27|py33|py34|py35|py36|py37|py38|py39]
|
||||
Python versions that should be supported by
|
||||
Black's output. [default: per-file auto-
|
||||
detection]
|
||||
|
||||
--pyi Format all input files like typing stubs
|
||||
regardless of file extension (useful when
|
||||
piping source on standard input).
|
||||
|
||||
-S, --skip-string-normalization
|
||||
Don't normalize string quotes or prefixes.
|
||||
-C, --skip-magic-trailing-comma
|
||||
Don't use trailing commas as a reason to
|
||||
split lines.
|
||||
|
||||
--check Don't write the files back, just return the
|
||||
status. Return code 0 means nothing would
|
||||
change. Return code 1 means some files
|
||||
would be reformatted. Return code 123 means
|
||||
there was an internal error.
|
||||
|
||||
--diff Don't write the files back, just output a
|
||||
diff for each file on stdout.
|
||||
|
||||
--color / --no-color Show colored diff. Only applies when
|
||||
`--diff` is given.
|
||||
|
||||
--fast / --safe If --fast given, skip temporary sanity
|
||||
checks. [default: --safe]
|
||||
|
||||
--include TEXT A regular expression that matches files and
|
||||
directories that should be included on
|
||||
recursive searches. An empty value means
|
||||
all files are included regardless of the
|
||||
name. Use forward slashes for directories
|
||||
on all platforms (Windows, too). Exclusions
|
||||
are calculated first, inclusions later.
|
||||
[default: \.pyi?$]
|
||||
|
||||
--exclude TEXT A regular expression that matches files and
|
||||
directories that should be excluded on
|
||||
recursive searches. An empty value means no
|
||||
paths are excluded. Use forward slashes for
|
||||
directories on all platforms (Windows, too).
|
||||
Exclusions are calculated first, inclusions
|
||||
later. [default: /(\.direnv|\.eggs|\.git|\.
|
||||
hg|\.mypy_cache|\.nox|\.tox|\.venv|venv|\.sv
|
||||
n|_build|buck-out|build|dist)/]
|
||||
|
||||
--extend-exclude TEXT Like --exclude, but adds additional files
|
||||
and directories on top of the excluded
|
||||
ones (useful if you simply want to add to
|
||||
the default).
|
||||
|
||||
--force-exclude TEXT Like --exclude, but files and directories
|
||||
matching this regex will be excluded even
|
||||
when they are passed explicitly as
|
||||
arguments.
|
||||
|
||||
|
||||
--stdin-filename TEXT The name of the file when passing it through
|
||||
stdin. Useful to make sure Black will
|
||||
respect --force-exclude option on some
|
||||
editors that rely on using stdin.
|
||||
|
||||
-q, --quiet Don't emit non-error messages to stderr.
|
||||
Errors are still emitted; silence those with
|
||||
2>/dev/null.
|
||||
|
||||
-v, --verbose Also emit messages to stderr about files
|
||||
that were not changed or were ignored due to
|
||||
exclusion patterns.
|
||||
|
||||
--version Show the version and exit.
|
||||
--config FILE Read configuration from FILE path.
|
||||
-h, --help Show this message and exit.
|
||||
```
|
||||
|
||||
_Black_ is a well-behaved Unix-style command-line tool:
|
||||
|
||||
- it does nothing if no sources are passed to it;
|
||||
- it will read from standard input and write to standard output if `-` is used as the
|
||||
filename;
|
||||
- it only outputs messages to users on standard error;
|
||||
- exits with code 0 unless an internal error occurred (or `--check` was used).
|
||||
|
||||
### Using _Black_ with other tools
|
||||
|
||||
While _Black_ enforces formatting that conforms to PEP 8, other tools may raise warnings
|
||||
about _Black_'s changes or will overwrite _Black_'s changes. A good example of this is
|
||||
[isort](https://pypi.org/p/isort). Since _Black_ is barely configurable, these tools
|
||||
should be configured to neither warn about nor overwrite _Black_'s changes.
|
||||
|
||||
Actual details on _Black_ compatible configurations for various tools can be found in
|
||||
[compatible_configs](https://github.com/psf/black/blob/master/docs/compatible_configs.md#black-compatible-configurations).
|
||||
|
||||
### Migrating your code style without 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.
|
||||
|
||||
```
|
||||
# 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 GitHub and GitLab do not yet support ignoring revisions using
|
||||
their native UI of blame.** So blame information will be cluttered with a reformatting
|
||||
commit on those platforms. (If you'd like this feature, there's an open issue for
|
||||
[GitLab](https://gitlab.com/gitlab-org/gitlab/-/issues/31423) and please let GitHub
|
||||
know!)
|
||||
|
||||
### NOTE: This is a beta product
|
||||
|
||||
_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).
|
||||
projects, small and big. It also sports a decent test suite. However, it is still very
|
||||
new. Things will probably be wonky for a while. This is made explicit by the "Beta"
|
||||
trove classifier, as well as by the "b" in the version number. What this means for you
|
||||
is that **until the formatter becomes stable, you should expect some formatting to
|
||||
change in the future**. That being said, no drastic stylistic changes are planned,
|
||||
mostly responses to bug reports.
|
||||
|
||||
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)
|
||||
[Pragmatism](https://github.com/psf/black/blob/master/docs/the_black_code_style.md#pragmatism)
|
||||
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)
|
||||
place. It is not configurable. It doesn't take previous formatting into account. Your
|
||||
main option of configuring _Black_ is that it doesn't reformat blocks that start with
|
||||
`# fmt: off` and end with `# fmt: on`, or lines that ends with `# fmt: skip`. Pay
|
||||
attention that `# fmt: on/off` have to be on the same level of indentation. To learn
|
||||
more about _Black_'s opinions, to go
|
||||
[the_black_code_style](https://github.com/psf/black/blob/master/docs/the_black_code_style.md).
|
||||
|
||||
Please refer to this document before submitting an issue. What seems like a bug might be
|
||||
intended behaviour.
|
||||
|
||||
### Pragmatism
|
||||
## 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)
|
||||
_Black_ does make some exceptions to rules it otherwise holds. This
|
||||
[section](https://github.com/psf/black/blob/master/docs/the_black_code_style.md#pragmatism)
|
||||
of `the_black_code_style` describes what those exceptions are and why this is the case.
|
||||
|
||||
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
|
||||
## pyproject.toml
|
||||
|
||||
_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)
|
||||
`--include` and `--exclude`/`--extend-exclude` patterns for your project.
|
||||
|
||||
**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.
|
||||
"No". _Black_ is all about sensible defaults.
|
||||
|
||||
### What on Earth is a `pyproject.toml` file?
|
||||
|
||||
[PEP 518](https://www.python.org/dev/peps/pep-0518/) defines `pyproject.toml` as a
|
||||
configuration file to store build system requirements for Python projects. With the help
|
||||
of tools like [Poetry](https://python-poetry.org/) or
|
||||
[Flit](https://flit.readthedocs.io/en/latest/) it can fully replace the need for
|
||||
`setup.py` and `setup.cfg` files.
|
||||
|
||||
### Where _Black_ looks for the file
|
||||
|
||||
By default _Black_ looks for `pyproject.toml` starting from the common base directory of
|
||||
all files and directories passed on the command line. If it's not there, it looks in
|
||||
parent directories. It stops looking when it finds the file, or a `.git` directory, or a
|
||||
`.hg` directory, or the root of the file system, whichever comes first.
|
||||
|
||||
If you're formatting standard input, _Black_ will look for configuration starting from
|
||||
the current working directory.
|
||||
|
||||
You can use a "global" configuration, stored in a specific location in your home
|
||||
directory. This will be used as a fallback configuration, that is, it will be used if
|
||||
and only if _Black_ doesn't find any configuration as mentioned above. Depending on your
|
||||
operating system, this configuration file should be stored as:
|
||||
|
||||
- Windows: `~\.black`
|
||||
- Unix-like (Linux, MacOS, etc.): `$XDG_CONFIG_HOME/black` (`~/.config/black` if the
|
||||
`XDG_CONFIG_HOME` environment variable is not set)
|
||||
|
||||
Note that these are paths to the TOML file itself (meaning that they shouldn't be named
|
||||
as `pyproject.toml`), not directories where you store the configuration. Here, `~`
|
||||
refers to the path to your home directory. On Windows, this will be something like
|
||||
`C:\\Users\UserName`.
|
||||
|
||||
You can also explicitly specify the path to a particular file that you want with
|
||||
`--config`. In this situation _Black_ will not look for any other file.
|
||||
|
||||
If you're running with `--verbose`, you will see a blue message if a file was found and
|
||||
used.
|
||||
|
||||
Please note `blackd` will not use `pyproject.toml` configuration.
|
||||
|
||||
### Configuration format
|
||||
|
||||
As the file extension suggests, `pyproject.toml` is a
|
||||
[TOML](https://github.com/toml-lang/toml) file. It contains separate sections for
|
||||
different tools. _Black_ is using the `[tool.black]` section. The option keys are the
|
||||
same as long names of options on the command line.
|
||||
|
||||
Note that you have to use single-quoted strings in TOML for regular expressions. It's
|
||||
the equivalent of r-strings in Python. Multiline strings are treated as verbose regular
|
||||
expressions by Black. Use `[ ]` to denote a significant space character.
|
||||
|
||||
<details>
|
||||
<summary>Example <code>pyproject.toml</code></summary>
|
||||
|
||||
```toml
|
||||
[tool.black]
|
||||
line-length = 88
|
||||
target-version = ['py37']
|
||||
include = '\.pyi?$'
|
||||
extend-exclude = '''
|
||||
# A regex preceded with ^/ will apply only to files and directories
|
||||
# in the root of the project.
|
||||
^/foo.py # exclude a file named foo.py in the root of the project (in addition to the defaults)
|
||||
'''
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Lookup hierarchy
|
||||
|
||||
Command-line options have defaults that you can see in `--help`. A `pyproject.toml` can
|
||||
override those defaults. Finally, options provided by the user on the command line
|
||||
override both.
|
||||
|
||||
_Black_ will only ever use one `pyproject.toml` file during an entire run. It doesn't
|
||||
look for multiple files, and doesn't compose configuration from different levels of the
|
||||
file hierarchy.
|
||||
|
||||
## Editor integration
|
||||
|
||||
_Black_ can be integrated into many editors with plugins. They let you run _Black_ on
|
||||
your code with the ease of doing it in your editor. To get started using _Black_ in your
|
||||
editor of choice, please see
|
||||
[editor_integration](https://github.com/psf/black/blob/master/docs/editor_integration.md).
|
||||
|
||||
Patches are welcome for editors without an editor integration or plugin! More
|
||||
information can be found in
|
||||
[editor_integration](https://github.com/psf/black/blob/master/docs/editor_integration.md#other-editors).
|
||||
|
||||
## blackd
|
||||
|
||||
`blackd` is a small HTTP server that exposes Black's functionality over a simple
|
||||
protocol. The main benefit of using it is to avoid paying the cost of starting up a new
|
||||
Black process every time you want to blacken a file. Please refer to
|
||||
[blackd](https://github.com/psf/black/blob/master/docs/blackd.md) to get the ball
|
||||
rolling.
|
||||
|
||||
## black-primer
|
||||
|
||||
`black-primer` is a tool built for CI (and humans) to have _Black_ `--check` a number of
|
||||
(configured in `primer.json`) Git accessible projects in parallel.
|
||||
[black_primer](https://github.com/psf/black/blob/master/docs/black_primer.md) has more
|
||||
information regarding its usage and configuration.
|
||||
|
||||
(A PR adding Mercurial support will be accepted.)
|
||||
|
||||
## Version control integration
|
||||
|
||||
Use [pre-commit](https://pre-commit.com/). Once you
|
||||
[have it installed](https://pre-commit.com/#install), add this to the
|
||||
`.pre-commit-config.yaml` in your repository:
|
||||
|
||||
```yaml
|
||||
repos:
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 20.8b1 # Replace by any tag/version: https://github.com/psf/black/tags
|
||||
hooks:
|
||||
- id: black
|
||||
language_version: python3 # Should be a command that runs python3.6+
|
||||
```
|
||||
|
||||
Then run `pre-commit install` and you're ready to go.
|
||||
|
||||
Avoid using `args` in the hook. Instead, store necessary configuration in
|
||||
`pyproject.toml` so that editors and command-line usage of Black all behave consistently
|
||||
for your project. See _Black_'s own
|
||||
[pyproject.toml](https://github.com/psf/black/blob/master/pyproject.toml) for an
|
||||
example.
|
||||
|
||||
If you're already using Python 3.7, switch the `language_version` accordingly. Finally,
|
||||
`stable` is a branch that tracks the latest release on PyPI. If you'd rather run on
|
||||
master, this is also an option.
|
||||
|
||||
## GitHub Actions
|
||||
|
||||
Create a file named `.github/workflows/black.yml` inside your repository with:
|
||||
|
||||
```yaml
|
||||
name: Lint
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: psf/black@stable
|
||||
with:
|
||||
args: ". --check"
|
||||
```
|
||||
|
||||
### Inputs
|
||||
|
||||
#### `black_args`
|
||||
|
||||
**optional**: Black input arguments. Defaults to `. --check --diff`.
|
||||
|
||||
## Ignoring unmodified files
|
||||
|
||||
_Black_ remembers files it has already formatted, unless the `--diff` flag is used or
|
||||
code is passed via standard input. This information is stored per-user. The exact
|
||||
location of the file depends on the _Black_ version and the system on which _Black_ is
|
||||
run. The file is non-portable. The standard location on common operating systems is:
|
||||
|
||||
- Windows:
|
||||
`C:\\Users\<username>\AppData\Local\black\black\Cache\<version>\cache.<line-length>.<file-mode>.pickle`
|
||||
- macOS:
|
||||
`/Users/<username>/Library/Caches/black/<version>/cache.<line-length>.<file-mode>.pickle`
|
||||
- Linux:
|
||||
`/home/<username>/.cache/black/<version>/cache.<line-length>.<file-mode>.pickle`
|
||||
|
||||
`file-mode` is an int flag that determines whether the file was formatted as 3.6+ only,
|
||||
as .pyi, and whether string normalization was omitted.
|
||||
|
||||
To override the location of these files on macOS or Linux, set the environment variable
|
||||
`XDG_CACHE_HOME` to your preferred location. For example, if you want to put the cache
|
||||
in the directory you're running _Black_ from, set `XDG_CACHE_HOME=.cache`. _Black_ will
|
||||
then write the above files to `.cache/black/<version>/`.
|
||||
|
||||
## 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.
|
||||
code style: pytest, tox, Pyramid, Django Channels, Hypothesis, attrs, SQLAlchemy,
|
||||
Poetry, PyPA applications (Warehouse, Bandersnatch, Pipenv, virtualenv), pandas, Pillow,
|
||||
every Datadog Agent Integration, Home Assistant, Zulip.
|
||||
|
||||
The following organizations use _Black_: Dropbox, KeepTruckin, Lyft, Mozilla, Quora,
|
||||
Duolingo, QuantumBlack, Tesla, Archer Aviation.
|
||||
The following organizations use _Black_: Facebook, Dropbox, Mozilla, Quora.
|
||||
|
||||
Are we missing anyone? Let us know.
|
||||
|
||||
## Testimonials
|
||||
|
||||
**Mike Bayer**, [author 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://smile.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Daps&field-keywords=dusty+phillips):
|
||||
|
||||
@ -165,8 +484,8 @@ Twisted and CPython:
|
||||
|
||||
> At least the name is good.
|
||||
|
||||
**Kenneth Reitz**, creator of [`requests`](https://requests.readthedocs.io/en/latest/)
|
||||
and [`pipenv`](https://readthedocs.org/projects/pipenv/):
|
||||
**Kenneth Reitz**, creator of [`requests`](http://python-requests.org/) and
|
||||
[`pipenv`](https://readthedocs.org/projects/pipenv/):
|
||||
|
||||
> This vastly improves the formatting of our code. Thanks a ton!
|
||||
|
||||
@ -192,39 +511,209 @@ Looks like this:
|
||||
|
||||
MIT
|
||||
|
||||
## Contributing
|
||||
## Contributing to _Black_
|
||||
|
||||
Welcome! Happy to see you willing to make the project better. You can get started by
|
||||
reading this:
|
||||
In terms of inspiration, _Black_ is about as configurable as _gofmt_. This is
|
||||
deliberate.
|
||||
|
||||
- [Contributing: The basics](https://black.readthedocs.io/en/latest/contributing/the_basics.html)
|
||||
Bug reports and fixes are always welcome! However, 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.
|
||||
|
||||
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)
|
||||
More details can be found in
|
||||
[CONTRIBUTING](https://github.com/psf/black/blob/master/CONTRIBUTING.md).
|
||||
|
||||
## Change log
|
||||
|
||||
The log has become rather long. It moved to its own file.
|
||||
The log's become rather long. It moved to its own file.
|
||||
|
||||
See [CHANGES](https://black.readthedocs.io/en/latest/change_log.html).
|
||||
See [CHANGES](https://github.com/psf/black/blob/master/CHANGES.md).
|
||||
|
||||
## Authors
|
||||
|
||||
The author list is quite long nowadays, so it lives in its own file.
|
||||
Glued together by [Łukasz Langa](mailto:lukasz@langa.pl).
|
||||
|
||||
See [AUTHORS.md](./AUTHORS.md)
|
||||
Maintained with [Carol Willing](mailto:carolcode@willingconsulting.com),
|
||||
[Carl Meyer](mailto:carl@oddbird.net),
|
||||
[Jelle Zijlstra](mailto:jelle.zijlstra@gmail.com),
|
||||
[Mika Naylor](mailto:mail@autophagy.io),
|
||||
[Zsolt Dollenstein](mailto:zsol.zsol@gmail.com),
|
||||
[Cooper Lees](mailto:me@cooperlees.com), and Richard Si.
|
||||
|
||||
## Code of Conduct
|
||||
Multiple contributions by:
|
||||
|
||||
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.
|
||||
- [Abdur-Rahmaan Janhangeer](mailto:arj.python@gmail.com)
|
||||
- [Adam Johnson](mailto:me@adamj.eu)
|
||||
- [Adam Williamson](mailto:adamw@happyassassin.net)
|
||||
- [Alexander Huynh](mailto:github@grande.coffee)
|
||||
- [Alex Vandiver](mailto:github@chmrr.net)
|
||||
- [Allan Simon](mailto:allan.simon@supinfo.com)
|
||||
- Anders-Petter Ljungquist
|
||||
- [Andrew Thorp](mailto:andrew.thorp.dev@gmail.com)
|
||||
- [Andrew Zhou](mailto:andrewfzhou@gmail.com)
|
||||
- [Andrey](mailto:dyuuus@yandex.ru)
|
||||
- [Andy Freeland](mailto:andy@andyfreeland.net)
|
||||
- [Anthony Sottile](mailto:asottile@umich.edu)
|
||||
- [Arjaan Buijk](mailto:arjaan.buijk@gmail.com)
|
||||
- [Arnav Borbornah](mailto:arnavborborah11@gmail.com)
|
||||
- [Artem Malyshev](mailto:proofit404@gmail.com)
|
||||
- [Asger Hautop Drewsen](mailto:asgerdrewsen@gmail.com)
|
||||
- [Augie Fackler](mailto:raf@durin42.com)
|
||||
- [Aviskar KC](mailto:aviskarkc10@gmail.com)
|
||||
- Batuhan Taşkaya
|
||||
- [Benjamin Wohlwend](mailto:bw@piquadrat.ch)
|
||||
- [Benjamin Woodruff](mailto:github@benjam.info)
|
||||
- [Bharat Raghunathan](mailto:bharatraghunthan9767@gmail.com)
|
||||
- [Brandt Bucher](mailto:brandtbucher@gmail.com)
|
||||
- [Brett Cannon](mailto:brett@python.org)
|
||||
- [Bryan Bugyi](mailto:bryan.bugyi@rutgers.edu)
|
||||
- [Bryan Forbes](mailto:bryan@reigndropsfall.net)
|
||||
- [Calum Lind](mailto:calumlind@gmail.com)
|
||||
- [Charles](mailto:peacech@gmail.com)
|
||||
- Charles Reid
|
||||
- [Christian Clauss](mailto:cclauss@bluewin.ch)
|
||||
- [Christian Heimes](mailto:christian@python.org)
|
||||
- [Chuck Wooters](mailto:chuck.wooters@microsoft.com)
|
||||
- [Chris Rose](mailto:offline@offby1.net)
|
||||
- Codey Oxley
|
||||
- [Cong](mailto:congusbongus@gmail.com)
|
||||
- [Cooper Ry Lees](mailto:me@cooperlees.com)
|
||||
- [Dan Davison](mailto:dandavison7@gmail.com)
|
||||
- [Daniel Hahler](mailto:github@thequod.de)
|
||||
- [Daniel M. Capella](mailto:polycitizen@gmail.com)
|
||||
- Daniele Esposti
|
||||
- [David Hotham](mailto:david.hotham@metaswitch.com)
|
||||
- [David Lukes](mailto:dafydd.lukes@gmail.com)
|
||||
- [David Szotten](mailto:davidszotten@gmail.com)
|
||||
- [Denis Laxalde](mailto:denis@laxalde.org)
|
||||
- [Douglas Thor](mailto:dthor@transphormusa.com)
|
||||
- dylanjblack
|
||||
- [Eli Treuherz](mailto:eli@treuherz.com)
|
||||
- [Emil Hessman](mailto:emil@hessman.se)
|
||||
- [Felix Kohlgrüber](mailto:felix.kohlgrueber@gmail.com)
|
||||
- [Florent Thiery](mailto:fthiery@gmail.com)
|
||||
- Francisco
|
||||
- [Giacomo Tagliabue](mailto:giacomo.tag@gmail.com)
|
||||
- [Greg Gandenberger](mailto:ggandenberger@shoprunner.com)
|
||||
- [Gregory P. Smith](mailto:greg@krypto.org)
|
||||
- Gustavo Camargo
|
||||
- hauntsaninja
|
||||
- [Hadi Alqattan](mailto:alqattanhadizaki@gmail.com)
|
||||
- [Heaford](mailto:dan@heaford.com)
|
||||
- [Hugo Barrera](mailto::hugo@barrera.io)
|
||||
- Hugo van Kemenade
|
||||
- [Hynek Schlawack](mailto:hs@ox.cx)
|
||||
- [Ivan Katanić](mailto:ivan.katanic@gmail.com)
|
||||
- [Jakub Kadlubiec](mailto:jakub.kadlubiec@skyscanner.net)
|
||||
- [Jakub Warczarek](mailto:jakub.warczarek@gmail.com)
|
||||
- [Jan Hnátek](mailto:jan.hnatek@gmail.com)
|
||||
- [Jason Fried](mailto:me@jasonfried.info)
|
||||
- [Jason Friedland](mailto:jason@friedland.id.au)
|
||||
- [jgirardet](mailto:ijkl@netc.fr)
|
||||
- Jim Brännlund
|
||||
- [Jimmy Jia](mailto:tesrin@gmail.com)
|
||||
- [Joe Antonakakis](mailto:jma353@cornell.edu)
|
||||
- [Jon Dufresne](mailto:jon.dufresne@gmail.com)
|
||||
- [Jonas Obrist](mailto:ojiidotch@gmail.com)
|
||||
- [Jonty Wareing](mailto:jonty@jonty.co.uk)
|
||||
- [Jose Nazario](mailto:jose.monkey.org@gmail.com)
|
||||
- [Joseph Larson](mailto:larson.joseph@gmail.com)
|
||||
- [Josh Bode](mailto:joshbode@fastmail.com)
|
||||
- [Josh Holland](mailto:anowlcalledjosh@gmail.com)
|
||||
- [Joshua Cannon](mailto:joshdcannon@gmail.com)
|
||||
- [José Padilla](mailto:jpadilla@webapplicate.com)
|
||||
- [Juan Luis Cano Rodríguez](mailto:hello@juanlu.space)
|
||||
- [kaiix](mailto:kvn.hou@gmail.com)
|
||||
- [Katie McLaughlin](mailto:katie@glasnt.com)
|
||||
- Katrin Leinweber
|
||||
- [Keith Smiley](mailto:keithbsmiley@gmail.com)
|
||||
- [Kenyon Ralph](mailto:kenyon@kenyonralph.com)
|
||||
- [Kevin Kirsche](mailto:Kev.Kirsche+GitHub@gmail.com)
|
||||
- [Kyle Hausmann](mailto:kyle.hausmann@gmail.com)
|
||||
- [Kyle Sunden](mailto:sunden@wisc.edu)
|
||||
- Lawrence Chan
|
||||
- [Linus Groh](mailto:mail@linusgroh.de)
|
||||
- [Loren Carvalho](mailto:comradeloren@gmail.com)
|
||||
- [Luka Sterbic](mailto:luka.sterbic@gmail.com)
|
||||
- [LukasDrude](mailto:mail@lukas-drude.de)
|
||||
- Mahmoud Hossam
|
||||
- Mariatta
|
||||
- [Matt VanEseltine](mailto:vaneseltine@gmail.com)
|
||||
- [Matthew Clapp](mailto:itsayellow+dev@gmail.com)
|
||||
- [Matthew Walster](mailto:matthew@walster.org)
|
||||
- Max Smolens
|
||||
- [Michael Aquilina](mailto:michaelaquilina@gmail.com)
|
||||
- [Michael Flaxman](mailto:michael.flaxman@gmail.com)
|
||||
- [Michael J. Sullivan](mailto:sully@msully.net)
|
||||
- [Michael McClimon](mailto:michael@mcclimon.org)
|
||||
- [Miguel Gaiowski](mailto:miggaiowski@gmail.com)
|
||||
- [Mike](mailto:roshi@fedoraproject.org)
|
||||
- [mikehoyio](mailto:mikehoy@gmail.com)
|
||||
- [Min ho Kim](mailto:minho42@gmail.com)
|
||||
- [Miroslav Shubernetskiy](mailto:miroslav@miki725.com)
|
||||
- MomIsBestFriend
|
||||
- [Nathan Goldbaum](mailto:ngoldbau@illinois.edu)
|
||||
- [Nathan Hunt](mailto:neighthan.hunt@gmail.com)
|
||||
- [Neraste](mailto:neraste.herr10@gmail.com)
|
||||
- [Nikolaus Waxweiler](mailto:madigens@gmail.com)
|
||||
- [Ofek Lev](mailto:ofekmeister@gmail.com)
|
||||
- [Osaetin Daniel](mailto:osaetindaniel@gmail.com)
|
||||
- [otstrel](mailto:otstrel@gmail.com)
|
||||
- [Pablo Galindo](mailto:Pablogsal@gmail.com)
|
||||
- [Paul Ganssle](mailto:p.ganssle@gmail.com)
|
||||
- [Paul Meinhardt](mailto:mnhrdt@gmail.com)
|
||||
- [Peter Bengtsson](mailto:mail@peterbe.com)
|
||||
- [Peter Grayson](mailto:pete@jpgrayson.net)
|
||||
- [Peter Stensmyr](mailto:peter.stensmyr@gmail.com)
|
||||
- pmacosta
|
||||
- [Quentin Pradet](mailto:quentin@pradet.me)
|
||||
- [Ralf Schmitt](mailto:ralf@systemexit.de)
|
||||
- [Ramón Valles](mailto:mroutis@protonmail.com)
|
||||
- [Richard Fearn](mailto:richardfearn@gmail.com)
|
||||
- Richard Si
|
||||
- [Rishikesh Jha](mailto:rishijha424@gmail.com)
|
||||
- [Rupert Bedford](mailto:rupert@rupertb.com)
|
||||
- Russell Davis
|
||||
- [Rémi Verschelde](mailto:rverschelde@gmail.com)
|
||||
- [Sami Salonen](mailto:sakki@iki.fi)
|
||||
- [Samuel Cormier-Iijima](mailto:samuel@cormier-iijima.com)
|
||||
- [Sanket Dasgupta](mailto:sanketdasgupta@gmail.com)
|
||||
- Sergi
|
||||
- [Scott Stevenson](mailto:scott@stevenson.io)
|
||||
- Shantanu
|
||||
- [shaoran](mailto:shaoran@sakuranohana.org)
|
||||
- [Shinya Fujino](mailto:shf0811@gmail.com)
|
||||
- springstan
|
||||
- [Stavros Korokithakis](mailto:hi@stavros.io)
|
||||
- [Stephen Rosen](mailto:sirosen@globus.org)
|
||||
- [Steven M. Vascellaro](mailto:S.Vascellaro@gmail.com)
|
||||
- [Sunil Kapil](mailto:snlkapil@gmail.com)
|
||||
- [Sébastien Eustace](mailto:sebastien.eustace@gmail.com)
|
||||
- [Tal Amuyal](mailto:TalAmuyal@gmail.com)
|
||||
- [Terrance](mailto:git@terrance.allofti.me)
|
||||
- [Thom Lu](mailto:thomas.c.lu@gmail.com)
|
||||
- [Thomas Grainger](mailto:tagrain@gmail.com)
|
||||
- [Tim Gates](mailto:tim.gates@iress.com)
|
||||
- [Tim Swast](mailto:swast@google.com)
|
||||
- [Timo](mailto:timo_tk@hotmail.com)
|
||||
- Toby Fleming
|
||||
- [Tom Christie](mailto:tom@tomchristie.com)
|
||||
- [Tony Narlock](mailto:tony@git-pull.com)
|
||||
- [Tsuyoshi Hombashi](mailto:tsuyoshi.hombashi@gmail.com)
|
||||
- [Tushar Chandra](mailto:tusharchandra2018@u.northwestern.edu)
|
||||
- [Tzu-ping Chung](mailto:uranusjr@gmail.com)
|
||||
- [Utsav Shah](mailto:ukshah2@illinois.edu)
|
||||
- utsav-dbx
|
||||
- vezeli
|
||||
- [Ville Skyttä](mailto:ville.skytta@iki.fi)
|
||||
- [Vishwas B Sharma](mailto:sharma.vishwas88@gmail.com)
|
||||
- [Vlad Emelianov](mailto:volshebnyi@gmail.com)
|
||||
- [williamfzc](mailto:178894043@qq.com)
|
||||
- [wouter bolsterlee](mailto:wouter@bolsterl.ee)
|
||||
- Yazdan
|
||||
- [Yngve Høiseth](mailto:yngve@hoiseth.net)
|
||||
- [Yurii Karabas](mailto:1998uriyyo@gmail.com)
|
||||
- [Zac Hatfield-Dodds](mailto:zac@zhd.dev)
|
||||
|
11
SECURITY.md
11
SECURITY.md
@ -1,11 +0,0 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
Only the latest non-prerelease version is supported.
|
||||
|
||||
## Security contact information
|
||||
|
||||
To report a security vulnerability, please use the
|
||||
[Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the
|
||||
fix and disclosure.
|
71
action.yml
71
action.yml
@ -2,78 +2,13 @@ name: "Black"
|
||||
description: "The uncompromising Python code formatter."
|
||||
author: "Łukasz Langa and contributors to Black"
|
||||
inputs:
|
||||
options:
|
||||
description:
|
||||
"Options passed to Black. Use `black --help` to see available options. Default:
|
||||
'--check --diff'"
|
||||
required: false
|
||||
default: "--check --diff"
|
||||
src:
|
||||
description: "Source to run Black. Default: '.'"
|
||||
required: false
|
||||
default: "."
|
||||
jupyter:
|
||||
description:
|
||||
"Set this option to true to include Jupyter Notebook files. Default: false"
|
||||
required: false
|
||||
default: false
|
||||
black_args:
|
||||
description: "[DEPRECATED] Black input arguments."
|
||||
description: "Black input arguments."
|
||||
required: false
|
||||
default: ""
|
||||
deprecationMessage:
|
||||
"Input `with.black_args` is deprecated. Use `with.options` and `with.src` instead."
|
||||
version:
|
||||
description: 'Python Version specifier (PEP440) - e.g. "21.5b1"'
|
||||
required: false
|
||||
default: ""
|
||||
use_pyproject:
|
||||
description: Read Black version specifier from pyproject.toml if `true`.
|
||||
required: false
|
||||
default: "false"
|
||||
summary:
|
||||
description: "Whether to add the output to the workflow summary"
|
||||
required: false
|
||||
default: true
|
||||
branding:
|
||||
color: "black"
|
||||
icon: "check-circle"
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: black
|
||||
run: |
|
||||
# Even when black fails, do not close the shell
|
||||
set +e
|
||||
|
||||
if [ "$RUNNER_OS" == "Windows" ]; then
|
||||
runner="python"
|
||||
else
|
||||
runner="python3"
|
||||
fi
|
||||
|
||||
out=$(${runner} $GITHUB_ACTION_PATH/action/main.py)
|
||||
exit_code=$?
|
||||
|
||||
# Display the raw output in the step
|
||||
echo "${out}"
|
||||
|
||||
if [ "${{ inputs.summary }}" == "true" ]; then
|
||||
# Display the Markdown output in the job summary
|
||||
echo "\`\`\`python" >> $GITHUB_STEP_SUMMARY
|
||||
echo "${out}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
|
||||
# Exit with the exit-code returned by Black
|
||||
exit ${exit_code}
|
||||
env:
|
||||
# TODO: Remove once https://github.com/actions/runner/issues/665 is fixed.
|
||||
INPUT_OPTIONS: ${{ inputs.options }}
|
||||
INPUT_SRC: ${{ inputs.src }}
|
||||
INPUT_JUPYTER: ${{ inputs.jupyter }}
|
||||
INPUT_BLACK_ARGS: ${{ inputs.black_args }}
|
||||
INPUT_VERSION: ${{ inputs.version }}
|
||||
INPUT_USE_PYPROJECT: ${{ inputs.use_pyproject }}
|
||||
pythonioencoding: utf-8
|
||||
shell: bash
|
||||
using: "docker"
|
||||
image: "action/Dockerfile"
|
||||
|
10
action/Dockerfile
Normal file
10
action/Dockerfile
Normal file
@ -0,0 +1,10 @@
|
||||
FROM python:3
|
||||
|
||||
ENV PYTHONDONTWRITEBYTECODE 1
|
||||
ENV PYTHONUNBUFFERED 1
|
||||
|
||||
RUN pip install --upgrade --no-cache-dir black
|
||||
|
||||
COPY entrypoint.sh /entrypoint.sh
|
||||
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
17
action/entrypoint.sh
Executable file
17
action/entrypoint.sh
Executable file
@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# If no arguments are given use current working directory
|
||||
black_args=(".")
|
||||
if [ "$#" -eq 0 ] && [ "${INPUT_BLACK_ARGS}" != "" ]; then
|
||||
black_args+=(${INPUT_BLACK_ARGS})
|
||||
elif [ "$#" -ne 0 ] && [ "${INPUT_BLACK_ARGS}" != "" ]; then
|
||||
black_args+=($* ${INPUT_BLACK_ARGS})
|
||||
elif [ "$#" -ne 0 ] && [ "${INPUT_BLACK_ARGS}" == "" ]; then
|
||||
black_args+=($*)
|
||||
else
|
||||
# Default (if no args provided).
|
||||
black_args+=("--check" "--diff")
|
||||
fi
|
||||
|
||||
sh -c "black . ${black_args[*]}"
|
182
action/main.py
182
action/main.py
@ -1,182 +0,0 @@
|
||||
import os
|
||||
import re
|
||||
import shlex
|
||||
import shutil
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from subprocess import PIPE, STDOUT, run
|
||||
from typing import Union
|
||||
|
||||
ACTION_PATH = Path(os.environ["GITHUB_ACTION_PATH"])
|
||||
ENV_PATH = ACTION_PATH / ".black-env"
|
||||
ENV_BIN = ENV_PATH / ("Scripts" if sys.platform == "win32" else "bin")
|
||||
OPTIONS = os.getenv("INPUT_OPTIONS", default="")
|
||||
SRC = os.getenv("INPUT_SRC", default="")
|
||||
JUPYTER = os.getenv("INPUT_JUPYTER") == "true"
|
||||
BLACK_ARGS = os.getenv("INPUT_BLACK_ARGS", default="")
|
||||
VERSION = os.getenv("INPUT_VERSION", default="")
|
||||
USE_PYPROJECT = os.getenv("INPUT_USE_PYPROJECT") == "true"
|
||||
|
||||
BLACK_VERSION_RE = re.compile(r"^black([^A-Z0-9._-]+.*)$", re.IGNORECASE)
|
||||
EXTRAS_RE = re.compile(r"\[.*\]")
|
||||
EXPORT_SUBST_FAIL_RE = re.compile(r"\$Format:.*\$")
|
||||
|
||||
|
||||
def determine_version_specifier() -> str:
|
||||
"""Determine the version of Black to install.
|
||||
|
||||
The version can be specified either via the `with.version` input or via the
|
||||
pyproject.toml file if `with.use_pyproject` is set to `true`.
|
||||
"""
|
||||
if USE_PYPROJECT and VERSION:
|
||||
print(
|
||||
"::error::'with.version' and 'with.use_pyproject' inputs are "
|
||||
"mutually exclusive.",
|
||||
file=sys.stderr,
|
||||
flush=True,
|
||||
)
|
||||
sys.exit(1)
|
||||
if USE_PYPROJECT:
|
||||
return read_version_specifier_from_pyproject()
|
||||
elif VERSION and VERSION[0] in "0123456789":
|
||||
return f"=={VERSION}"
|
||||
else:
|
||||
return VERSION
|
||||
|
||||
|
||||
def read_version_specifier_from_pyproject() -> str:
|
||||
if sys.version_info < (3, 11):
|
||||
print(
|
||||
"::error::'with.use_pyproject' input requires Python 3.11 or later.",
|
||||
file=sys.stderr,
|
||||
flush=True,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
import tomllib # type: ignore[import-not-found,unreachable]
|
||||
|
||||
try:
|
||||
with Path("pyproject.toml").open("rb") as fp:
|
||||
pyproject = tomllib.load(fp)
|
||||
except FileNotFoundError:
|
||||
print(
|
||||
"::error::'with.use_pyproject' input requires a pyproject.toml file.",
|
||||
file=sys.stderr,
|
||||
flush=True,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
version = pyproject.get("tool", {}).get("black", {}).get("required-version")
|
||||
if version is not None:
|
||||
return f"=={version}"
|
||||
|
||||
arrays = [
|
||||
*pyproject.get("dependency-groups", {}).values(),
|
||||
pyproject.get("project", {}).get("dependencies"),
|
||||
*pyproject.get("project", {}).get("optional-dependencies", {}).values(),
|
||||
]
|
||||
for array in arrays:
|
||||
version = find_black_version_in_array(array)
|
||||
if version is not None:
|
||||
break
|
||||
|
||||
if version is None:
|
||||
print(
|
||||
"::error::'black' dependency missing from pyproject.toml.",
|
||||
file=sys.stderr,
|
||||
flush=True,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
return version
|
||||
|
||||
|
||||
def find_black_version_in_array(array: object) -> Union[str, None]:
|
||||
if not isinstance(array, list):
|
||||
return None
|
||||
try:
|
||||
for item in array:
|
||||
# Rudimentary PEP 508 parsing.
|
||||
item = item.split(";")[0]
|
||||
item = EXTRAS_RE.sub("", item).strip()
|
||||
if item == "black":
|
||||
print(
|
||||
"::error::Version specifier missing for 'black' dependency in "
|
||||
"pyproject.toml.",
|
||||
file=sys.stderr,
|
||||
flush=True,
|
||||
)
|
||||
sys.exit(1)
|
||||
elif m := BLACK_VERSION_RE.match(item):
|
||||
return m.group(1).strip()
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
return None
|
||||
|
||||
|
||||
run([sys.executable, "-m", "venv", str(ENV_PATH)], check=True)
|
||||
|
||||
version_specifier = determine_version_specifier()
|
||||
if JUPYTER:
|
||||
extra_deps = "[colorama,jupyter]"
|
||||
else:
|
||||
extra_deps = "[colorama]"
|
||||
if version_specifier:
|
||||
req = f"black{extra_deps}{version_specifier}"
|
||||
else:
|
||||
describe_name = ""
|
||||
with open(ACTION_PATH / ".git_archival.txt", encoding="utf-8") as fp:
|
||||
for line in fp:
|
||||
if line.startswith("describe-name: "):
|
||||
describe_name = line[len("describe-name: ") :].rstrip()
|
||||
break
|
||||
if not describe_name:
|
||||
print("::error::Failed to detect action version.", file=sys.stderr, flush=True)
|
||||
sys.exit(1)
|
||||
# expected format is one of:
|
||||
# - 23.1.0
|
||||
# - 23.1.0-51-g448bba7
|
||||
# - $Format:%(describe:tags=true,match=*[0-9]*)$ (if export-subst fails)
|
||||
if (
|
||||
describe_name.count("-") < 2
|
||||
and EXPORT_SUBST_FAIL_RE.match(describe_name) is None
|
||||
):
|
||||
# the action's commit matches a tag exactly, install exact version from PyPI
|
||||
req = f"black{extra_deps}=={describe_name}"
|
||||
else:
|
||||
# the action's commit does not match any tag, install from the local git repo
|
||||
req = f".{extra_deps}"
|
||||
print(f"Installing {req}...", flush=True)
|
||||
pip_proc = run(
|
||||
[str(ENV_BIN / "python"), "-m", "pip", "install", req],
|
||||
stdout=PIPE,
|
||||
stderr=STDOUT,
|
||||
encoding="utf-8",
|
||||
cwd=ACTION_PATH,
|
||||
)
|
||||
if pip_proc.returncode:
|
||||
print(pip_proc.stdout)
|
||||
print("::error::Failed to install Black.", file=sys.stderr, flush=True)
|
||||
sys.exit(pip_proc.returncode)
|
||||
|
||||
|
||||
base_cmd = [str(ENV_BIN / "black")]
|
||||
if BLACK_ARGS:
|
||||
# TODO: remove after a while since this is deprecated in favour of SRC + OPTIONS.
|
||||
proc = run(
|
||||
[*base_cmd, *shlex.split(BLACK_ARGS)],
|
||||
stdout=PIPE,
|
||||
stderr=STDOUT,
|
||||
encoding="utf-8",
|
||||
)
|
||||
else:
|
||||
proc = run(
|
||||
[*base_cmd, *shlex.split(OPTIONS), *shlex.split(SRC)],
|
||||
stdout=PIPE,
|
||||
stderr=STDOUT,
|
||||
encoding="utf-8",
|
||||
)
|
||||
shutil.rmtree(ENV_PATH, ignore_errors=True)
|
||||
print(proc.stdout)
|
||||
sys.exit(proc.returncode)
|
@ -3,13 +3,8 @@ import collections
|
||||
import os
|
||||
import sys
|
||||
import vim
|
||||
from distutils.util import strtobool
|
||||
|
||||
def strtobool(text):
|
||||
if text.lower() in ['y', 'yes', 't', 'true', 'on', '1']:
|
||||
return True
|
||||
if text.lower() in ['n', 'no', 'f', 'false', 'off', '0']:
|
||||
return False
|
||||
raise ValueError(f"{text} is not convertible to boolean")
|
||||
|
||||
class Flag(collections.namedtuple("FlagBase", "name, cast")):
|
||||
@property
|
||||
@ -27,14 +22,12 @@ class Flag(collections.namedtuple("FlagBase", "name, cast")):
|
||||
FLAGS = [
|
||||
Flag(name="line_length", cast=int),
|
||||
Flag(name="fast", cast=strtobool),
|
||||
Flag(name="skip_string_normalization", cast=strtobool),
|
||||
Flag(name="string_normalization", cast=strtobool),
|
||||
Flag(name="quiet", cast=strtobool),
|
||||
Flag(name="skip_magic_trailing_comma", cast=strtobool),
|
||||
Flag(name="preview", cast=strtobool),
|
||||
]
|
||||
|
||||
|
||||
def _get_python_binary(exec_prefix, pyver):
|
||||
def _get_python_binary(exec_prefix):
|
||||
try:
|
||||
default = vim.eval("g:pymode_python").strip()
|
||||
except vim.error:
|
||||
@ -43,15 +36,7 @@ def _get_python_binary(exec_prefix, pyver):
|
||||
return default
|
||||
if sys.platform[:3] == "win":
|
||||
return exec_prefix / 'python.exe'
|
||||
bin_path = exec_prefix / "bin"
|
||||
exec_path = (bin_path / f"python{pyver[0]}.{pyver[1]}").resolve()
|
||||
if exec_path.exists():
|
||||
return exec_path
|
||||
# It is possible that some environments may only have python3
|
||||
exec_path = (bin_path / f"python3").resolve()
|
||||
if exec_path.exists():
|
||||
return exec_path
|
||||
raise ValueError("python executable not found")
|
||||
return exec_prefix / 'bin' / 'python3'
|
||||
|
||||
def _get_pip(venv_path):
|
||||
if sys.platform[:3] == "win":
|
||||
@ -64,19 +49,9 @@ def _get_virtualenv_site_packages(venv_path, pyver):
|
||||
return venv_path / 'lib' / f'python{pyver[0]}.{pyver[1]}' / 'site-packages'
|
||||
|
||||
def _initialize_black_env(upgrade=False):
|
||||
if vim.eval("g:black_use_virtualenv ? 'true' : 'false'") == "false":
|
||||
if upgrade:
|
||||
print("Upgrade disabled due to g:black_use_virtualenv being disabled.")
|
||||
print("Either use your system package manager (or pip) to upgrade black separately,")
|
||||
print("or modify your vimrc to have 'let g:black_use_virtualenv = 1'.")
|
||||
return False
|
||||
else:
|
||||
# Nothing needed to be done.
|
||||
return True
|
||||
|
||||
pyver = sys.version_info[:3]
|
||||
if pyver < (3, 9):
|
||||
print("Sorry, Black requires Python 3.9+ to run.")
|
||||
if pyver < (3, 6, 2):
|
||||
print("Sorry, Black requires Python 3.6.2+ to run.")
|
||||
return False
|
||||
|
||||
from pathlib import Path
|
||||
@ -90,7 +65,7 @@ def _initialize_black_env(upgrade=False):
|
||||
_executable = sys.executable
|
||||
_base_executable = getattr(sys, "_base_executable", _executable)
|
||||
try:
|
||||
executable = str(_get_python_binary(Path(sys.exec_prefix), pyver))
|
||||
executable = str(_get_python_binary(Path(sys.exec_prefix)))
|
||||
sys.executable = executable
|
||||
sys._base_executable = executable
|
||||
print(f'Creating a virtualenv in {virtualenv_path}...')
|
||||
@ -123,49 +98,13 @@ if _initialize_black_env():
|
||||
import black
|
||||
import time
|
||||
|
||||
def get_target_version(tv):
|
||||
if isinstance(tv, black.TargetVersion):
|
||||
return tv
|
||||
ret = None
|
||||
try:
|
||||
ret = black.TargetVersion[tv.upper()]
|
||||
except KeyError:
|
||||
print(f"WARNING: Target version {tv!r} not recognized by Black, using default target")
|
||||
return ret
|
||||
|
||||
def Black(**kwargs):
|
||||
"""
|
||||
kwargs allows you to override ``target_versions`` argument of
|
||||
``black.FileMode``.
|
||||
|
||||
``target_version`` needs to be cleaned because ``black.FileMode``
|
||||
expects the ``target_versions`` argument to be a set of TargetVersion enums.
|
||||
|
||||
Allow kwargs["target_version"] to be a string to allow
|
||||
to type it more quickly.
|
||||
|
||||
Using also target_version instead of target_versions to remain
|
||||
consistent to Black's documentation of the structure of pyproject.toml.
|
||||
"""
|
||||
def Black():
|
||||
start = time.time()
|
||||
configs = get_configs()
|
||||
|
||||
black_kwargs = {}
|
||||
if "target_version" in kwargs:
|
||||
target_version = kwargs["target_version"]
|
||||
|
||||
if not isinstance(target_version, (list, set)):
|
||||
target_version = [target_version]
|
||||
target_version = set(filter(lambda x: x, map(lambda tv: get_target_version(tv), target_version)))
|
||||
black_kwargs["target_versions"] = target_version
|
||||
|
||||
mode = black.FileMode(
|
||||
line_length=configs["line_length"],
|
||||
string_normalization=not configs["skip_string_normalization"],
|
||||
string_normalization=configs["string_normalization"],
|
||||
is_pyi=vim.current.buffer.name.endswith('.pyi'),
|
||||
magic_trailing_comma=not configs["skip_magic_trailing_comma"],
|
||||
preview=configs["preview"],
|
||||
**black_kwargs,
|
||||
)
|
||||
quiet = configs["quiet"]
|
||||
|
||||
@ -178,9 +117,9 @@ def Black(**kwargs):
|
||||
)
|
||||
except black.NothingChanged:
|
||||
if not quiet:
|
||||
print(f'Black: already well formatted, good job. (took {time.time() - start:.4f}s)')
|
||||
print(f'Already well formatted, good job. (took {time.time() - start:.4f}s)')
|
||||
except Exception as exc:
|
||||
print(f'Black: {exc}')
|
||||
print(exc)
|
||||
else:
|
||||
current_buffer = vim.current.window.buffer
|
||||
cursors = []
|
||||
@ -197,18 +136,17 @@ def Black(**kwargs):
|
||||
except vim.error:
|
||||
window.cursor = (len(window.buffer), 0)
|
||||
if not quiet:
|
||||
print(f'Black: reformatted in {time.time() - start:.4f}s.')
|
||||
print(f'Reformatted in {time.time() - start:.4f}s.')
|
||||
|
||||
def get_configs():
|
||||
filename = vim.eval("@%")
|
||||
path_pyproject_toml = black.find_pyproject_toml((filename,))
|
||||
path_pyproject_toml = black.find_pyproject_toml(vim.eval("fnamemodify(getcwd(), ':t')"))
|
||||
if path_pyproject_toml:
|
||||
toml_config = black.parse_pyproject_toml(path_pyproject_toml)
|
||||
else:
|
||||
toml_config = {}
|
||||
|
||||
return {
|
||||
flag.var_name: toml_config.get(flag.name, flag.cast(vim.eval(flag.vim_rc_name)))
|
||||
flag.var_name: flag.cast(toml_config.get(flag.name, vim.eval(flag.vim_rc_name)))
|
||||
for flag in FLAGS
|
||||
}
|
||||
|
||||
@ -221,17 +159,8 @@ def BlackVersion():
|
||||
|
||||
EndPython3
|
||||
|
||||
function black#Black(...)
|
||||
let kwargs = {}
|
||||
for arg in a:000
|
||||
let arg_list = split(arg, '=')
|
||||
let kwargs[arg_list[0]] = arg_list[1]
|
||||
endfor
|
||||
python3 << EOF
|
||||
import vim
|
||||
kwargs = vim.eval("kwargs")
|
||||
EOF
|
||||
:py3 Black(**kwargs)
|
||||
function black#Black()
|
||||
:py3 Black()
|
||||
endfunction
|
||||
|
||||
function black#BlackUpgrade()
|
||||
|
@ -17,4 +17,4 @@ help:
|
||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||
%: Makefile
|
||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
38
docs/_static/custom.css
vendored
Normal file
38
docs/_static/custom.css
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
/* Make the sidebar scrollable. Fixes https://github.com/psf/black/issues/990 */
|
||||
div.sphinxsidebar {
|
||||
max-height: calc(100% - 18px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* Hide scrollbar for Chrome, Safari and Opera */
|
||||
div.sphinxsidebar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Hide scrollbar for IE 6, 7 and 8 */
|
||||
@media \0screen\, screen\9 {
|
||||
div.sphinxsidebar {
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Hide scrollbar for IE 9 and 10 */
|
||||
/* backslash-9 removes ie11+ & old Safari 4 */
|
||||
@media screen and (min-width: 0\0) {
|
||||
div.sphinxsidebar {
|
||||
-ms-overflow-style: none\9;
|
||||
}
|
||||
}
|
||||
|
||||
/* Hide scrollbar for IE 11 and up */
|
||||
_:-ms-fullscreen,
|
||||
:root div.sphinxsidebar {
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
/* Hide scrollbar for Edge */
|
||||
@supports (-ms-ime-align: auto) {
|
||||
div.sphinxsidebar {
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
}
|
2
docs/_static/license.svg
vendored
2
docs/_static/license.svg
vendored
@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="78" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="78" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h47v20H0z"/><path fill="#7900CA" d="M47 0h31v20H47z"/><path fill="url(#b)" d="M0 0h78v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"><text x="245" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="370">license</text><text x="245" y="140" transform="scale(.1)" textLength="370">license</text><text x="615" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="210">MIT</text><text x="615" y="140" transform="scale(.1)" textLength="210">MIT</text></g> </svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="78" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="78" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h47v20H0z"/><path fill="#7900CA" d="M47 0h31v20H47z"/><path fill="url(#b)" d="M0 0h78v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"><text x="245" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="370">license</text><text x="245" y="140" transform="scale(.1)" textLength="370">license</text><text x="615" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="210">MIT</text><text x="615" y="140" transform="scale(.1)" textLength="210">MIT</text></g> </svg>
|
Before Width: | Height: | Size: 950 B After Width: | Height: | Size: 949 B |
188
docs/authors.md
188
docs/authors.md
@ -1,3 +1,187 @@
|
||||
```{include} ../AUTHORS.md
|
||||
[//]: # "NOTE: THIS FILE WAS AUTOGENERATED FROM README.md"
|
||||
|
||||
```
|
||||
# Authors
|
||||
|
||||
Glued together by [Łukasz Langa](mailto:lukasz@langa.pl).
|
||||
|
||||
Maintained with [Carol Willing](mailto:carolcode@willingconsulting.com),
|
||||
[Carl Meyer](mailto:carl@oddbird.net),
|
||||
[Jelle Zijlstra](mailto:jelle.zijlstra@gmail.com),
|
||||
[Mika Naylor](mailto:mail@autophagy.io),
|
||||
[Zsolt Dollenstein](mailto:zsol.zsol@gmail.com), and
|
||||
[Cooper Lees](mailto:me@cooperlees.com).
|
||||
|
||||
Multiple contributions by:
|
||||
|
||||
- [Abdur-Rahmaan Janhangeer](mailto:arj.python@gmail.com)
|
||||
- [Adam Johnson](mailto:me@adamj.eu)
|
||||
- [Adam Williamson](mailto:adamw@happyassassin.net)
|
||||
- [Alexander Huynh](mailto:github@grande.coffee)
|
||||
- [Alex Vandiver](mailto:github@chmrr.net)
|
||||
- [Allan Simon](mailto:allan.simon@supinfo.com)
|
||||
- Anders-Petter Ljungquist
|
||||
- [Andrew Thorp](mailto:andrew.thorp.dev@gmail.com)
|
||||
- [Andrew Zhou](mailto:andrewfzhou@gmail.com)
|
||||
- [Andrey](mailto:dyuuus@yandex.ru)
|
||||
- [Andy Freeland](mailto:andy@andyfreeland.net)
|
||||
- [Anthony Sottile](mailto:asottile@umich.edu)
|
||||
- [Arjaan Buijk](mailto:arjaan.buijk@gmail.com)
|
||||
- [Arnav Borbornah](mailto:arnavborborah11@gmail.com)
|
||||
- [Artem Malyshev](mailto:proofit404@gmail.com)
|
||||
- [Asger Hautop Drewsen](mailto:asgerdrewsen@gmail.com)
|
||||
- [Augie Fackler](mailto:raf@durin42.com)
|
||||
- [Aviskar KC](mailto:aviskarkc10@gmail.com)
|
||||
- Batuhan Taşkaya
|
||||
- [Benjamin Wohlwend](mailto:bw@piquadrat.ch)
|
||||
- [Benjamin Woodruff](mailto:github@benjam.info)
|
||||
- [Bharat Raghunathan](mailto:bharatraghunthan9767@gmail.com)
|
||||
- [Brandt Bucher](mailto:brandtbucher@gmail.com)
|
||||
- [Brett Cannon](mailto:brett@python.org)
|
||||
- [Bryan Bugyi](mailto:bryan.bugyi@rutgers.edu)
|
||||
- [Bryan Forbes](mailto:bryan@reigndropsfall.net)
|
||||
- [Calum Lind](mailto:calumlind@gmail.com)
|
||||
- [Charles](mailto:peacech@gmail.com)
|
||||
- Charles Reid
|
||||
- [Christian Clauss](mailto:cclauss@bluewin.ch)
|
||||
- [Christian Heimes](mailto:christian@python.org)
|
||||
- [Chuck Wooters](mailto:chuck.wooters@microsoft.com)
|
||||
- [Chris Rose](mailto:offline@offby1.net)
|
||||
- Codey Oxley
|
||||
- [Cong](mailto:congusbongus@gmail.com)
|
||||
- [Cooper Ry Lees](mailto:me@cooperlees.com)
|
||||
- [Dan Davison](mailto:dandavison7@gmail.com)
|
||||
- [Daniel Hahler](mailto:github@thequod.de)
|
||||
- [Daniel M. Capella](mailto:polycitizen@gmail.com)
|
||||
- Daniele Esposti
|
||||
- [David Hotham](mailto:david.hotham@metaswitch.com)
|
||||
- [David Lukes](mailto:dafydd.lukes@gmail.com)
|
||||
- [David Szotten](mailto:davidszotten@gmail.com)
|
||||
- [Denis Laxalde](mailto:denis@laxalde.org)
|
||||
- [Douglas Thor](mailto:dthor@transphormusa.com)
|
||||
- dylanjblack
|
||||
- [Eli Treuherz](mailto:eli@treuherz.com)
|
||||
- [Emil Hessman](mailto:emil@hessman.se)
|
||||
- [Felix Kohlgrüber](mailto:felix.kohlgrueber@gmail.com)
|
||||
- [Florent Thiery](mailto:fthiery@gmail.com)
|
||||
- Francisco
|
||||
- [Giacomo Tagliabue](mailto:giacomo.tag@gmail.com)
|
||||
- [Greg Gandenberger](mailto:ggandenberger@shoprunner.com)
|
||||
- [Gregory P. Smith](mailto:greg@krypto.org)
|
||||
- Gustavo Camargo
|
||||
- hauntsaninja
|
||||
- [Hadi Alqattan](mailto:alqattanhadizaki@gmail.com)
|
||||
- [Heaford](mailto:dan@heaford.com)
|
||||
- [Hugo Barrera](mailto::hugo@barrera.io)
|
||||
- Hugo van Kemenade
|
||||
- [Hynek Schlawack](mailto:hs@ox.cx)
|
||||
- [Ivan Katanić](mailto:ivan.katanic@gmail.com)
|
||||
- [Jakub Kadlubiec](mailto:jakub.kadlubiec@skyscanner.net)
|
||||
- [Jakub Warczarek](mailto:jakub.warczarek@gmail.com)
|
||||
- [Jan Hnátek](mailto:jan.hnatek@gmail.com)
|
||||
- [Jason Fried](mailto:me@jasonfried.info)
|
||||
- [Jason Friedland](mailto:jason@friedland.id.au)
|
||||
- [jgirardet](mailto:ijkl@netc.fr)
|
||||
- Jim Brännlund
|
||||
- [Jimmy Jia](mailto:tesrin@gmail.com)
|
||||
- [Joe Antonakakis](mailto:jma353@cornell.edu)
|
||||
- [Jon Dufresne](mailto:jon.dufresne@gmail.com)
|
||||
- [Jonas Obrist](mailto:ojiidotch@gmail.com)
|
||||
- [Jonty Wareing](mailto:jonty@jonty.co.uk)
|
||||
- [Jose Nazario](mailto:jose.monkey.org@gmail.com)
|
||||
- [Joseph Larson](mailto:larson.joseph@gmail.com)
|
||||
- [Josh Bode](mailto:joshbode@fastmail.com)
|
||||
- [Josh Holland](mailto:anowlcalledjosh@gmail.com)
|
||||
- [José Padilla](mailto:jpadilla@webapplicate.com)
|
||||
- [Juan Luis Cano Rodríguez](mailto:hello@juanlu.space)
|
||||
- [kaiix](mailto:kvn.hou@gmail.com)
|
||||
- [Katie McLaughlin](mailto:katie@glasnt.com)
|
||||
- Katrin Leinweber
|
||||
- [Keith Smiley](mailto:keithbsmiley@gmail.com)
|
||||
- [Kenyon Ralph](mailto:kenyon@kenyonralph.com)
|
||||
- [Kevin Kirsche](mailto:Kev.Kirsche+GitHub@gmail.com)
|
||||
- [Kyle Hausmann](mailto:kyle.hausmann@gmail.com)
|
||||
- [Kyle Sunden](mailto:sunden@wisc.edu)
|
||||
- Lawrence Chan
|
||||
- [Linus Groh](mailto:mail@linusgroh.de)
|
||||
- [Loren Carvalho](mailto:comradeloren@gmail.com)
|
||||
- [Luka Sterbic](mailto:luka.sterbic@gmail.com)
|
||||
- [LukasDrude](mailto:mail@lukas-drude.de)
|
||||
- Mahmoud Hossam
|
||||
- Mariatta
|
||||
- [Matt VanEseltine](mailto:vaneseltine@gmail.com)
|
||||
- [Matthew Clapp](mailto:itsayellow+dev@gmail.com)
|
||||
- [Matthew Walster](mailto:matthew@walster.org)
|
||||
- Max Smolens
|
||||
- [Michael Aquilina](mailto:michaelaquilina@gmail.com)
|
||||
- [Michael Flaxman](mailto:michael.flaxman@gmail.com)
|
||||
- [Michael J. Sullivan](mailto:sully@msully.net)
|
||||
- [Michael McClimon](mailto:michael@mcclimon.org)
|
||||
- [Miguel Gaiowski](mailto:miggaiowski@gmail.com)
|
||||
- [Mike](mailto:roshi@fedoraproject.org)
|
||||
- [mikehoyio](mailto:mikehoy@gmail.com)
|
||||
- [Min ho Kim](mailto:minho42@gmail.com)
|
||||
- [Miroslav Shubernetskiy](mailto:miroslav@miki725.com)
|
||||
- MomIsBestFriend
|
||||
- [Nathan Goldbaum](mailto:ngoldbau@illinois.edu)
|
||||
- [Nathan Hunt](mailto:neighthan.hunt@gmail.com)
|
||||
- [Neraste](mailto:neraste.herr10@gmail.com)
|
||||
- [Nikolaus Waxweiler](mailto:madigens@gmail.com)
|
||||
- [Ofek Lev](mailto:ofekmeister@gmail.com)
|
||||
- [Osaetin Daniel](mailto:osaetindaniel@gmail.com)
|
||||
- [otstrel](mailto:otstrel@gmail.com)
|
||||
- [Pablo Galindo](mailto:Pablogsal@gmail.com)
|
||||
- [Paul Ganssle](mailto:p.ganssle@gmail.com)
|
||||
- [Paul Meinhardt](mailto:mnhrdt@gmail.com)
|
||||
- [Paul "TBBle" Hampson](mailto:Paul.Hampson@Pobox.com)
|
||||
- [Peter Bengtsson](mailto:mail@peterbe.com)
|
||||
- [Peter Grayson](mailto:pete@jpgrayson.net)
|
||||
- [Peter Stensmyr](mailto:peter.stensmyr@gmail.com)
|
||||
- pmacosta
|
||||
- [Quentin Pradet](mailto:quentin@pradet.me)
|
||||
- [Ralf Schmitt](mailto:ralf@systemexit.de)
|
||||
- [Ramón Valles](mailto:mroutis@protonmail.com)
|
||||
- [Richard Fearn](mailto:richardfearn@gmail.com)
|
||||
- Richard Si
|
||||
- [Rishikesh Jha](mailto:rishijha424@gmail.com)
|
||||
- [Rupert Bedford](mailto:rupert@rupertb.com)
|
||||
- Russell Davis
|
||||
- [Rémi Verschelde](mailto:rverschelde@gmail.com)
|
||||
- [Sami Salonen](mailto:sakki@iki.fi)
|
||||
- [Samuel Cormier-Iijima](mailto:samuel@cormier-iijima.com)
|
||||
- [Sanket Dasgupta](mailto:sanketdasgupta@gmail.com)
|
||||
- Sergi
|
||||
- [Scott Stevenson](mailto:scott@stevenson.io)
|
||||
- Shantanu
|
||||
- [shaoran](mailto:shaoran@sakuranohana.org)
|
||||
- [Shinya Fujino](mailto:shf0811@gmail.com)
|
||||
- springstan
|
||||
- [Stavros Korokithakis](mailto:hi@stavros.io)
|
||||
- [Stephen Rosen](mailto:sirosen@globus.org)
|
||||
- [Steven M. Vascellaro](mailto:S.Vascellaro@gmail.com)
|
||||
- [Sunil Kapil](mailto:snlkapil@gmail.com)
|
||||
- [Sébastien Eustace](mailto:sebastien.eustace@gmail.com)
|
||||
- [Tal Amuyal](mailto:TalAmuyal@gmail.com)
|
||||
- [Terrance](mailto:git@terrance.allofti.me)
|
||||
- [Thom Lu](mailto:thomas.c.lu@gmail.com)
|
||||
- [Thomas Grainger](mailto:tagrain@gmail.com)
|
||||
- [Tim Gates](mailto:tim.gates@iress.com)
|
||||
- [Tim Swast](mailto:swast@google.com)
|
||||
- [Timo](mailto:timo_tk@hotmail.com)
|
||||
- Toby Fleming
|
||||
- [Tom Christie](mailto:tom@tomchristie.com)
|
||||
- [Tony Narlock](mailto:tony@git-pull.com)
|
||||
- [Tsuyoshi Hombashi](mailto:tsuyoshi.hombashi@gmail.com)
|
||||
- [Tushar Chandra](mailto:tusharchandra2018@u.northwestern.edu)
|
||||
- [Tzu-ping Chung](mailto:uranusjr@gmail.com)
|
||||
- [Utsav Shah](mailto:ukshah2@illinois.edu)
|
||||
- utsav-dbx
|
||||
- vezeli
|
||||
- [Ville Skyttä](mailto:ville.skytta@iki.fi)
|
||||
- [Vishwas B Sharma](mailto:sharma.vishwas88@gmail.com)
|
||||
- [Vlad Emelianov](mailto:volshebnyi@gmail.com)
|
||||
- [williamfzc](mailto:178894043@qq.com)
|
||||
- [wouter bolsterlee](mailto:wouter@bolsterl.ee)
|
||||
- Yazdan
|
||||
- [Yngve Høiseth](mailto:yngve@hoiseth.net)
|
||||
- [Yurii Karabas](mailto:1998uriyyo@gmail.com)
|
||||
- [Zac Hatfield-Dodds](mailto:zac@zhd.dev)
|
||||
|
120
docs/black_primer.md
Normal file
120
docs/black_primer.md
Normal file
@ -0,0 +1,120 @@
|
||||
# black-primer
|
||||
|
||||
`black-primer` is a tool built for CI (and humans) to have _Black_ `--check` a number of
|
||||
(configured in `primer.json`) Git accessible projects in parallel. _(A PR will be
|
||||
accepted to add Mercurial support.)_
|
||||
|
||||
## Run flow
|
||||
|
||||
- Ensure we have a `black` + `git` in PATH
|
||||
- Load projects from `primer.json`
|
||||
- Run projects in parallel with `--worker` workers (defaults to CPU count / 2)
|
||||
- Checkout projects
|
||||
- Run black and record result
|
||||
- Clean up repository checkout _(can optionally be disabled via `--keep`)_
|
||||
- Display results summary to screen
|
||||
- Default to cleaning up `--work-dir` (which defaults to tempfile schemantics)
|
||||
- Return
|
||||
- 0 for successful run
|
||||
- < 0 for environment / internal error
|
||||
- \> 0 for each project with an error
|
||||
|
||||
## Speed up runs 🏎
|
||||
|
||||
If you're running locally yourself to test black on lots of code try:
|
||||
|
||||
- Using `-k` / `--keep` + `-w` / `--work-dir` so you don't have to re-checkout the repo
|
||||
each run
|
||||
|
||||
## CLI arguments
|
||||
|
||||
```text
|
||||
Usage: black-primer [OPTIONS]
|
||||
|
||||
primer - prime projects for blackening... 🏴
|
||||
|
||||
Options:
|
||||
-c, --config PATH JSON config file path [default: /Users/cooper/repos/
|
||||
black/src/black_primer/primer.json]
|
||||
|
||||
--debug Turn on debug logging [default: False]
|
||||
-k, --keep Keep workdir + repos post run [default: False]
|
||||
-L, --long-checkouts Pull big projects to test [default: False]
|
||||
-R, --rebase Rebase project if already checked out [default:
|
||||
False]
|
||||
|
||||
-w, --workdir PATH Directory path for repo checkouts [default: /var/fol
|
||||
ders/tc/hbwxh76j1hn6gqjd2n2sjn4j9k1glp/T/primer.20200
|
||||
517125229]
|
||||
|
||||
-W, --workers INTEGER Number of parallel worker coroutines [default: 2]
|
||||
-h, --help Show this message and exit.
|
||||
```
|
||||
|
||||
## Primer config file
|
||||
|
||||
The config file is in JSON format. Its main element is the `"projects"` dictionary and
|
||||
each parameter is explained below:
|
||||
|
||||
```json
|
||||
{
|
||||
"projects": {
|
||||
"00_Example": {
|
||||
"cli_arguments": "List of extra CLI arguments to pass Black for this project",
|
||||
"expect_formatting_changes": "Boolean to indicate that the version of Black is expected to cause changes",
|
||||
"git_clone_url": "URL you would pass `git clone` to check out this repo",
|
||||
"long_checkout": "Boolean to have repo skipped by default unless `--long-checkouts` is specified",
|
||||
"py_versions": "List of major Python versions to run this project with - all will do as you'd expect - run on ALL versions"
|
||||
},
|
||||
"aioexabgp": {
|
||||
"cli_arguments": [],
|
||||
"expect_formatting_changes": true,
|
||||
"git_clone_url": "https://github.com/cooperlees/aioexabgp.git",
|
||||
"long_checkout": false,
|
||||
"py_versions": ["all", "3.8"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
An example primer config file is used by Black
|
||||
[here](https://github.com/psf/black/blob/master/src/black_primer/primer.json)
|
||||
|
||||
## Example run
|
||||
|
||||
```console
|
||||
cooper-mbp:black cooper$ ~/venvs/b/bin/black-primer
|
||||
[2020-05-17 13:06:40,830] INFO: 4 projects to run Black over (lib.py:270)
|
||||
[2020-05-17 13:06:44,215] INFO: Analyzing results (lib.py:285)
|
||||
-- primer results 📊 --
|
||||
|
||||
3 / 4 succeeded (75.0%) ✅
|
||||
1 / 4 FAILED (25.0%) 💩
|
||||
- 0 projects disabled by config
|
||||
- 0 projects skipped due to Python version
|
||||
- 0 skipped due to long checkout
|
||||
|
||||
Failed projects:
|
||||
|
||||
## flake8-bugbear:
|
||||
- Returned 1
|
||||
- stdout:
|
||||
--- tests/b303_b304.py 2020-05-17 20:04:09.991227 +0000
|
||||
+++ tests/b303_b304.py 2020-05-17 20:06:42.753851 +0000
|
||||
@@ -26,11 +26,11 @@
|
||||
maxint = 5 # this is okay
|
||||
# the following should not crash
|
||||
(a, b, c) = list(range(3))
|
||||
# it is different than this
|
||||
a, b, c = list(range(3))
|
||||
- a, b, c, = list(range(3))
|
||||
+ a, b, c = list(range(3))
|
||||
# and different than this
|
||||
(a, b), c = list(range(3))
|
||||
a, *b, c = [1, 2, 3, 4, 5]
|
||||
b[1:3] = [0, 0]
|
||||
|
||||
would reformat tests/b303_b304.py
|
||||
Oh no! 💥 💔 💥
|
||||
1 file would be reformatted, 22 files would be left unchanged.
|
||||
```
|
@ -1,18 +1,13 @@
|
||||
# Black as a server (blackd)
|
||||
## blackd
|
||||
|
||||
`blackd` is a small HTTP server that exposes _Black_'s functionality over a simple
|
||||
protocol. The main benefit of using it is to avoid the cost of starting up a new _Black_
|
||||
process every time you want to blacken a file.
|
||||
|
||||
```{warning}
|
||||
`blackd` should not be run as a publicly accessible server as there are no security
|
||||
precautions in place to prevent abuse. **It is intended for local use only**.
|
||||
```
|
||||
|
||||
## Usage
|
||||
### Usage
|
||||
|
||||
`blackd` is not packaged alongside _Black_ by default because it has additional
|
||||
dependencies. You will need to execute `pip install 'black[d]'` to install it.
|
||||
dependencies. You will need to execute `pip install black[d]` to install it.
|
||||
|
||||
You can start the server on the default port, binding only to the local interface by
|
||||
running `blackd`. You will see a single line mentioning the server's version, and the
|
||||
@ -23,8 +18,14 @@ formatting requests.
|
||||
`blackd` provides even less options than _Black_. You can see them by running
|
||||
`blackd --help`:
|
||||
|
||||
```{program-output} blackd --help
|
||||
```text
|
||||
Usage: blackd [OPTIONS]
|
||||
|
||||
Options:
|
||||
--bind-host TEXT Address to bind the server to.
|
||||
--bind-port INTEGER Port to listen on
|
||||
--version Show the version and exit.
|
||||
-h, --help Show this message and exit.
|
||||
```
|
||||
|
||||
There is no official `blackd` client tool (yet!). You can test that blackd is working
|
||||
@ -35,7 +36,7 @@ blackd --bind-port 9090 & # or let blackd choose a port
|
||||
curl -s -XPOST "localhost:9090" -d "print('valid')"
|
||||
```
|
||||
|
||||
## Protocol
|
||||
### Protocol
|
||||
|
||||
`blackd` only accepts `POST` requests at the `/` path. The body of the request should
|
||||
contain the python source code to be formatted, encoded according to the `charset` field
|
||||
@ -50,24 +51,12 @@ is rejected with `HTTP 501` (Not Implemented).
|
||||
The headers controlling how source code is formatted are:
|
||||
|
||||
- `X-Line-Length`: corresponds to the `--line-length` command line flag.
|
||||
- `X-Skip-Source-First-Line`: corresponds to the `--skip-source-first-line` command line
|
||||
flag. If present and its value is not an empty string, the first line of the source
|
||||
code will be ignored.
|
||||
- `X-Skip-String-Normalization`: corresponds to the `--skip-string-normalization`
|
||||
command line flag. If present and its value is not the empty string, no string
|
||||
normalization will be performed.
|
||||
- `X-Skip-Magic-Trailing-Comma`: corresponds to the `--skip-magic-trailing-comma`
|
||||
command line flag. If present and its value is not an empty string, trailing commas
|
||||
command line flag. If present and its value is not the empty string, trailing commas
|
||||
will not be used as a reason to split lines.
|
||||
- `X-Preview`: corresponds to the `--preview` command line flag. If present and its
|
||||
value is not an empty string, experimental and potentially disruptive style changes
|
||||
will be used.
|
||||
- `X-Unstable`: corresponds to the `--unstable` command line flag. If present and its
|
||||
value is not an empty string, experimental style changes that are known to be buggy
|
||||
will be used.
|
||||
- `X-Enable-Unstable-Feature`: corresponds to the `--enable-unstable-feature` flag. The
|
||||
contents of the flag must be a comma-separated list of unstable features to be
|
||||
enabled. Example: `X-Enable-Unstable-Feature: feature1, feature2`.
|
||||
- `X-Fast-Or-Safe`: if set to `fast`, `blackd` will act as _Black_ does when passed the
|
||||
`--fast` command line flag.
|
||||
- `X-Python-Variant`: if set to `pyi`, `blackd` will act as _Black_ does when passed the
|
@ -1,3 +0,0 @@
|
||||
```{include} ../CHANGES.md
|
||||
|
||||
```
|
1
docs/change_log.md
Symbolic link
1
docs/change_log.md
Symbolic link
@ -0,0 +1 @@
|
||||
../CHANGES.md
|
@ -1,6 +1,4 @@
|
||||
# Using _Black_ with other tools
|
||||
|
||||
## Black compatible configurations
|
||||
# _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
|
||||
@ -13,28 +11,28 @@ tools out there.
|
||||
tools, using **their** supported file formats.
|
||||
|
||||
Compatible configuration files can be
|
||||
[found here](https://github.com/psf/black/blob/main/docs/compatible_configs/).
|
||||
[found here](https://github.com/psf/black/blob/master/docs/compatible_configs/).
|
||||
|
||||
### isort
|
||||
## isort
|
||||
|
||||
[isort](https://pypi.org/p/isort/) 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
|
||||
### Profile
|
||||
|
||||
Since version 5.0.0, isort supports
|
||||
[profiles](https://pycqa.github.io/isort/docs/configuration/profiles.html) to allow easy
|
||||
[profiles](https://pycqa.github.io/isort/docs/configuration/profiles/) to allow easy
|
||||
interoperability with common code styles. You can set the black profile in any of the
|
||||
[config files](https://pycqa.github.io/isort/docs/configuration/config_files.html)
|
||||
supported by isort. Below, an example for `pyproject.toml`:
|
||||
[config files](https://pycqa.github.io/isort/docs/configuration/config_files/) supported
|
||||
by isort. Below, an example for `pyproject.toml`:
|
||||
|
||||
```toml
|
||||
[tool.isort]
|
||||
profile = "black"
|
||||
```
|
||||
|
||||
#### Custom Configuration
|
||||
### 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
|
||||
@ -49,12 +47,12 @@ ensure_newline_before_comments = True
|
||||
line_length = 88
|
||||
```
|
||||
|
||||
#### Why those options above?
|
||||
### 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).
|
||||
_Black_ wraps imports that surpass `line-length` by moving identifiers into their own
|
||||
indented line. If that still doesn't fit the bill, it will put all of them in separate
|
||||
lines and put a trailing comma. A more detailed explanation of this behaviour can be
|
||||
[found here](https://github.com/psf/black/blob/master/docs/the_black_code_style.md#how-black-wraps-lines).
|
||||
|
||||
isort's default mode of wrapping imports that extend past the `line_length` limit is
|
||||
"Grid".
|
||||
@ -92,12 +90,12 @@ 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
|
||||
### Formats
|
||||
|
||||
<details>
|
||||
<summary>.isort.cfg</summary>
|
||||
|
||||
```ini
|
||||
```cfg
|
||||
[settings]
|
||||
profile = black
|
||||
```
|
||||
@ -107,7 +105,7 @@ profile = black
|
||||
<details>
|
||||
<summary>setup.cfg</summary>
|
||||
|
||||
```ini
|
||||
```cfg
|
||||
[isort]
|
||||
profile = black
|
||||
```
|
||||
@ -134,147 +132,117 @@ profile = black
|
||||
|
||||
</details>
|
||||
|
||||
### pycodestyle
|
||||
## Flake8
|
||||
|
||||
[pycodestyle](https://pycodestyle.pycqa.org/) is a code linter. It warns you of syntax
|
||||
errors, possible bugs, stylistic errors, etc. For the most part, pycodestyle follows
|
||||
[Flake8](https://pypi.org/p/flake8/) is a code linter. It warns you of syntax errors,
|
||||
possible bugs, stylistic errors, etc. For the most part, Flake8 follows
|
||||
[PEP 8](https://www.python.org/dev/peps/pep-0008/) when warning about stylistic errors.
|
||||
There are a few deviations that cause incompatibilities with _Black_.
|
||||
|
||||
#### Configuration
|
||||
### Configuration
|
||||
|
||||
```
|
||||
max-line-length = 88
|
||||
ignore = E203,E701
|
||||
extend-ignore = E203
|
||||
```
|
||||
|
||||
(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`
|
||||
### Why those options above?
|
||||
|
||||
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`
|
||||
whitespace around slice operators. Due to this, Flake8 will raise
|
||||
`E203 whitespace before ':'` warnings. Since this warning is not PEP 8 compliant, Flake8
|
||||
should be configured to ignore it via `extend-ignore = E203`.
|
||||
|
||||
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.
|
||||
in your configuration.
|
||||
|
||||
#### Formats
|
||||
Also, as like with isort, flake8 should be configured to allow lines up to the length
|
||||
limit of `88`, _Black_'s default. This explains `max-line-length = 88`.
|
||||
|
||||
### Formats
|
||||
|
||||
<details>
|
||||
<summary>setup.cfg, .pycodestyle, tox.ini</summary>
|
||||
|
||||
```ini
|
||||
[pycodestyle]
|
||||
max-line-length = 88
|
||||
ignore = E203,E701
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Flake8
|
||||
|
||||
[Flake8](https://pypi.org/p/flake8/) 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:
|
||||
|
||||
```
|
||||
[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:
|
||||
|
||||
```
|
||||
[flake8]
|
||||
max-line-length = 88
|
||||
extend-ignore = E203,E701
|
||||
```
|
||||
|
||||
#### Why those options above?
|
||||
|
||||
See [the pycodestyle section](labels/why-pycodestyle-warnings) above.
|
||||
|
||||
#### Formats
|
||||
|
||||
<details>
|
||||
<summary>.flake8, setup.cfg, tox.ini</summary>
|
||||
<summary>.flake8</summary>
|
||||
|
||||
```ini
|
||||
[flake8]
|
||||
max-line-length = 88
|
||||
extend-ignore = E203,E701
|
||||
extend-ignore = E203
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Pylint
|
||||
<details>
|
||||
<summary>setup.cfg</summary>
|
||||
|
||||
[Pylint](https://pypi.org/p/pylint/) 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.
|
||||
```cfg
|
||||
[flake8]
|
||||
max-line-length = 88
|
||||
extend-ignore = E203
|
||||
```
|
||||
|
||||
#### Configuration
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>tox.ini</summary>
|
||||
|
||||
```ini
|
||||
[flake8]
|
||||
max-line-length = 88
|
||||
extend-ignore = E203
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Pylint
|
||||
|
||||
[Pylint](https://pypi.org/p/pylint/) is also a code linter like Flake8. It has the same
|
||||
checks as flake8 and more. In particular, it has more formatting checks regarding style
|
||||
conventions like variable naming. With so many checks, Pylint is bound to have some
|
||||
mixed feelings about _Black_'s formatting style.
|
||||
|
||||
### Configuration
|
||||
|
||||
```
|
||||
disable = C0330, C0326
|
||||
max-line-length = 88
|
||||
```
|
||||
|
||||
#### Why those options above?
|
||||
### Why those options above?
|
||||
|
||||
Pylint should be configured to only complain about lines that surpass `88` characters
|
||||
via `max-line-length = 88`.
|
||||
When _Black_ is folding very long expressions, the closing brackets will
|
||||
[be dedented](https://github.com/psf/black/blob/master/docs/the_black_code_style.md#how-black-wraps-lines).
|
||||
|
||||
If using `pylint<2.6.0`, also disable `C0326` and `C0330` as these are incompatible with
|
||||
_Black_ formatting and have since been removed.
|
||||
```py3
|
||||
ImportantClass.important_method(
|
||||
exc, limit, lookup_lines, capture_locals, callback
|
||||
)
|
||||
```
|
||||
|
||||
#### Formats
|
||||
Although, this style is PEP 8 compliant, Pylint will raise
|
||||
`C0330: Wrong hanging indentation before block (add 4 spaces)` warnings. Since _Black_
|
||||
isn't configurable on this style, Pylint should be told to ignore these warnings via
|
||||
`disable = C0330`.
|
||||
|
||||
Also, since _Black_ deals with whitespace around operators and brackets, Pylint's
|
||||
warning `C0326: Bad whitespace` should be disabled using `disable = C0326`.
|
||||
|
||||
And as usual, Pylint should be configured to only complain about lines that surpass `88`
|
||||
characters via `max-line-length = 88`.
|
||||
|
||||
### Formats
|
||||
|
||||
<details>
|
||||
<summary>pylintrc</summary>
|
||||
|
||||
```ini
|
||||
[MESSAGES CONTROL]
|
||||
disable = C0330, C0326
|
||||
|
||||
[format]
|
||||
max-line-length = 88
|
||||
```
|
||||
@ -287,6 +255,9 @@ max-line-length = 88
|
||||
```cfg
|
||||
[pylint]
|
||||
max-line-length = 88
|
||||
|
||||
[pylint.messages_control]
|
||||
disable = C0330, C0326
|
||||
```
|
||||
|
||||
</details>
|
||||
@ -295,6 +266,9 @@ max-line-length = 88
|
||||
<summary>pyproject.toml</summary>
|
||||
|
||||
```toml
|
||||
[tool.pylint.messages_control]
|
||||
disable = "C0330, C0326"
|
||||
|
||||
[tool.pylint.format]
|
||||
max-line-length = "88"
|
||||
```
|
@ -1,3 +1,3 @@
|
||||
[flake8]
|
||||
max-line-length = 88
|
||||
extend-ignore = E203,E701
|
||||
extend-ignore = E203
|
||||
|
@ -1,3 +1,3 @@
|
||||
[flake8]
|
||||
max-line-length = 88
|
||||
extend-ignore = E203,E701
|
||||
extend-ignore = E203
|
||||
|
@ -1,3 +1,3 @@
|
||||
[flake8]
|
||||
max-line-length = 88
|
||||
extend-ignore = E203,E701
|
||||
extend-ignore = E203
|
||||
|
@ -1,3 +0,0 @@
|
||||
[pycodestyle]
|
||||
max-line-length = 88
|
||||
ignore = E203,E701
|
@ -1,3 +0,0 @@
|
||||
[pycodestyle]
|
||||
max-line-length = 88
|
||||
ignore = E203,E701
|
@ -1,3 +0,0 @@
|
||||
[pycodestyle]
|
||||
max-line-length = 88
|
||||
ignore = E203,E701
|
@ -1,2 +1,5 @@
|
||||
[MESSAGES CONTROL]
|
||||
disable = C0330, C0326
|
||||
|
||||
[format]
|
||||
max-line-length = 88
|
||||
|
@ -1,2 +1,5 @@
|
||||
[tool.pylint.messages_control]
|
||||
disable = "C0330, C0326"
|
||||
|
||||
[tool.pylint.format]
|
||||
max-line-length = "88"
|
||||
|
@ -1,2 +1,5 @@
|
||||
[pylint]
|
||||
max-line-length = 88
|
||||
|
||||
[pylint.messages_control]
|
||||
disable = C0330, C0326
|
||||
|
329
docs/conf.py
329
docs/conf.py
@ -1,3 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
@ -11,73 +12,240 @@
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import string
|
||||
from importlib.metadata import version
|
||||
from pathlib import Path
|
||||
from typing import Callable, Dict, List, Optional, Pattern, Tuple, Set
|
||||
from dataclasses import dataclass
|
||||
import logging
|
||||
|
||||
from sphinx.application import Sphinx
|
||||
from pkg_resources import get_distribution
|
||||
|
||||
logging.basicConfig(format="%(levelname)s: %(message)s", level=logging.INFO)
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
CURRENT_DIR = Path(__file__).parent
|
||||
README = CURRENT_DIR / ".." / "README.md"
|
||||
REFERENCE_DIR = CURRENT_DIR / "reference"
|
||||
STATIC_DIR = CURRENT_DIR / "_static"
|
||||
|
||||
|
||||
@dataclass
|
||||
class SrcRange:
|
||||
"""Tracks which part of a file to get a section's content.
|
||||
|
||||
Data:
|
||||
start_line: The line where the section starts (i.e. its sub-header) (inclusive).
|
||||
end_line: The line where the section ends (usually next sub-header) (exclusive).
|
||||
"""
|
||||
|
||||
start_line: int
|
||||
end_line: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class DocSection:
|
||||
"""Tracks information about a section of documentation.
|
||||
|
||||
Data:
|
||||
name: The section's name. This will used to detect duplicate sections.
|
||||
src: The filepath to get its contents.
|
||||
processors: The processors to run before writing the section to CURRENT_DIR.
|
||||
out_filename: The filename to use when writing the section to CURRENT_DIR.
|
||||
src_range: The line range of SRC to gets its contents.
|
||||
"""
|
||||
|
||||
name: str
|
||||
src: Path
|
||||
src_range: SrcRange = SrcRange(0, 1_000_000)
|
||||
out_filename: str = ""
|
||||
processors: Tuple[Callable, ...] = ()
|
||||
|
||||
def get_out_filename(self) -> str:
|
||||
if not self.out_filename:
|
||||
return self.name + ".md"
|
||||
else:
|
||||
return self.out_filename
|
||||
|
||||
|
||||
def make_pypi_svg(version: str) -> None:
|
||||
template: Path = CURRENT_DIR / "_static" / "pypi_template.svg"
|
||||
target: Path = CURRENT_DIR / "_static" / "pypi.svg"
|
||||
with open(str(template), encoding="utf8") as f:
|
||||
with open(str(template), "r", encoding="utf8") as f:
|
||||
svg: str = string.Template(f.read()).substitute(version=version)
|
||||
with open(str(target), "w", encoding="utf8") as f:
|
||||
f.write(svg)
|
||||
|
||||
|
||||
def replace_pr_numbers_with_links(content: str) -> str:
|
||||
"""Replaces all PR numbers with the corresponding GitHub link."""
|
||||
return re.sub(r"#(\d+)", r"[#\1](https://github.com/psf/black/pull/\1)", content)
|
||||
def make_filename(line: str) -> str:
|
||||
non_letters: Pattern = re.compile(r"[^a-z]+")
|
||||
filename: str = line[3:].rstrip().lower()
|
||||
filename = non_letters.sub("_", filename)
|
||||
if filename.startswith("_"):
|
||||
filename = filename[1:]
|
||||
if filename.endswith("_"):
|
||||
filename = filename[:-1]
|
||||
return filename + ".md"
|
||||
|
||||
|
||||
def handle_include_read(
|
||||
app: Sphinx,
|
||||
relative_path: Path,
|
||||
parent_docname: str,
|
||||
content: list[str],
|
||||
def get_contents(section: DocSection) -> str:
|
||||
"""Gets the contents for the DocSection."""
|
||||
contents: List[str] = []
|
||||
src: Path = section.src
|
||||
start_line: int = section.src_range.start_line
|
||||
end_line: int = section.src_range.end_line
|
||||
with open(src, "r", encoding="utf-8") as f:
|
||||
for lineno, line in enumerate(f, start=1):
|
||||
if lineno >= start_line and lineno < end_line:
|
||||
contents.append(line)
|
||||
result = "".join(contents)
|
||||
# Let's make Prettier happy with the amount of trailing newlines in the sections.
|
||||
if result.endswith("\n\n"):
|
||||
result = result[:-1]
|
||||
if not result.endswith("\n"):
|
||||
result = result + "\n"
|
||||
return result
|
||||
|
||||
|
||||
def get_sections_from_readme() -> List[DocSection]:
|
||||
"""Gets the sections from README so they can be processed by process_sections.
|
||||
|
||||
It opens README and goes down line by line looking for sub-header lines which
|
||||
denotes a section. Once it finds a sub-header line, it will create a DocSection
|
||||
object with all of the information currently available. Then on every line, it will
|
||||
track the ending line index of the section. And it repeats this for every sub-header
|
||||
line it finds.
|
||||
"""
|
||||
sections: List[DocSection] = []
|
||||
section: Optional[DocSection] = None
|
||||
with open(README, "r", encoding="utf-8") as f:
|
||||
for lineno, line in enumerate(f, start=1):
|
||||
if line.startswith("## "):
|
||||
filename = make_filename(line)
|
||||
section_name = filename[:-3]
|
||||
section = DocSection(
|
||||
name=str(section_name),
|
||||
src=README,
|
||||
src_range=SrcRange(lineno, lineno),
|
||||
out_filename=filename,
|
||||
processors=(fix_headers,),
|
||||
)
|
||||
sections.append(section)
|
||||
if section is not None:
|
||||
section.src_range.end_line += 1
|
||||
return sections
|
||||
|
||||
|
||||
def fix_headers(contents: str) -> str:
|
||||
"""Fixes the headers of sections copied from README.
|
||||
|
||||
Removes one octothorpe (#) from all headers since the contents are no longer nested
|
||||
in a root document (i.e. the README).
|
||||
"""
|
||||
lines: List[str] = contents.splitlines()
|
||||
fixed_contents: List[str] = []
|
||||
for line in lines:
|
||||
if line.startswith("##"):
|
||||
line = line[1:]
|
||||
fixed_contents.append(line + "\n") # splitlines strips the leading newlines
|
||||
return "".join(fixed_contents)
|
||||
|
||||
|
||||
def process_sections(
|
||||
custom_sections: List[DocSection], readme_sections: List[DocSection]
|
||||
) -> None:
|
||||
"""Handler for the include-read sphinx event."""
|
||||
if parent_docname == "change_log":
|
||||
content[0] = replace_pr_numbers_with_links(content[0])
|
||||
"""Reads, processes, and writes sections to CURRENT_DIR.
|
||||
|
||||
For each section, the contents will be fetched, processed by processors
|
||||
required by the section, and written to CURRENT_DIR. If it encounters duplicate
|
||||
sections (i.e. shares the same name attribute), it will skip processing the
|
||||
duplicates.
|
||||
|
||||
def setup(app: Sphinx) -> None:
|
||||
"""Sets up a minimal sphinx extension."""
|
||||
app.connect("include-read", handle_include_read)
|
||||
It processes custom sections before the README generated sections so sections in the
|
||||
README can be overwritten with custom options.
|
||||
"""
|
||||
processed_sections: Dict[str, DocSection] = {}
|
||||
modified_files: Set[Path] = set()
|
||||
sections: List[DocSection] = custom_sections
|
||||
sections.extend(readme_sections)
|
||||
for section in sections:
|
||||
if section.name in processed_sections:
|
||||
LOG.warning(
|
||||
f"Skipping '{section.name}' from '{section.src}' as it is a duplicate"
|
||||
f" of a custom section from '{processed_sections[section.name].src}'"
|
||||
)
|
||||
continue
|
||||
|
||||
LOG.info(f"Processing '{section.name}' from '{section.src}'")
|
||||
target_path: Path = CURRENT_DIR / section.get_out_filename()
|
||||
if target_path in modified_files:
|
||||
LOG.warning(
|
||||
f"{target_path} has been already written to, its contents will be"
|
||||
" OVERWRITTEN and notices will be duplicated"
|
||||
)
|
||||
contents: str = get_contents(section)
|
||||
|
||||
# processors goes here
|
||||
if fix_headers in section.processors:
|
||||
contents = fix_headers(contents)
|
||||
|
||||
with open(target_path, "w", encoding="utf-8") as f:
|
||||
if section.src.suffix == ".md" and section.src != target_path:
|
||||
rel = section.src.resolve().relative_to(CURRENT_DIR.parent)
|
||||
f.write(f'[//]: # "NOTE: THIS FILE WAS AUTOGENERATED FROM {rel}"\n\n')
|
||||
f.write(contents)
|
||||
processed_sections[section.name] = section
|
||||
modified_files.add(target_path)
|
||||
|
||||
# Necessary so Click doesn't hit an encode error when called by
|
||||
# sphinxcontrib-programoutput on Windows.
|
||||
os.putenv("pythonioencoding", "utf-8")
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = "Black"
|
||||
copyright = "2018-Present, Łukasz Langa and contributors to Black"
|
||||
copyright = "2020, Łukasz Langa and contributors to Black"
|
||||
author = "Łukasz Langa and contributors to Black"
|
||||
|
||||
# Autopopulate version
|
||||
# The version, including alpha/beta/rc tags, but not commit hash and datestamps
|
||||
release = version("black").split("+")[0]
|
||||
release = get_distribution("black").version.split("+")[0]
|
||||
# The short X.Y version.
|
||||
version = release
|
||||
for sp in "abcfr":
|
||||
version = version.split(sp)[0]
|
||||
|
||||
custom_sections = [
|
||||
DocSection("the_black_code_style", CURRENT_DIR / "the_black_code_style.md"),
|
||||
DocSection("editor_integration", CURRENT_DIR / "editor_integration.md"),
|
||||
DocSection("blackd", CURRENT_DIR / "blackd.md"),
|
||||
DocSection("black_primer", CURRENT_DIR / "black_primer.md"),
|
||||
DocSection("contributing_to_black", CURRENT_DIR / ".." / "CONTRIBUTING.md"),
|
||||
]
|
||||
|
||||
# Sphinx complains when there is a source file that isn't referenced in any of the docs.
|
||||
# Since some sections autogenerated from the README are unused warnings will appear.
|
||||
#
|
||||
# Sections must be listed to what their name is when passed through make_filename().
|
||||
blocklisted_sections_from_readme = {
|
||||
"license",
|
||||
"pragmatism",
|
||||
"testimonials",
|
||||
"used_by",
|
||||
"change_log",
|
||||
}
|
||||
|
||||
make_pypi_svg(release)
|
||||
readme_sections = get_sections_from_readme()
|
||||
readme_sections = [
|
||||
x for x in readme_sections if x.name not in blocklisted_sections_from_readme
|
||||
]
|
||||
|
||||
process_sections(custom_sections, readme_sections)
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
needs_sphinx = "4.4"
|
||||
needs_sphinx = "3.0"
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
@ -86,13 +254,11 @@ def setup(app: Sphinx) -> None:
|
||||
"sphinx.ext.autodoc",
|
||||
"sphinx.ext.intersphinx",
|
||||
"sphinx.ext.napoleon",
|
||||
"myst_parser",
|
||||
"sphinxcontrib.programoutput",
|
||||
"sphinx_copybutton",
|
||||
"recommonmark",
|
||||
]
|
||||
|
||||
# If you need extensions of a certain version or higher, list them here.
|
||||
needs_extensions = {"myst_parser": "0.13.7"}
|
||||
needs_extensions = {"recommonmark": "0.5"}
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ["_templates"]
|
||||
@ -109,7 +275,7 @@ def setup(app: Sphinx) -> None:
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = "en"
|
||||
language = None
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
@ -120,29 +286,36 @@ def setup(app: Sphinx) -> None:
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = "sphinx"
|
||||
|
||||
# We need headers to be linkable to so ask MyST-Parser to autogenerate anchor IDs for
|
||||
# headers up to and including level 3.
|
||||
myst_heading_anchors = 3
|
||||
|
||||
# Prettier support formatting some MyST syntax but not all, so let's disable the
|
||||
# unsupported yet still enabled by default ones.
|
||||
myst_disable_syntax = [
|
||||
"colon_fence",
|
||||
"myst_block_break",
|
||||
"myst_line_comment",
|
||||
"math_block",
|
||||
]
|
||||
|
||||
# Optional MyST Syntaxes
|
||||
myst_enable_extensions = []
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
html_theme = "furo"
|
||||
html_logo = "_static/logo2-readme.png"
|
||||
html_theme = "alabaster"
|
||||
|
||||
html_sidebars = {
|
||||
"**": [
|
||||
"about.html",
|
||||
"navigation.html",
|
||||
"relations.html",
|
||||
"sourcelink.html",
|
||||
"searchbox.html",
|
||||
]
|
||||
}
|
||||
|
||||
html_theme_options = {
|
||||
"show_related": False,
|
||||
"description": "“Any color you like.”",
|
||||
"github_button": True,
|
||||
"github_user": "psf",
|
||||
"github_repo": "black",
|
||||
"github_type": "star",
|
||||
"show_powered_by": True,
|
||||
"fixed_sidebar": True,
|
||||
"logo": "logo2.png",
|
||||
}
|
||||
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
@ -168,16 +341,33 @@ def setup(app: Sphinx) -> None:
|
||||
|
||||
# -- Options for LaTeX output ------------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#
|
||||
# 'papersize': 'letterpaper',
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#
|
||||
# 'pointsize': '10pt',
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#
|
||||
# 'preamble': '',
|
||||
# Latex figure (float) alignment
|
||||
#
|
||||
# 'figure_align': 'htbp',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [(
|
||||
master_doc,
|
||||
"black.tex",
|
||||
"Documentation for Black",
|
||||
"Łukasz Langa and contributors to Black",
|
||||
"manual",
|
||||
)]
|
||||
latex_documents = [
|
||||
(
|
||||
master_doc,
|
||||
"black.tex",
|
||||
"Documentation for Black",
|
||||
"Łukasz Langa and contributors to Black",
|
||||
"manual",
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
# -- Options for manual page output ------------------------------------------
|
||||
@ -192,15 +382,17 @@ def setup(app: Sphinx) -> None:
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [(
|
||||
master_doc,
|
||||
"Black",
|
||||
"Documentation for Black",
|
||||
author,
|
||||
"Black",
|
||||
"The uncompromising Python code formatter",
|
||||
"Miscellaneous",
|
||||
)]
|
||||
texinfo_documents = [
|
||||
(
|
||||
master_doc,
|
||||
"Black",
|
||||
"Documentation for Black",
|
||||
author,
|
||||
"Black",
|
||||
"The uncompromising Python code formatter",
|
||||
"Miscellaneous",
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
# -- Options for Epub output -------------------------------------------------
|
||||
@ -228,14 +420,7 @@ def setup(app: Sphinx) -> None:
|
||||
|
||||
autodoc_member_order = "bysource"
|
||||
|
||||
# -- sphinx-copybutton configuration ----------------------------------------
|
||||
copybutton_prompt_text = (
|
||||
r">>> |\.\.\. |> |\$ |\# | In \[\d*\]: | {2,5}\.\.\.: | {5,8}: "
|
||||
)
|
||||
copybutton_prompt_is_regexp = True
|
||||
copybutton_remove_prompts = True
|
||||
|
||||
# -- Options for intersphinx extension ---------------------------------------
|
||||
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
intersphinx_mapping = {"<name>": ("https://docs.python.org/3/", None)}
|
||||
intersphinx_mapping = {"https://docs.python.org/3/": None}
|
||||
|
@ -1,58 +0,0 @@
|
||||
# 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 ..." /
|
||||
"diff-shades reports zero changes ..." 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 `main` | 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-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-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 of the preview
|
||||
changes and links to further information. If there's a pre-existing diff-shades comment,
|
||||
it'll be updated instead the next time the workflow is triggered on the same PR.
|
||||
|
||||
```{note}
|
||||
The `preview-changes` job will only fail intentionally if while analyzing a file failed to
|
||||
format. Otherwise a failure indicates a bug in the workflow.
|
||||
```
|
||||
|
||||
The workflow uploads several artifacts upon completion:
|
||||
|
||||
- The raw analyses (.json)
|
||||
- HTML diffs (.html)
|
||||
- `.pr-comment.json` (if triggered by a PR)
|
||||
|
||||
The last one is downloaded by the `diff-shades-comment` workflow and shouldn't be
|
||||
downloaded locally. The HTML diffs come in handy for push-based where there's no PR to
|
||||
post a comment. And the analyses exist just in case you want to do further analysis
|
||||
using the collected data locally.
|
||||
|
||||
[diff-shades]: https://github.com/ichard26/diff-shades#readme
|
@ -1,45 +0,0 @@
|
||||
# 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`.
|
@ -1,169 +0,0 @@
|
||||
# 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 a long enough time, 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)
|
||||
- **`skip news`**: for PRs that are trivial and don't need a CHANGELOG entry (and skips
|
||||
the CHANGELOG entry check)
|
||||
|
||||
```{note}
|
||||
We do use labels for PRs, in particular the `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 longterm
|
||||
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/master/docs/the_black_code_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!
|
||||
```
|
@ -1,174 +0,0 @@
|
||||
# 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, 2022 → `22.1.0`
|
||||
- `release.py` will calculate this and log to stderr for you copy paste pleasure
|
||||
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
|
||||
- Sub headings in the template, if they have no bullet points need manual removal
|
||||
_PR welcome to improve :D_
|
||||
1. If `release.py` fail 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. Double-check that no changelog entries since the last release were put in the
|
||||
wrong section (e.g., run `git diff <last release> CHANGES.md`)
|
||||
1. Update references to the latest version in
|
||||
{doc}`/integrations/source_version_control` and
|
||||
{doc}`/usage_and_configuration/the_basics`
|
||||
- Example PR: [GH-3139]
|
||||
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. You can leave the release title blank, GitHub will default to the tag name
|
||||
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 + commit (git push - No review) 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.
|
||||
|
||||
### Publish to PyPI
|
||||
|
||||
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 [build] and then uploads them to PyPI using [twine]. These artifacts
|
||||
are general-purpose and can be used on basically any platform supported by Python.
|
||||
|
||||
#### 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).
|
||||
|
||||
Like the previous job group, the built wheels are uploaded to PyPI using [twine].
|
||||
|
||||
#### Update stable branch
|
||||
|
||||
So this job doesn't _really_ belong here, but updating the `stable` branch after the
|
||||
other PyPI jobs pass (they must pass for this job to start) makes the most sense. This
|
||||
saves us from remembering to update the branch sometime after cutting the release.
|
||||
|
||||
- _Currently this workflow uses an API token associated with @ambv's PyPI account_
|
||||
|
||||
### Publish executables
|
||||
|
||||
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`.
|
||||
```
|
||||
|
||||
[black-actions]: https://github.com/psf/black/actions
|
||||
[build]: https://pypa-build.readthedocs.io/
|
||||
[calver]: https://calver.org
|
||||
[cibuildwheel]: https://cibuildwheel.readthedocs.io/
|
||||
[gh-3139]: https://github.com/psf/black/pull/3139
|
||||
[github actions]: https://github.com/features/actions
|
||||
[github release]: https://github.com/psf/black/releases
|
||||
[new-release]: https://github.com/psf/black/releases/new
|
||||
[mypyc]: https://mypyc.readthedocs.io/
|
||||
[mypyc-platform-support]:
|
||||
/faq.html#what-is-compiled-yes-no-all-about-in-the-version-output
|
||||
[pyinstaller]: https://www.pyinstaller.org/
|
||||
[sdist]:
|
||||
https://packaging.python.org/en/latest/glossary/#term-Source-Distribution-or-sdist
|
||||
[twine]: https://github.com/features/actions
|
||||
[wheels]: https://packaging.python.org/en/latest/glossary/#term-Wheel
|
@ -1,158 +0,0 @@
|
||||
# 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 -r test_requirements.txt
|
||||
(.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
|
||||
# Linting
|
||||
(.venv)$ pre-commit run -a
|
||||
|
||||
# Unit tests
|
||||
(.venv)$ tox -e py
|
||||
|
||||
# Optional Fuzz testing
|
||||
(.venv)$ tox -e fuzz
|
||||
|
||||
# Format Black itself
|
||||
(.venv)$ tox -e run_self
|
||||
```
|
||||
|
||||
### Development
|
||||
|
||||
Further examples of invoking the tests
|
||||
|
||||
```console
|
||||
# Run all of the above mentioned, in parallel
|
||||
(.venv)$ tox --parallel=auto
|
||||
|
||||
# Run tests on a specific python version
|
||||
(.venv)$ tox -e py39
|
||||
|
||||
# Run an individual test
|
||||
(.venv)$ pytest -k <test name>
|
||||
|
||||
# Pass arguments to pytest
|
||||
(.venv)$ tox -e py -- --no-cov
|
||||
|
||||
# Print full tree diff, see documentation below
|
||||
(.venv)$ tox -e py -- --print-full-tree
|
||||
|
||||
# Disable diff printing, see documentation below
|
||||
(.venv)$ tox -e py -- --print-tree-diff=False
|
||||
```
|
||||
|
||||
### 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`.
|
||||
|
||||
#### `--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`.
|
||||
|
||||
### 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 `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)
|
||||
```
|
||||
|
||||
<!---
|
||||
The Next PR Number link uses HTML because of a bug in MyST-Parser that double-escapes the ampersand, causing the query parameters to not be processed.
|
||||
MyST-Parser issue: https://github.com/executablebooks/MyST-Parser/issues/760
|
||||
MyST-Parser stalled fix PR: https://github.com/executablebooks/MyST-Parser/pull/929
|
||||
-->
|
||||
|
||||
Note that X should be your PR number, not issue number! To workout X, please use
|
||||
<a href="https://ichard26.github.io/next-pr-number/?owner=psf&name=black">Next PR
|
||||
Number</a>. 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
|
||||
|
||||
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 though. 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 -r docs/requirements.txt
|
||||
(.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.
|
112
docs/contributing_to_black.md
Normal file
112
docs/contributing_to_black.md
Normal file
@ -0,0 +1,112 @@
|
||||
[//]: # "NOTE: THIS FILE WAS AUTOGENERATED FROM CONTRIBUTING.md"
|
||||
|
||||
# Contributing to _Black_
|
||||
|
||||
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?
|
||||
|
||||
## Bird's eye view
|
||||
|
||||
In terms of inspiration, _Black_ is about as configurable as _gofmt_. This is
|
||||
deliberate.
|
||||
|
||||
Bug reports and fixes are always welcome! Please follow the
|
||||
[issue template on GitHub](https://github.com/psf/black/issues/new) 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.
|
||||
|
||||
## Technicalities
|
||||
|
||||
Development on the latest version of Python is preferred. As of this writing it's 3.9.
|
||||
You can use any operating system. I am using macOS myself and CentOS at work.
|
||||
|
||||
Install all development dependencies using:
|
||||
|
||||
```console
|
||||
$ pipenv install --dev
|
||||
$ pipenv shell
|
||||
$ pre-commit install
|
||||
```
|
||||
|
||||
If you haven't used `pipenv` before but are comfortable with virtualenvs, just run
|
||||
`pip install pipenv` in the virtualenv you're already using and invoke the command above
|
||||
from the cloned _Black_ repo. It will do the correct thing.
|
||||
|
||||
Non pipenv install works too:
|
||||
|
||||
```console
|
||||
$ pip install -r test_requirements
|
||||
$ pip install -e .[d]
|
||||
```
|
||||
|
||||
Before submitting pull requests, run lints and tests with the following commands from
|
||||
the root of the black repo:
|
||||
|
||||
```console
|
||||
# Linting
|
||||
$ pre-commit run -a
|
||||
|
||||
# Unit tests
|
||||
$ tox -e py
|
||||
|
||||
# Optional Fuzz testing
|
||||
$ tox -e fuzz
|
||||
|
||||
# Optional CI run to test your changes on many popular python projects
|
||||
$ black-primer [-k -w /tmp/black_test_repos]
|
||||
```
|
||||
|
||||
### News / Changelog Requirement
|
||||
|
||||
`Black` has CI that will check for an entry corresponding to your PR in `CHANGES.md`. If
|
||||
you feel this PR not require a changelog entry please state that in a comment and a
|
||||
maintainer can add a `skip news` label to make the CI pass. Otherwise, please ensure you
|
||||
have a line in the following format:
|
||||
|
||||
```md
|
||||
- `Black` is now more awesome (#X)
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
### Docs Testing
|
||||
|
||||
If you make changes to docs, you can test they still build locally too.
|
||||
|
||||
```console
|
||||
$ pip install -r docs/requirements.txt
|
||||
$ pip install [-e] .[d]
|
||||
$ sphinx-build -a -b html -W docs/ docs/_build/
|
||||
```
|
||||
|
||||
## black-primer
|
||||
|
||||
`black-primer` is used by CI to pull down well-known _Black_ formatted projects and see
|
||||
if we get source code changes. It will error on formatting changes or errors. Please run
|
||||
before pushing your PR to see if you get the actions you would expect from _Black_ with
|
||||
your PR. You may need to change
|
||||
[primer.json](https://github.com/psf/black/blob/master/src/black_primer/primer.json)
|
||||
configuration for it to pass.
|
||||
|
||||
For more `black-primer` information visit the
|
||||
[documentation](https://github.com/psf/black/blob/master/docs/black_primer.md).
|
||||
|
||||
## Hygiene
|
||||
|
||||
If you're fixing a bug, add a test. Run it first to confirm it fails, then fix the bug,
|
||||
run it again to confirm it's really fixed.
|
||||
|
||||
If adding a new feature, add a test. In fact, always add a test. But wait, before adding
|
||||
any large feature, first open an issue for us to discuss the idea first.
|
||||
|
||||
## Finally
|
||||
|
||||
Thanks again for your interest in improving the project! You're taking action when most
|
||||
people decide to sit and watch.
|
335
docs/editor_integration.md
Normal file
335
docs/editor_integration.md
Normal file
@ -0,0 +1,335 @@
|
||||
# Editor integration
|
||||
|
||||
## Emacs
|
||||
|
||||
Options include the following:
|
||||
|
||||
- [purcell/reformatter.el](https://github.com/purcell/reformatter.el)
|
||||
- [proofit404/blacken](https://github.com/pythonic-emacs/blacken)
|
||||
- [Elpy](https://github.com/jorgenschaefer/elpy).
|
||||
|
||||
## PyCharm/IntelliJ IDEA
|
||||
|
||||
1. Install `black`.
|
||||
|
||||
```console
|
||||
$ pip install black
|
||||
```
|
||||
|
||||
2. Locate your `black` installation folder.
|
||||
|
||||
On macOS / Linux / BSD:
|
||||
|
||||
```console
|
||||
$ which black
|
||||
/usr/local/bin/black # possible location
|
||||
```
|
||||
|
||||
On Windows:
|
||||
|
||||
```console
|
||||
$ where black
|
||||
%LocalAppData%\Programs\Python\Python36-32\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`.
|
||||
|
||||
3. Open External tools in PyCharm/IntelliJ IDEA
|
||||
|
||||
On macOS:
|
||||
|
||||
`PyCharm -> Preferences -> Tools -> External Tools`
|
||||
|
||||
On Windows / Linux / BSD:
|
||||
|
||||
`File -> Settings -> Tools -> External Tools`
|
||||
|
||||
4. Click the + icon to add a new external tool with the following values:
|
||||
|
||||
- Name: Black
|
||||
- Description: Black is the uncompromising Python code formatter.
|
||||
- Program: <install_location_from_step_2>
|
||||
- Arguments: `"$FilePath$"`
|
||||
|
||||
5. 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`.
|
||||
|
||||
6. Optionally, run _Black_ on every file save:
|
||||
|
||||
1. Make sure you have the
|
||||
[File Watchers](https://plugins.jetbrains.com/plugin/7177-file-watchers) plugin
|
||||
installed.
|
||||
2. Go to `Preferences or Settings -> Tools -> File Watchers` and click `+` to add a
|
||||
new watcher:
|
||||
- Name: Black
|
||||
- File type: Python
|
||||
- Scope: Project Files
|
||||
- Program: <install_location_from_step_2>
|
||||
- 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 supports black via the OS Commands tool, as explained in the Wing documentation on
|
||||
[pep8 formatting](https://wingware.com/doc/edit/pep8). The detailed procedure is:
|
||||
|
||||
1. Install `black`.
|
||||
|
||||
```console
|
||||
$ pip install black
|
||||
```
|
||||
|
||||
2. Make sure it runs from the command line, e.g.
|
||||
|
||||
```console
|
||||
$ black --help
|
||||
```
|
||||
|
||||
3. In Wing IDE, activate the **OS Commands** panel and define the command **black** to
|
||||
execute black on the currently selected file:
|
||||
|
||||
- Use the Tools -> OS Commands menu selection
|
||||
- click on **+** in **OS Commands** -> New: Command line..
|
||||
- Title: black
|
||||
- Command Line: black %s
|
||||
- I/O Encoding: Use Default
|
||||
- Key Binding: F1
|
||||
- [x] Raise OS Commands when executed
|
||||
- [x] Auto-save files before execution
|
||||
- [x] Line mode
|
||||
|
||||
4. Select a file in the editor and press **F1** , or whatever key binding you selected
|
||||
in step 3, to reformat the file.
|
||||
|
||||
## Vim
|
||||
|
||||
### Official plugin
|
||||
|
||||
Commands and shortcuts:
|
||||
|
||||
- `:Black` to format the entire file (ranges not supported);
|
||||
- `:BlackUpgrade` to upgrade _Black_ inside the virtualenv;
|
||||
- `:BlackVersion` to get the current version of _Black_ inside the virtualenv.
|
||||
|
||||
Configuration:
|
||||
|
||||
- `g:black_fast` (defaults to `0`)
|
||||
- `g:black_linelength` (defaults to `88`)
|
||||
- `g:black_skip_string_normalization` (defaults to `0`)
|
||||
- `g:black_virtualenv` (defaults to `~/.vim/black` or `~/.local/share/nvim/black`)
|
||||
- `g:black_quiet` (defaults to `0`)
|
||||
|
||||
To install with [vim-plug](https://github.com/junegunn/vim-plug):
|
||||
|
||||
```
|
||||
Plug 'psf/black', { 'branch': 'stable' }
|
||||
```
|
||||
|
||||
or with [Vundle](https://github.com/VundleVim/Vundle.vim):
|
||||
|
||||
```
|
||||
Plugin 'psf/black'
|
||||
```
|
||||
|
||||
and execute the following in a terminal:
|
||||
|
||||
```console
|
||||
$ cd ~/.vim/bundle/black
|
||||
$ git checkout origin/stable -b stable
|
||||
```
|
||||
|
||||
or you can copy the plugin from
|
||||
[plugin/black.vim](https://github.com/psf/black/blob/stable/plugin/black.vim).
|
||||
|
||||
```
|
||||
mkdir -p ~/.vim/pack/python/start/black/plugin
|
||||
curl https://raw.githubusercontent.com/psf/black/stable/plugin/black.vim -o ~/.vim/pack/python/start/black/plugin/black.vim
|
||||
```
|
||||
|
||||
Let me know if this requires any changes to work with Vim 8's builtin `packadd`, or
|
||||
Pathogen, and so on.
|
||||
|
||||
This plugin **requires Vim 7.0+ built with Python 3.6+ support**. It needs Python 3.6 to
|
||||
be able to run _Black_ inside the Vim process which is much faster than calling an
|
||||
external command.
|
||||
|
||||
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 master), create a virtualenv manually and point
|
||||
`g:black_virtualenv` to it. The plugin will use it.
|
||||
|
||||
To run _Black_ on save, add the following line to `.vimrc` or `init.vim`:
|
||||
|
||||
```
|
||||
autocmd BufWritePre *.py execute ':Black'
|
||||
```
|
||||
|
||||
To run _Black_ on a key press (e.g. F9 below), add this:
|
||||
|
||||
```
|
||||
nnoremap <F9> :Black<CR>
|
||||
```
|
||||
|
||||
**How to get Vim with Python 3.6?** On Ubuntu 17.10 Vim comes with Python 3.6 by
|
||||
default. On macOS with Homebrew run: `brew install vim`. When building Vim from source,
|
||||
use: `./configure --enable-python3interp=yes`. There's many guides online how to do
|
||||
this.
|
||||
|
||||
**I get an import error when using _Black_ from a virtual environment**: If you get an
|
||||
error message like this:
|
||||
|
||||
```text
|
||||
Traceback (most recent call last):
|
||||
File "<string>", line 63, in <module>
|
||||
File "/home/gui/.vim/black/lib/python3.7/site-packages/black.py", line 45, in <module>
|
||||
from typed_ast import ast3, ast27
|
||||
File "/home/gui/.vim/black/lib/python3.7/site-packages/typed_ast/ast3.py", line 40, in <module>
|
||||
from typed_ast import _ast3
|
||||
ImportError: /home/gui/.vim/black/lib/python3.7/site-packages/typed_ast/_ast3.cpython-37m-x86_64-linux-gnu.so: undefined symbool: PyExc_KeyboardInterrupt
|
||||
```
|
||||
|
||||
Then you need to install `typed_ast` and `regex` directly from the source code. The
|
||||
error happens because `pip` will download [Python wheels](https://pythonwheels.com/) if
|
||||
they are available. Python wheels are a new standard of distributing Python packages and
|
||||
packages that have Cython and extensions written in C are already compiled, so the
|
||||
installation is much more faster. The problem here is that somehow the Python
|
||||
environment inside Vim does not match with those already compiled C extensions and these
|
||||
kind of errors are the result. Luckily there is an easy fix: installing the packages
|
||||
from the source code.
|
||||
|
||||
The two packages that cause the problem are:
|
||||
|
||||
- [regex](https://pypi.org/project/regex/)
|
||||
- [typed-ast](https://pypi.org/project/typed-ast/)
|
||||
|
||||
Now remove those two packages:
|
||||
|
||||
```console
|
||||
$ pip uninstall regex typed-ast -y
|
||||
```
|
||||
|
||||
And now you can install them with:
|
||||
|
||||
```console
|
||||
$ pip install --no-binary :all: regex typed-ast
|
||||
```
|
||||
|
||||
The C extensions will be compiled and now Vim's Python environment will match. Note that
|
||||
you need to have the GCC compiler and the Python development files installed (on
|
||||
Ubuntu/Debian do `sudo apt-get install build-essential python3-dev`).
|
||||
|
||||
If you later want to update _Black_, you should do it like this:
|
||||
|
||||
```console
|
||||
$ pip install -U black --no-binary regex,typed-ast
|
||||
```
|
||||
|
||||
### With ALE
|
||||
|
||||
1. Install [`ale`](https://github.com/dense-analysis/ale)
|
||||
2. Install `black`
|
||||
3. Add this to your vimrc:
|
||||
|
||||
```vim
|
||||
let g:ale_fixers = {}
|
||||
let g:ale_fixers.python = ['black']
|
||||
```
|
||||
|
||||
## 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`
|
||||
2. Search for `external tools` and activate it.
|
||||
3. In `Tools menu -> Manage external tools`
|
||||
4. Add a new tool using `+` button.
|
||||
5. Copy the below content to the code window.
|
||||
|
||||
```console
|
||||
#!/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/editing#_formatting)).
|
||||
|
||||
## SublimeText 3
|
||||
|
||||
Use [sublack plugin](https://github.com/jgirardet/sublack).
|
||||
|
||||
## Jupyter Notebook Magic
|
||||
|
||||
Use [blackcellmagic](https://github.com/csurfer/blackcellmagic).
|
||||
|
||||
## Python Language 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 Language Server](https://github.com/palantir/python-language-server) with the
|
||||
[pyls-black](https://github.com/rupert/pyls-black) plugin.
|
||||
|
||||
## Atom/Nuclide
|
||||
|
||||
Use [python-black](https://atom.io/packages/python-black) or
|
||||
[formatters-python](https://atom.io/packages/formatters-python).
|
||||
|
||||
## Gradle (the build tool)
|
||||
|
||||
Use the [Spotless](https://github.com/diffplug/spotless/tree/main/plugin-gradle) 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-code-format](https://github.com/Franccisco/thonny-black-code-format).
|
||||
|
||||
## Other integrations
|
||||
|
||||
Other editors and tools will require external contributions.
|
||||
|
||||
Patches welcome! ✨ 🍰 ✨
|
||||
|
||||
Any tool that can pipe code through _Black_ using its stdio mode (just
|
||||
[use `-` as the file name](https://www.tldp.org/LDP/abs/html/special-chars.html#DASHREF2)).
|
||||
The formatted code will be returned on stdout (unless `--check` was passed). _Black_
|
||||
will still emit messages on stderr but that shouldn't affect your use case.
|
||||
|
||||
This can be used for example with PyCharm's or IntelliJ's
|
||||
[File Watchers](https://www.jetbrains.com/help/pycharm/file-watchers.html).
|
139
docs/faq.md
139
docs/faq.md
@ -1,139 +0,0 @@
|
||||
# Frequently Asked Questions
|
||||
|
||||
The most common questions and issues users face are aggregated to this FAQ.
|
||||
|
||||
```{contents}
|
||||
:local:
|
||||
:backlinks: none
|
||||
:class: this-will-duplicate-information-and-it-is-still-useful-here
|
||||
```
|
||||
|
||||
## Why spaces? I prefer tabs
|
||||
|
||||
PEP 8 recommends spaces over tabs, and they are used by most of the Python community.
|
||||
_Black_ provides no options to configure the indentation style, and requests for such
|
||||
options will not be considered.
|
||||
|
||||
However, we recognise that using tabs is an accessibility issue as well. While the
|
||||
option will never be added to _Black_, visually impaired developers may find conversion
|
||||
tools such as `expand/unexpand` (for Linux) useful when contributing to Python projects.
|
||||
A workflow might consist of e.g. setting up appropriate pre-commit and post-merge git
|
||||
hooks, and scripting `unexpand` to run after applying _Black_.
|
||||
|
||||
## Does Black have an API?
|
||||
|
||||
Not yet. _Black_ is fundamentally a command line tool. Many
|
||||
[integrations](/integrations/index.md) are provided, but a Python interface is not one
|
||||
of them. A simple API is being [planned](https://github.com/psf/black/issues/779)
|
||||
though.
|
||||
|
||||
## Is Black safe to use?
|
||||
|
||||
Yes. _Black_ is strictly about formatting, nothing else. Black strives to ensure that
|
||||
after formatting the AST is
|
||||
[checked](the_black_code_style/current_style.md#ast-before-and-after-formatting) with
|
||||
limited special cases where the code is allowed to differ. If issues are found, an error
|
||||
is raised and the file is left untouched. Magical comments that influence linters and
|
||||
other tools, such as `# noqa`, may be moved by _Black_. See below for more details.
|
||||
|
||||
## How stable is Black's style?
|
||||
|
||||
Stable. _Black_ aims to enforce one style and one style only, with some room for
|
||||
pragmatism. See [The Black Code Style](the_black_code_style/index.md) for more details.
|
||||
|
||||
Starting in 2022, the formatting output is stable for the releases made in the same year
|
||||
(other than unintentional bugs). At the beginning of every year, the first release will
|
||||
make changes to the stable style. It is possible to opt in to the latest formatting
|
||||
styles using the `--preview` flag.
|
||||
|
||||
## Why is my file not formatted?
|
||||
|
||||
Most likely because it is ignored in `.gitignore` or excluded with configuration. See
|
||||
[file collection and discovery](usage_and_configuration/file_collection_and_discovery.md)
|
||||
for details.
|
||||
|
||||
## Why is my Jupyter Notebook cell not formatted?
|
||||
|
||||
_Black_ is timid about formatting Jupyter Notebooks. Cells containing any of the
|
||||
following will not be formatted:
|
||||
|
||||
- automagics (e.g. `pip install black`)
|
||||
- non-Python cell magics (e.g. `%%writefile`). These can be added with the flag
|
||||
`--python-cell-magics`, e.g. `black --python-cell-magics writefile hello.ipynb`.
|
||||
- multiline magics, e.g.:
|
||||
|
||||
```python
|
||||
%timeit f(1, \
|
||||
2, \
|
||||
3)
|
||||
```
|
||||
|
||||
- code which `IPython`'s `TransformerManager` would transform magics into, e.g.:
|
||||
|
||||
```python
|
||||
get_ipython().system('ls')
|
||||
```
|
||||
|
||||
- invalid syntax, as it can't be safely distinguished from automagics in the absence of
|
||||
a running `IPython` kernel.
|
||||
|
||||
## Why does Flake8 report warnings?
|
||||
|
||||
Some of Flake8's rules conflict with Black's style. We recommend disabling these rules.
|
||||
See [Using _Black_ with other tools](labels/why-pycodestyle-warnings).
|
||||
|
||||
## Which Python versions does Black support?
|
||||
|
||||
_Black_ generally supports all Python versions supported by CPython (see
|
||||
[the Python devguide](https://devguide.python.org/versions/) for current information).
|
||||
We promise to support at least all Python versions that have not reached their end of
|
||||
life. This is the case for both running _Black_ and formatting code.
|
||||
|
||||
Support for formatting Python 2 code was removed in version 22.0. While we've made no
|
||||
plans to stop supporting older Python 3 minor versions immediately, their support might
|
||||
also be removed some time in the future without a deprecation period.
|
||||
|
||||
`await`/`async` as soft keywords/indentifiers are no longer supported as of 25.2.0.
|
||||
|
||||
Runtime support for 3.6 was removed in version 22.10.0, for 3.7 in version 23.7.0, and
|
||||
for 3.8 in version 24.10.0.
|
||||
|
||||
## Why does my linter or typechecker complain after I format my code?
|
||||
|
||||
Some linters and other tools use magical comments (e.g., `# noqa`, `# type: ignore`) to
|
||||
influence their behavior. While Black does its best to recognize such comments and leave
|
||||
them in the right place, this detection is not and cannot be perfect. Therefore, you'll
|
||||
sometimes have to manually move these comments to the right place after you format your
|
||||
codebase with _Black_.
|
||||
|
||||
## Can I run Black with PyPy?
|
||||
|
||||
Yes, there is support for PyPy 3.8 and higher.
|
||||
|
||||
## Why does Black not detect syntax errors in my code?
|
||||
|
||||
_Black_ is an autoformatter, not a Python linter or interpreter. Detecting all syntax
|
||||
errors is not a goal. It can format all code accepted by CPython (if you find an example
|
||||
where that doesn't hold, please report a bug!), but it may also format some code that
|
||||
CPython doesn't accept.
|
||||
|
||||
(labels/mypyc-support)=
|
||||
|
||||
## What is `compiled: yes/no` all about in the version output?
|
||||
|
||||
While _Black_ is indeed a pure Python project, we use [mypyc] to compile _Black_ into a
|
||||
C Python extension, usually doubling performance. These compiled wheels are available
|
||||
for 64-bit versions of Windows, Linux (via the manylinux standard), and macOS across all
|
||||
supported CPython versions.
|
||||
|
||||
Platforms including musl-based and/or ARM Linux distributions, and ARM Windows are
|
||||
currently **not** supported. These platforms will fall back to the slower pure Python
|
||||
wheel available on PyPI.
|
||||
|
||||
If you are experiencing exceptionally weird issues or even segfaults, you can try
|
||||
passing `--no-binary black` to your pip install invocation. This flag excludes all
|
||||
wheels (including the pure Python wheel), so this command will use the [sdist].
|
||||
|
||||
[mypyc]: https://mypyc.readthedocs.io/en/latest/
|
||||
[sdist]:
|
||||
https://packaging.python.org/en/latest/glossary/#term-Source-Distribution-or-sdist
|
@ -1,50 +0,0 @@
|
||||
# Getting Started
|
||||
|
||||
New to _Black_? Don't worry, you've found the perfect place to get started!
|
||||
|
||||
## Do you like the _Black_ code style?
|
||||
|
||||
Before using _Black_ on some of your code, it might be a good idea to first understand
|
||||
how _Black_ will format your code. _Black_ isn't for everyone and you may find something
|
||||
that is a dealbreaker for you personally, which is okay! The current _Black_ code style
|
||||
[is described here](./the_black_code_style/current_style.md).
|
||||
|
||||
## Try it out online
|
||||
|
||||
Also, you can try out _Black_ online for minimal fuss on the
|
||||
[Black Playground](https://black.vercel.app) generously created by José Padilla.
|
||||
|
||||
## Installation
|
||||
|
||||
_Black_ can be installed by running `pip install black`. It requires Python 3.9+ to run.
|
||||
If you want to format Jupyter Notebooks, install with `pip install "black[jupyter]"`.
|
||||
|
||||
If you use pipx, you can install Black with `pipx install black`.
|
||||
|
||||
If you can't wait for the latest _hotness_ and want to install from GitHub, use:
|
||||
|
||||
`pip install git+https://github.com/psf/black`
|
||||
|
||||
## Basic 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}...
|
||||
```
|
||||
|
||||
## Next steps
|
||||
|
||||
Took a look at [the _Black_ code style](./the_black_code_style/current_style.md) and
|
||||
tried out _Black_? Fantastic, you're ready for more. Why not explore some more on using
|
||||
_Black_ by reading
|
||||
[Usage and Configuration: The basics](./usage_and_configuration/the_basics.md).
|
||||
Alternatively, you can check out the
|
||||
[Introducing _Black_ to your project](./guides/introducing_black_to_your_project.md)
|
||||
guide.
|
27
docs/github_actions.md
Normal file
27
docs/github_actions.md
Normal file
@ -0,0 +1,27 @@
|
||||
[//]: # "NOTE: THIS FILE WAS AUTOGENERATED FROM README.md"
|
||||
|
||||
# GitHub Actions
|
||||
|
||||
Create a file named `.github/workflows/black.yml` inside your repository with:
|
||||
|
||||
```yaml
|
||||
name: Lint
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: psf/black@stable
|
||||
with:
|
||||
black_args: ". --check"
|
||||
```
|
||||
|
||||
## Inputs
|
||||
|
||||
### `black_args`
|
||||
|
||||
**optional**: Black input arguments. Defaults to `. --check --diff`.
|
@ -1,16 +0,0 @@
|
||||
# Guides
|
||||
|
||||
```{toctree}
|
||||
---
|
||||
hidden:
|
||||
---
|
||||
|
||||
introducing_black_to_your_project
|
||||
using_black_with_other_tools
|
||||
```
|
||||
|
||||
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`
|
@ -1,52 +0,0 @@
|
||||
# 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 like GitLab do not yet support
|
||||
ignoring revisions using their native blame UI.** So blame information will be cluttered
|
||||
with a reformatting commit on those platforms. (If you'd like this feature, there's an
|
||||
open issue for [GitLab](https://gitlab.com/gitlab-org/gitlab/-/issues/31423)).
|
||||
[GitHub supports `.git-blame-ignore-revs`](https://docs.github.com/en/repositories/working-with-files/using-files/viewing-a-file#ignore-commits-in-the-blame-view)
|
||||
by default in blame views however.
|
23
docs/ignoring_unmodified_files.md
Normal file
23
docs/ignoring_unmodified_files.md
Normal file
@ -0,0 +1,23 @@
|
||||
[//]: # "NOTE: THIS FILE WAS AUTOGENERATED FROM README.md"
|
||||
|
||||
# Ignoring unmodified files
|
||||
|
||||
_Black_ remembers files it has already formatted, unless the `--diff` flag is used or
|
||||
code is passed via standard input. This information is stored per-user. The exact
|
||||
location of the file depends on the _Black_ version and the system on which _Black_ is
|
||||
run. The file is non-portable. The standard location on common operating systems is:
|
||||
|
||||
- Windows:
|
||||
`C:\\Users\<username>\AppData\Local\black\black\Cache\<version>\cache.<line-length>.<file-mode>.pickle`
|
||||
- macOS:
|
||||
`/Users/<username>/Library/Caches/black/<version>/cache.<line-length>.<file-mode>.pickle`
|
||||
- Linux:
|
||||
`/home/<username>/.cache/black/<version>/cache.<line-length>.<file-mode>.pickle`
|
||||
|
||||
`file-mode` is an int flag that determines whether the file was formatted as 3.6+ only,
|
||||
as .pyi, and whether string normalization was omitted.
|
||||
|
||||
To override the location of these files on macOS or Linux, set the environment variable
|
||||
`XDG_CACHE_HOME` to your preferred location. For example, if you want to put the cache
|
||||
in the directory you're running _Black_ from, set `XDG_CACHE_HOME=.cache`. _Black_ will
|
||||
then write the above files to `.cache/black/<version>/`.
|
139
docs/index.md
139
docs/index.md
@ -1,139 +0,0 @@
|
||||
<!--
|
||||
black documentation master file, created by
|
||||
sphinx-quickstart on Fri Mar 23 10:53:30 2018.
|
||||
-->
|
||||
|
||||
# The uncompromising code formatter
|
||||
|
||||
> “Any color you like.”
|
||||
|
||||
By using _Black_, 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.
|
||||
|
||||
_Black_ makes code review faster by producing the smallest diffs possible. 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.
|
||||
|
||||
Try it out now using the [Black Playground](https://black.vercel.app).
|
||||
|
||||
```{admonition} Note - Black is now stable!
|
||||
*Black* is [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, our own auto formatting and parallel Continuous Integration runner.
|
||||
Now that we have become stable, you should not expect large changes to formatting in
|
||||
the future. Stylistic changes will mostly be responses to bug reports and support for new Python
|
||||
syntax.
|
||||
|
||||
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](./the_black_code_style/current_style.md#pragmatism)
|
||||
section for details). If you're feeling confident, use `--fast`.
|
||||
```
|
||||
|
||||
```{note}
|
||||
{doc}`Black is licensed under the MIT license <license>`.
|
||||
```
|
||||
|
||||
## Testimonials
|
||||
|
||||
**Mike Bayer**, author 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://smile.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Daps&field-keywords=dusty+phillips):
|
||||
|
||||
> _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](http://python-requests.org/) and
|
||||
[pipenv](https://docs.pipenv.org/):
|
||||
|
||||
> _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:
|
||||
|
||||
```{image} https://img.shields.io/badge/code%20style-black-000000.svg
|
||||
:target: https://github.com/psf/black
|
||||
```
|
||||
|
||||
## Contents
|
||||
|
||||
```{toctree}
|
||||
---
|
||||
maxdepth: 3
|
||||
includehidden:
|
||||
---
|
||||
|
||||
the_black_code_style/index
|
||||
```
|
||||
|
||||
```{toctree}
|
||||
---
|
||||
maxdepth: 3
|
||||
includehidden:
|
||||
caption: User Guide
|
||||
---
|
||||
|
||||
getting_started
|
||||
usage_and_configuration/index
|
||||
integrations/index
|
||||
guides/index
|
||||
faq
|
||||
```
|
||||
|
||||
```{toctree}
|
||||
---
|
||||
maxdepth: 2
|
||||
includehidden:
|
||||
caption: Development
|
||||
---
|
||||
|
||||
contributing/index
|
||||
change_log
|
||||
authors
|
||||
```
|
||||
|
||||
```{toctree}
|
||||
---
|
||||
hidden:
|
||||
caption: Project Links
|
||||
---
|
||||
|
||||
GitHub <https://github.com/psf/black>
|
||||
PyPI <https://pypi.org/project/black>
|
||||
Chat <https://discord.gg/RtVdv86PrH>
|
||||
```
|
||||
|
||||
# Indices and tables
|
||||
|
||||
- {ref}`genindex`
|
||||
- {ref}`search`
|
71
docs/index.rst
Normal file
71
docs/index.rst
Normal file
@ -0,0 +1,71 @@
|
||||
.. black documentation master file, created by
|
||||
sphinx-quickstart on Fri Mar 23 10:53:30 2018.
|
||||
|
||||
The uncompromising code formatter
|
||||
=================================
|
||||
|
||||
By using *Black*, 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.
|
||||
|
||||
*Black* makes code review faster by producing the smallest diffs
|
||||
possible. 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.
|
||||
|
||||
Try it out now using the `Black Playground <https://black.now.sh>`_.
|
||||
|
||||
.. note::
|
||||
|
||||
`Black is beta <installation_and_usage.html#note-this-is-a-beta-product>`_.
|
||||
|
||||
|
||||
Testimonials
|
||||
------------
|
||||
|
||||
**Dusty Phillips**, `writer <https://smile.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Daps&field-keywords=dusty+phillips>`_:
|
||||
|
||||
*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 <http://python-requests.org/>`_
|
||||
and `pipenv <https://docs.pipenv.org/>`_:
|
||||
|
||||
*This vastly improves the formatting of our code. Thanks a ton!*
|
||||
|
||||
Contents
|
||||
--------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
installation_and_usage
|
||||
the_black_code_style
|
||||
pyproject_toml
|
||||
compatible_configs
|
||||
editor_integration
|
||||
blackd
|
||||
black_primer
|
||||
version_control_integration
|
||||
github_actions
|
||||
ignoring_unmodified_files
|
||||
contributing_to_black
|
||||
show_your_style
|
||||
change_log
|
||||
reference/reference_summary
|
||||
authors
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`search`
|
195
docs/installation_and_usage.md
Normal file
195
docs/installation_and_usage.md
Normal file
@ -0,0 +1,195 @@
|
||||
[//]: # "NOTE: THIS FILE WAS AUTOGENERATED FROM README.md"
|
||||
|
||||
# Installation and usage
|
||||
|
||||
## Installation
|
||||
|
||||
_Black_ can be installed by running `pip install black`. It requires Python 3.6.0+ to
|
||||
run but you can reformat Python 2 code with it, too.
|
||||
|
||||
### Install from GitHub
|
||||
|
||||
If you can't wait for the latest _hotness_ and want to install from GitHub, use:
|
||||
|
||||
`pip install git+git://github.com/psf/black`
|
||||
|
||||
## 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}
|
||||
```
|
||||
|
||||
## Command line options
|
||||
|
||||
_Black_ doesn't provide many options. You can list them by running `black --help`:
|
||||
|
||||
```text
|
||||
Usage: black [OPTIONS] [SRC]...
|
||||
|
||||
The uncompromising code formatter.
|
||||
|
||||
Options:
|
||||
-c, --code TEXT Format the code passed in as a string.
|
||||
-l, --line-length INTEGER How many characters per line to allow.
|
||||
[default: 88]
|
||||
|
||||
-t, --target-version [py27|py33|py34|py35|py36|py37|py38|py39]
|
||||
Python versions that should be supported by
|
||||
Black's output. [default: per-file auto-
|
||||
detection]
|
||||
|
||||
--pyi Format all input files like typing stubs
|
||||
regardless of file extension (useful when
|
||||
piping source on standard input).
|
||||
|
||||
-S, --skip-string-normalization
|
||||
Don't normalize string quotes or prefixes.
|
||||
-C, --skip-magic-trailing-comma
|
||||
Don't use trailing commas as a reason to
|
||||
split lines.
|
||||
|
||||
--check Don't write the files back, just return the
|
||||
status. Return code 0 means nothing would
|
||||
change. Return code 1 means some files
|
||||
would be reformatted. Return code 123 means
|
||||
there was an internal error.
|
||||
|
||||
--diff Don't write the files back, just output a
|
||||
diff for each file on stdout.
|
||||
|
||||
--color / --no-color Show colored diff. Only applies when
|
||||
`--diff` is given.
|
||||
|
||||
--fast / --safe If --fast given, skip temporary sanity
|
||||
checks. [default: --safe]
|
||||
|
||||
--include TEXT A regular expression that matches files and
|
||||
directories that should be included on
|
||||
recursive searches. An empty value means
|
||||
all files are included regardless of the
|
||||
name. Use forward slashes for directories
|
||||
on all platforms (Windows, too). Exclusions
|
||||
are calculated first, inclusions later.
|
||||
[default: \.pyi?$]
|
||||
|
||||
--exclude TEXT A regular expression that matches files and
|
||||
directories that should be excluded on
|
||||
recursive searches. An empty value means no
|
||||
paths are excluded. Use forward slashes for
|
||||
directories on all platforms (Windows, too).
|
||||
Exclusions are calculated first, inclusions
|
||||
later. [default: /(\.direnv|\.eggs|\.git|\.
|
||||
hg|\.mypy_cache|\.nox|\.tox|\.venv|venv|\.sv
|
||||
n|_build|buck-out|build|dist)/]
|
||||
|
||||
--force-exclude TEXT Like --exclude, but files and directories
|
||||
matching this regex will be excluded even
|
||||
when they are passed explicitly as
|
||||
arguments.
|
||||
|
||||
--extend-exclude TEXT Like --exclude, but adds additional files
|
||||
and directories on top of the excluded
|
||||
ones. (useful if you simply want to add to
|
||||
the default)
|
||||
|
||||
--stdin-filename TEXT The name of the file when passing it through
|
||||
stdin. Useful to make sure Black will
|
||||
respect --force-exclude option on some
|
||||
editors that rely on using stdin.
|
||||
|
||||
-q, --quiet Don't emit non-error messages to stderr.
|
||||
Errors are still emitted; silence those with
|
||||
2>/dev/null.
|
||||
|
||||
-v, --verbose Also emit messages to stderr about files
|
||||
that were not changed or were ignored due to
|
||||
exclusion patterns.
|
||||
|
||||
--version Show the version and exit.
|
||||
--config FILE Read configuration from FILE path.
|
||||
-h, --help Show this message and exit.
|
||||
```
|
||||
|
||||
_Black_ is a well-behaved Unix-style command-line tool:
|
||||
|
||||
- it does nothing if no sources are passed to it;
|
||||
- it will read from standard input and write to standard output if `-` is used as the
|
||||
filename;
|
||||
- it only outputs messages to users on standard error;
|
||||
- exits with code 0 unless an internal error occurred (or `--check` was used).
|
||||
|
||||
## Using _Black_ with other tools
|
||||
|
||||
While _Black_ enforces formatting that conforms to PEP 8, other tools may raise warnings
|
||||
about _Black_'s changes or will overwrite _Black_'s changes. A good example of this is
|
||||
[isort](https://pypi.org/p/isort). Since _Black_ is barely configurable, these tools
|
||||
should be configured to neither warn about nor overwrite _Black_'s changes.
|
||||
|
||||
Actual details on _Black_ compatible configurations for various tools can be found in
|
||||
[compatible_configs](https://github.com/psf/black/blob/master/docs/compatible_configs.md#black-compatible-configurations).
|
||||
|
||||
## Migrating your code style without 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.
|
||||
|
||||
```
|
||||
# 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 GitHub and GitLab do not yet support ignoring revisions using
|
||||
their native UI of blame.** So blame information will be cluttered with a reformatting
|
||||
commit on those platforms. (If you'd like this feature, there's an open issue for
|
||||
[GitLab](https://gitlab.com/gitlab-org/gitlab/-/issues/31423) and please let GitHub
|
||||
know!)
|
||||
|
||||
## NOTE: This is a beta product
|
||||
|
||||
_Black_ is already [successfully used](https://github.com/psf/black#used-by) by many
|
||||
projects, small and big. It also sports a decent test suite. However, it is still very
|
||||
new. Things will probably be wonky for a while. This is made explicit by the "Beta"
|
||||
trove classifier, as well as by the "b" in the version number. What this means for you
|
||||
is that **until the formatter becomes stable, you should expect some formatting to
|
||||
change in the future**. That being said, no drastic stylistic changes are planned,
|
||||
mostly responses to bug reports.
|
||||
|
||||
Also, as a temporary safety measure, _Black_ will check that the reformatted code still
|
||||
produces a valid AST that is equivalent to the original. This slows it down. If you're
|
||||
feeling confident, use `--fast`.
|
@ -1,435 +0,0 @@
|
||||
# Editor integration
|
||||
|
||||
## Emacs
|
||||
|
||||
Options include the following:
|
||||
|
||||
- [wbolster/emacs-python-black](https://github.com/wbolster/emacs-python-black)
|
||||
- [proofit404/blacken](https://github.com/pythonic-emacs/blacken)
|
||||
- [Elpy](https://github.com/jorgenschaefer/elpy).
|
||||
|
||||
## 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 </usage_and_configuration/black_as_a_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
|
||||
%LocalAppData%\Programs\Python\Python36-32\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: \<install_location_from_step_2>
|
||||
- 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
|
||||
%LocalAppData%\Programs\Python\Python36-32\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: \<install_location_from_step_2>
|
||||
- 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:
|
||||
|
||||
### Prerequistes
|
||||
|
||||
- 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.9+ support**. It needs Python 3.9 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://github.com/junegunn/vim-plug):
|
||||
|
||||
_Black_'s `stable` branch tracks official version updates, and can be used to simply
|
||||
follow the most recent stable version.
|
||||
|
||||
```
|
||||
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):
|
||||
|
||||
```
|
||||
Plug 'psf/black', { 'tag': '*.*.*' }
|
||||
```
|
||||
|
||||
and the following demonstrates pinning to a specific year's stable style (2022 in this
|
||||
case):
|
||||
|
||||
```
|
||||
Plug 'psf/black', { 'tag': '22.*.*' }
|
||||
```
|
||||
|
||||
##### Vundle
|
||||
|
||||
or with [Vundle](https://github.com/VundleVim/Vundle.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).
|
||||
|
||||
```
|
||||
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:
|
||||
|
||||
```
|
||||
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`:
|
||||
|
||||
```
|
||||
augroup black_on_save
|
||||
autocmd!
|
||||
autocmd BufWritePre *.py Black
|
||||
augroup end
|
||||
```
|
||||
|
||||
To run _Black_ on a key press (e.g. F9 below), add this:
|
||||
|
||||
```
|
||||
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']
|
||||
```
|
||||
|
||||
## 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.
|
||||
|
||||
```console
|
||||
#!/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
|
||||
|
||||
For SublimeText 3, use [sublack plugin](https://github.com/jgirardet/sublack). For
|
||||
higher versions, it is recommended to use [LSP](#python-lsp-server) as documented below.
|
||||
|
||||
## 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.
|
||||
|
||||
## Atom/Nuclide
|
||||
|
||||
Use [python-black](https://atom.io/packages/python-black) or
|
||||
[formatters-python](https://atom.io/packages/formatters-python).
|
||||
|
||||
## Gradle (the build tool)
|
||||
|
||||
Use the [Spotless](https://github.com/diffplug/spotless/tree/main/plugin-gradle) 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://pypi.org/project/thonny-black-formatter/).
|
@ -1,90 +0,0 @@
|
||||
# GitHub Actions integration
|
||||
|
||||
You can use _Black_ within a GitHub Actions workflow without setting your own Python
|
||||
environment. Great for enforcing that your code matches the _Black_ code style.
|
||||
|
||||
## Compatibility
|
||||
|
||||
This action is known to support all GitHub-hosted runner OSes. In addition, only
|
||||
published versions of _Black_ are supported (i.e. whatever is available on PyPI).
|
||||
|
||||
Finally, this action installs _Black_ with the `colorama` extra so the `--color` flag
|
||||
should work fine.
|
||||
|
||||
## Usage
|
||||
|
||||
Create a file named `.github/workflows/black.yml` inside your repository with:
|
||||
|
||||
```yaml
|
||||
name: Lint
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: psf/black@stable
|
||||
```
|
||||
|
||||
We recommend the use of the `@stable` tag, but per version tags also exist if you prefer
|
||||
that. Note that the action's version you select is independent of the version of _Black_
|
||||
the action will use.
|
||||
|
||||
The version of _Black_ the action will use can be configured via `version` or read from
|
||||
the `pyproject.toml` file. `version` can be any
|
||||
[valid version specifier](https://packaging.python.org/en/latest/glossary/#term-Version-Specifier)
|
||||
or just the version number if you want an exact version. To read the version from the
|
||||
`pyproject.toml` file instead, set `use_pyproject` to `true`. This will first look into
|
||||
the `tool.black.required-version` field, then the `dependency-groups` table, then the
|
||||
`project.dependencies` array and finally the `project.optional-dependencies` table. The
|
||||
action defaults to the latest release available on PyPI. Only versions available from
|
||||
PyPI are supported, so no commit SHAs or branch names.
|
||||
|
||||
If you want to include Jupyter Notebooks, _Black_ must be installed with the `jupyter`
|
||||
extra. Installing the extra and including Jupyter Notebook files can be configured via
|
||||
`jupyter` (default is `false`).
|
||||
|
||||
You can also configure the arguments passed to _Black_ via `options` (defaults to
|
||||
`'--check --diff'`) and `src` (default is `'.'`). Please note that the
|
||||
[`--check` flag](labels/exit-code) is required so that the workflow fails if _Black_
|
||||
finds files that need to be formatted.
|
||||
|
||||
Here's an example configuration:
|
||||
|
||||
```yaml
|
||||
- uses: psf/black@stable
|
||||
with:
|
||||
options: "--check --verbose"
|
||||
src: "./src"
|
||||
jupyter: true
|
||||
version: "21.5b1"
|
||||
```
|
||||
|
||||
If you want to match versions covered by Black's
|
||||
[stability policy](labels/stability-policy), you can use the compatible release operator
|
||||
(`~=`):
|
||||
|
||||
```yaml
|
||||
- uses: psf/black@stable
|
||||
with:
|
||||
options: "--check --verbose"
|
||||
src: "./src"
|
||||
version: "~= 22.0"
|
||||
```
|
||||
|
||||
If you want to read the version from `pyproject.toml`, set `use_pyproject` to `true`.
|
||||
Note that this requires Python >= 3.11, so using the setup-python action may be
|
||||
required, for example:
|
||||
|
||||
```yaml
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.13"
|
||||
- uses: psf/black@stable
|
||||
with:
|
||||
options: "--check --verbose"
|
||||
src: "./src"
|
||||
use_pyproject: true
|
||||
```
|
@ -1,31 +0,0 @@
|
||||
# Integrations
|
||||
|
||||
```{toctree}
|
||||
---
|
||||
hidden:
|
||||
---
|
||||
|
||||
editors
|
||||
github_actions
|
||||
source_version_control
|
||||
```
|
||||
|
||||
_Black_ can be integrated into many environments, providing a better and smoother
|
||||
experience. Documentation for integrating _Black_ with a tool can be found for the
|
||||
following areas:
|
||||
|
||||
- {doc}`Editor / IDE <./editors>`
|
||||
- {doc}`GitHub Actions <./github_actions>`
|
||||
- {doc}`Source version control <./source_version_control>`
|
||||
|
||||
Editors and tools not listed will require external contributions.
|
||||
|
||||
Patches welcome! ✨ 🍰 ✨
|
||||
|
||||
Any tool can pipe code through _Black_ using its stdio mode (just
|
||||
[use `-` as the file name](https://www.tldp.org/LDP/abs/html/special-chars.html#DASHREF2)).
|
||||
The formatted code will be returned on stdout (unless `--check` was passed). _Black_
|
||||
will still emit messages on stderr but that shouldn't affect your use case.
|
||||
|
||||
This can be used for example with PyCharm's or IntelliJ's
|
||||
[File Watchers](https://www.jetbrains.com/help/pycharm/file-watchers.html).
|
@ -1,53 +0,0 @@
|
||||
# Version control integration
|
||||
|
||||
Use [pre-commit](https://pre-commit.com/). Once you
|
||||
[have it installed](https://pre-commit.com/#install), add this to the
|
||||
`.pre-commit-config.yaml` in your repository:
|
||||
|
||||
```yaml
|
||||
repos:
|
||||
# Using this mirror lets us use mypyc-compiled black, which is about 2x faster
|
||||
- repo: https://github.com/psf/black-pre-commit-mirror
|
||||
rev: 25.1.0
|
||||
hooks:
|
||||
- id: black
|
||||
# It is recommended to specify the latest version of Python
|
||||
# supported by your project here, or alternatively use
|
||||
# pre-commit's default_language_version, see
|
||||
# https://pre-commit.com/#top_level-default_language_version
|
||||
language_version: python3.11
|
||||
```
|
||||
|
||||
Feel free to switch out the `rev` value to a different version of Black.
|
||||
|
||||
Note if you'd like to use a specific commit in `rev`, you'll need to swap the repo
|
||||
specified from the mirror to https://github.com/psf/black. We discourage the use of
|
||||
branches or other mutable refs since the hook [won't auto update as you may
|
||||
expect][pre-commit-mutable-rev].
|
||||
|
||||
## Jupyter Notebooks
|
||||
|
||||
There is an alternate hook `black-jupyter` that expands the targets of `black` to
|
||||
include Jupyter Notebooks. To use this hook, simply replace the hook's `id: black` with
|
||||
`id: black-jupyter` in the `.pre-commit-config.yaml`:
|
||||
|
||||
```yaml
|
||||
repos:
|
||||
# Using this mirror lets us use mypyc-compiled black, which is about 2x faster
|
||||
- repo: https://github.com/psf/black-pre-commit-mirror
|
||||
rev: 25.1.0
|
||||
hooks:
|
||||
- id: black-jupyter
|
||||
# It is recommended to specify the latest version of Python
|
||||
# supported by your project here, or alternatively use
|
||||
# pre-commit's default_language_version, see
|
||||
# https://pre-commit.com/#top_level-default_language_version
|
||||
language_version: python3.11
|
||||
```
|
||||
|
||||
```{note}
|
||||
The `black-jupyter` hook became available in version 21.8b0.
|
||||
```
|
||||
|
||||
[pre-commit-mutable-rev]:
|
||||
https://pre-commit.com/#using-the-latest-version-for-a-repository
|
@ -1,9 +0,0 @@
|
||||
---
|
||||
orphan: true
|
||||
---
|
||||
|
||||
# License
|
||||
|
||||
```{include} ../LICENSE
|
||||
|
||||
```
|
91
docs/pyproject_toml.md
Normal file
91
docs/pyproject_toml.md
Normal file
@ -0,0 +1,91 @@
|
||||
[//]: # "NOTE: THIS FILE WAS AUTOGENERATED FROM README.md"
|
||||
|
||||
# pyproject.toml
|
||||
|
||||
_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.
|
||||
|
||||
**Pro-tip**: If you're asking yourself "Do I need to configure anything?" the answer is
|
||||
"No". _Black_ is all about sensible defaults.
|
||||
|
||||
## What on Earth is a `pyproject.toml` file?
|
||||
|
||||
[PEP 518](https://www.python.org/dev/peps/pep-0518/) defines `pyproject.toml` as a
|
||||
configuration file to store build system requirements for Python projects. With the help
|
||||
of tools like [Poetry](https://python-poetry.org/) or
|
||||
[Flit](https://flit.readthedocs.io/en/latest/) it can fully replace the need for
|
||||
`setup.py` and `setup.cfg` files.
|
||||
|
||||
## Where _Black_ looks for the file
|
||||
|
||||
By default _Black_ looks for `pyproject.toml` starting from the common base directory of
|
||||
all files and directories passed on the command line. If it's not there, it looks in
|
||||
parent directories. It stops looking when it finds the file, or a `.git` directory, or a
|
||||
`.hg` directory, or the root of the file system, whichever comes first.
|
||||
|
||||
If you're formatting standard input, _Black_ will look for configuration starting from
|
||||
the current working directory.
|
||||
|
||||
You can use a "global" configuration, stored in a specific location in your home
|
||||
directory. This will be used as a fallback configuration, that is, it will be used if
|
||||
and only if _Black_ doesn't find any configuration as mentioned above. Depending on your
|
||||
operating system, this configuration file should be stored as:
|
||||
|
||||
- Windows: `~\.black`
|
||||
- Unix-like (Linux, MacOS, etc.): `$XDG_CONFIG_HOME/black` (`~/.config/black` if the
|
||||
`XDG_CONFIG_HOME` environment variable is not set)
|
||||
|
||||
Note that these are paths to the TOML file itself (meaning that they shouldn't be named
|
||||
as `pyproject.toml`), not directories where you store the configuration. Here, `~`
|
||||
refers to the path to your home directory. On Windows, this will be something like
|
||||
`C:\\Users\UserName`.
|
||||
|
||||
You can also explicitly specify the path to a particular file that you want with
|
||||
`--config`. In this situation _Black_ will not look for any other file.
|
||||
|
||||
If you're running with `--verbose`, you will see a blue message if a file was found and
|
||||
used.
|
||||
|
||||
Files listed within a projects `.gitignore` file will not be formatted by _Black_.
|
||||
|
||||
Please note `blackd` will not use `pyproject.toml` configuration.
|
||||
|
||||
## Configuration format
|
||||
|
||||
As the file extension suggests, `pyproject.toml` is a
|
||||
[TOML](https://github.com/toml-lang/toml) file. It contains separate sections for
|
||||
different tools. _Black_ is using the `[tool.black]` section. The option keys are the
|
||||
same as long names of options on the command line.
|
||||
|
||||
Note that you have to use single-quoted strings in TOML for regular expressions. It's
|
||||
the equivalent of r-strings in Python. Multiline strings are treated as verbose regular
|
||||
expressions by Black. Use `[ ]` to denote a significant space character.
|
||||
|
||||
<details>
|
||||
<summary>Example <code>pyproject.toml</code></summary>
|
||||
|
||||
```toml
|
||||
[tool.black]
|
||||
line-length = 88
|
||||
target-version = ['py37']
|
||||
include = '\.pyi?$'
|
||||
extend-exclude = '''
|
||||
# A regex preceded with ^/ will apply only to files and directories
|
||||
# in the root of the project.
|
||||
^/foo.py # exclude a file named foo.py in the root of the project (in addition to the defaults)
|
||||
'''
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Lookup hierarchy
|
||||
|
||||
Command-line options have defaults that you can see in `--help`. A `pyproject.toml` can
|
||||
override those defaults. Finally, options provided by the user on the command line
|
||||
override both.
|
||||
|
||||
_Black_ will only ever use one `pyproject.toml` file during an entire run. It doesn't
|
||||
look for multiple files, and doesn't compose configuration from different levels of the
|
||||
file hierarchy.
|
76
docs/reference/reference_classes.rst
Normal file
76
docs/reference/reference_classes.rst
Normal file
@ -0,0 +1,76 @@
|
||||
*Black* classes
|
||||
===============
|
||||
|
||||
*Contents are subject to change.*
|
||||
|
||||
.. currentmodule:: black
|
||||
|
||||
:class:`BracketTracker`
|
||||
-----------------------
|
||||
|
||||
.. autoclass:: black.BracketTracker
|
||||
:members:
|
||||
|
||||
:class:`EmptyLineTracker`
|
||||
-------------------------
|
||||
|
||||
.. autoclass:: black.EmptyLineTracker
|
||||
:members:
|
||||
|
||||
:class:`Line`
|
||||
-------------
|
||||
|
||||
.. autoclass:: black.Line
|
||||
:members:
|
||||
:special-members: __str__, __bool__
|
||||
|
||||
:class:`LineGenerator`
|
||||
----------------------
|
||||
|
||||
.. autoclass:: black.LineGenerator
|
||||
:show-inheritance:
|
||||
:members:
|
||||
|
||||
:class:`ProtoComment`
|
||||
---------------------
|
||||
|
||||
.. autoclass:: black.ProtoComment
|
||||
:members:
|
||||
|
||||
:class:`Report`
|
||||
---------------
|
||||
|
||||
.. autoclass:: black.Report
|
||||
:members:
|
||||
:special-members: __str__
|
||||
|
||||
:class:`Visitor`
|
||||
----------------
|
||||
|
||||
.. autoclass:: black.Visitor
|
||||
:show-inheritance:
|
||||
:members:
|
||||
|
||||
Enums
|
||||
=====
|
||||
|
||||
:class:`Changed`
|
||||
----------------
|
||||
|
||||
.. autoclass:: black.Changed
|
||||
:show-inheritance:
|
||||
:members:
|
||||
|
||||
:class:`Mode`
|
||||
-----------------
|
||||
|
||||
.. autoclass:: black.Mode
|
||||
:show-inheritance:
|
||||
:members:
|
||||
|
||||
:class:`WriteBack`
|
||||
------------------
|
||||
|
||||
.. autoclass:: black.WriteBack
|
||||
:show-inheritance:
|
||||
:members:
|
12
docs/reference/reference_exceptions.rst
Normal file
12
docs/reference/reference_exceptions.rst
Normal file
@ -0,0 +1,12 @@
|
||||
*Black* exceptions
|
||||
==================
|
||||
|
||||
*Contents are subject to change.*
|
||||
|
||||
.. currentmodule:: black
|
||||
|
||||
.. autoexception:: black.CannotSplit
|
||||
|
||||
.. autoexception:: black.NothingChanged
|
||||
|
||||
.. autoexception:: black.InvalidInput
|
180
docs/reference/reference_functions.rst
Normal file
180
docs/reference/reference_functions.rst
Normal file
@ -0,0 +1,180 @@
|
||||
*Black* functions
|
||||
=================
|
||||
|
||||
*Contents are subject to change.*
|
||||
|
||||
.. currentmodule:: black
|
||||
|
||||
Assertions and checks
|
||||
---------------------
|
||||
|
||||
.. autofunction:: black.assert_equivalent
|
||||
|
||||
.. autofunction:: black.assert_stable
|
||||
|
||||
.. autofunction:: black.can_be_split
|
||||
|
||||
.. autofunction:: black.can_omit_invisible_parens
|
||||
|
||||
.. autofunction:: black.is_empty_tuple
|
||||
|
||||
.. autofunction:: black.is_import
|
||||
|
||||
.. autofunction:: black.is_line_short_enough
|
||||
|
||||
.. autofunction:: black.is_multiline_string
|
||||
|
||||
.. autofunction:: black.is_one_tuple
|
||||
|
||||
.. autofunction:: black.is_split_after_delimiter
|
||||
|
||||
.. autofunction:: black.is_split_before_delimiter
|
||||
|
||||
.. autofunction:: black.is_stub_body
|
||||
|
||||
.. autofunction:: black.is_stub_suite
|
||||
|
||||
.. autofunction:: black.is_vararg
|
||||
|
||||
.. autofunction:: black.is_yield
|
||||
|
||||
|
||||
Formatting
|
||||
----------
|
||||
|
||||
.. autofunction:: black.format_file_contents
|
||||
|
||||
.. autofunction:: black.format_file_in_place
|
||||
|
||||
.. autofunction:: black.format_stdin_to_stdout
|
||||
|
||||
.. autofunction:: black.format_str
|
||||
|
||||
.. autofunction:: black.reformat_one
|
||||
|
||||
.. autofunction:: black.schedule_formatting
|
||||
|
||||
File operations
|
||||
---------------
|
||||
|
||||
.. autofunction:: black.dump_to_file
|
||||
|
||||
.. autofunction:: black.find_project_root
|
||||
|
||||
.. autofunction:: black.gen_python_files
|
||||
|
||||
.. autofunction:: black.read_pyproject_toml
|
||||
|
||||
Parsing
|
||||
-------
|
||||
|
||||
.. autofunction:: black.decode_bytes
|
||||
|
||||
.. autofunction:: black.lib2to3_parse
|
||||
|
||||
.. autofunction:: black.lib2to3_unparse
|
||||
|
||||
Split functions
|
||||
---------------
|
||||
|
||||
.. autofunction:: black.bracket_split_build_line
|
||||
|
||||
.. autofunction:: black.bracket_split_succeeded_or_raise
|
||||
|
||||
.. autofunction:: black.delimiter_split
|
||||
|
||||
.. autofunction:: black.left_hand_split
|
||||
|
||||
.. autofunction:: black.right_hand_split
|
||||
|
||||
.. autofunction:: black.standalone_comment_split
|
||||
|
||||
.. autofunction:: black.transform_line
|
||||
|
||||
Caching
|
||||
-------
|
||||
|
||||
.. autofunction:: black.filter_cached
|
||||
|
||||
.. autofunction:: black.get_cache_file
|
||||
|
||||
.. autofunction:: black.get_cache_info
|
||||
|
||||
.. autofunction:: black.read_cache
|
||||
|
||||
.. autofunction:: black.write_cache
|
||||
|
||||
Utilities
|
||||
---------
|
||||
|
||||
.. py:function:: black.DebugVisitor.show(code: str) -> None
|
||||
|
||||
Pretty-print the lib2to3 AST of a given string of `code`.
|
||||
|
||||
.. autofunction:: black.cancel
|
||||
|
||||
.. autofunction:: black.child_towards
|
||||
|
||||
.. autofunction:: black.container_of
|
||||
|
||||
.. autofunction:: black.convert_one_fmt_off_pair
|
||||
|
||||
.. autofunction:: black.diff
|
||||
|
||||
.. autofunction:: black.dont_increase_indentation
|
||||
|
||||
.. autofunction:: black.format_float_or_int_string
|
||||
|
||||
.. autofunction:: black.ensure_visible
|
||||
|
||||
.. autofunction:: black.enumerate_reversed
|
||||
|
||||
.. autofunction:: black.enumerate_with_length
|
||||
|
||||
.. autofunction:: black.generate_comments
|
||||
|
||||
.. autofunction:: black.generate_ignored_nodes
|
||||
|
||||
.. autofunction:: black.is_fmt_on
|
||||
|
||||
.. autofunction:: black.contains_fmt_on_at_column
|
||||
|
||||
.. autofunction:: black.first_leaf_column
|
||||
|
||||
.. autofunction:: black.generate_trailers_to_omit
|
||||
|
||||
.. autofunction:: black.get_future_imports
|
||||
|
||||
.. autofunction:: black.list_comments
|
||||
|
||||
.. autofunction:: black.make_comment
|
||||
|
||||
.. autofunction:: black.maybe_make_parens_invisible_in_atom
|
||||
|
||||
.. autofunction:: black.max_delimiter_priority_in_atom
|
||||
|
||||
.. autofunction:: black.normalize_fmt_off
|
||||
|
||||
.. autofunction:: black.normalize_numeric_literal
|
||||
|
||||
.. autofunction:: black.normalize_prefix
|
||||
|
||||
.. autofunction:: black.normalize_string_prefix
|
||||
|
||||
.. autofunction:: black.normalize_string_quotes
|
||||
|
||||
.. autofunction:: black.normalize_invisible_parens
|
||||
|
||||
.. autofunction:: black.patch_click
|
||||
|
||||
.. autofunction:: black.preceding_leaf
|
||||
|
||||
.. autofunction:: black.re_compile_maybe_verbose
|
||||
|
||||
.. autofunction:: black.should_split_line
|
||||
|
||||
.. autofunction:: black.shutdown
|
||||
|
||||
.. autofunction:: black.sub_twice
|
||||
|
||||
.. autofunction:: black.whitespace
|
11
docs/reference/reference_summary.rst
Normal file
11
docs/reference/reference_summary.rst
Normal file
@ -0,0 +1,11 @@
|
||||
Developer reference
|
||||
===================
|
||||
|
||||
*Contents are subject to change.*
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
reference_classes
|
||||
reference_functions
|
||||
reference_exceptions
|
@ -1,9 +1,3 @@
|
||||
# Used by ReadTheDocs; pinned requirements for stability.
|
||||
|
||||
myst-parser==4.0.1
|
||||
Sphinx==8.2.3
|
||||
# Older versions break Sphinx even though they're declared to be supported.
|
||||
docutils==0.21.2
|
||||
sphinxcontrib-programoutput==0.18
|
||||
sphinx_copybutton==0.5.2
|
||||
furo==2024.8.6
|
||||
recommonmark==0.6.0
|
||||
Sphinx==3.2.1
|
||||
Pygments==2.7.4
|
19
docs/show_your_style.md
Normal file
19
docs/show_your_style.md
Normal file
@ -0,0 +1,19 @@
|
||||
[//]: # "NOTE: THIS FILE WAS AUTOGENERATED FROM README.md"
|
||||
|
||||
# Show your style
|
||||
|
||||
Use the badge in your project's README.md:
|
||||
|
||||
```md
|
||||
[](https://github.com/psf/black)
|
||||
```
|
||||
|
||||
Using the badge in README.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)
|
@ -2,21 +2,18 @@
|
||||
|
||||
## Code style
|
||||
|
||||
_Black_ aims for consistency, generality, readability and reducing git diffs. Similar
|
||||
language constructs are formatted with similar rules. Style configuration options are
|
||||
deliberately limited and rarely added. Previous formatting is taken into account as
|
||||
little as possible, with rare exceptions like the magic trailing comma. The coding style
|
||||
used by _Black_ can be viewed as a strict subset of PEP 8.
|
||||
|
||||
This document describes the current formatting style. If you're interested in trying out
|
||||
where the style is heading, see [future style](./future_style.md) and try running
|
||||
`black --preview`.
|
||||
_Black_ reformats entire files in place. It is not configurable. It doesn't take
|
||||
previous formatting into account. It doesn't reformat blocks that start with
|
||||
`# fmt: off` and end with `# fmt: on`. `# fmt: on/off` have to be on the same level of
|
||||
indentation. It also recognizes [YAPF](https://github.com/google/yapf)'s block comments
|
||||
to the same effect, as a courtesy for straddling code.
|
||||
|
||||
### How _Black_ wraps lines
|
||||
|
||||
_Black_ ignores previous formatting and applies uniform horizontal and vertical
|
||||
whitespace to your code. The rules for horizontal whitespace can be summarized as: do
|
||||
whatever makes `pycodestyle` happy.
|
||||
whatever makes `pycodestyle` happy. The coding style used by _Black_ can be viewed as a
|
||||
strict subset of PEP 8.
|
||||
|
||||
As for vertical whitespace, _Black_ tries to render one full expression or simple
|
||||
statement per line. If this fits the allotted line length, great.
|
||||
@ -78,21 +75,6 @@ def very_important_function(
|
||||
...
|
||||
```
|
||||
|
||||
If a data structure literal (tuple, list, set, dict) or a line of "from" imports cannot
|
||||
fit in the allotted length, it's always split into one element per line. This minimizes
|
||||
diffs as well as enables readers of code to find which commit introduced a particular
|
||||
entry. This also makes _Black_ compatible with
|
||||
[isort](../guides/using_black_with_other_tools.md#isort) with the ready-made `black`
|
||||
profile or manual configuration.
|
||||
|
||||
You might have noticed that closing brackets are always dedented and that a trailing
|
||||
comma is always added. Such formatting produces smaller diffs; when you add or remove an
|
||||
element, it's always just one line. Also, having the closing bracket dedented provides a
|
||||
clear delimiter between two distinct sections of the code that otherwise share the same
|
||||
indentation level (like the arguments list and the docstring in the example above).
|
||||
|
||||
(labels/why-no-backslashes)=
|
||||
|
||||
_Black_ prefers parentheses over backslashes, and will remove backslashes if found.
|
||||
|
||||
```py3
|
||||
@ -133,7 +115,61 @@ If you're reaching for backslashes, that's a clear signal that you can do better
|
||||
slightly refactor your code. I hope some of the examples above show you that there are
|
||||
many ways in which you can do it.
|
||||
|
||||
(labels/line-length)=
|
||||
However there is one exception: `with` statements using multiple context managers.
|
||||
Python's grammar does not allow organizing parentheses around the series of context
|
||||
managers.
|
||||
|
||||
We don't want formatting like:
|
||||
|
||||
```py3
|
||||
with make_context_manager1() as cm1, make_context_manager2() as cm2, make_context_manager3() as cm3, make_context_manager4() as cm4:
|
||||
... # nothing to split on - line too long
|
||||
```
|
||||
|
||||
So _Black_ will now format it like this:
|
||||
|
||||
```py3
|
||||
with \
|
||||
make_context_manager(1) as cm1, \
|
||||
make_context_manager(2) as cm2, \
|
||||
make_context_manager(3) as cm3, \
|
||||
make_context_manager(4) as cm4 \
|
||||
:
|
||||
... # backslashes and an ugly stranded colon
|
||||
```
|
||||
|
||||
You might have noticed that closing brackets are always dedented and that a trailing
|
||||
comma is always added. Such formatting produces smaller diffs; when you add or remove an
|
||||
element, it's always just one line. Also, having the closing bracket dedented provides a
|
||||
clear delimiter between two distinct sections of the code that otherwise share the same
|
||||
indentation level (like the arguments list and the docstring in the example above).
|
||||
|
||||
If a data structure literal (tuple, list, set, dict) or a line of "from" imports cannot
|
||||
fit in the allotted length, it's always split into one element per line. This minimizes
|
||||
diffs as well as enables readers of code to find which commit introduced a particular
|
||||
entry. This also makes _Black_ compatible with [isort](https://pypi.org/p/isort/) with
|
||||
the following configuration.
|
||||
|
||||
<details>
|
||||
<summary>A compatible `.isort.cfg`</summary>
|
||||
|
||||
```cfg
|
||||
[settings]
|
||||
multi_line_output = 3
|
||||
include_trailing_comma = True
|
||||
force_grid_wrap = 0
|
||||
use_parentheses = True
|
||||
ensure_newline_before_comments = True
|
||||
line_length = 88
|
||||
```
|
||||
|
||||
The equivalent command line is:
|
||||
|
||||
```
|
||||
$ isort --multi-line=3 --trailing-comma --force-grid-wrap=0 --use-parentheses --line-width=88 [ file.py ]
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Line length
|
||||
|
||||
@ -143,7 +179,7 @@ significantly shorter files than sticking with 80 (the most popular), or even 79
|
||||
by the standard library). In general,
|
||||
[90-ish seems like the wise choice](https://youtu.be/wf-BqAjZb8M?t=260).
|
||||
|
||||
If you're paid by the lines of code you write, you can pass `--line-length` with a lower
|
||||
If you're paid by the line of code you write, you can pass `--line-length` with a lower
|
||||
number. _Black_ will try to respect that. However, sometimes it won't be able to without
|
||||
breaking other rules. In those rare cases, auto-formatted code will exceed your allotted
|
||||
limit.
|
||||
@ -153,10 +189,33 @@ harder to work with line lengths exceeding 100 characters. It also adversely aff
|
||||
side-by-side diff review on typical screen resolutions. Long lines also make it harder
|
||||
to present code neatly in documentation or talk slides.
|
||||
|
||||
#### Flake8 and other linters
|
||||
If you're using Flake8, you can bump `max-line-length` to 88 and mostly forget about it.
|
||||
However, it's better if you use [Bugbear](https://github.com/PyCQA/flake8-bugbear)'s
|
||||
B950 warning instead of E501, and bump the max line length to 88 (or the `--line-length`
|
||||
you used for black), which will align more with black's _"try to respect
|
||||
`--line-length`, but don't become crazy if you can't"_. You'd do it like this:
|
||||
|
||||
See [Using _Black_ with other tools](../guides/using_black_with_other_tools.md) about
|
||||
linter compatibility.
|
||||
```ini
|
||||
[flake8]
|
||||
max-line-length = 88
|
||||
...
|
||||
select = C,E,F,W,B,B950
|
||||
extend-ignore = E203, E501
|
||||
```
|
||||
|
||||
Explanation of why E203 is disabled can be found further in this documentation. And if
|
||||
you're curious about the reasoning behind B950,
|
||||
[Bugbear's documentation](https://github.com/PyCQA/flake8-bugbear#opinionated-warnings)
|
||||
explains it. The tl;dr is "it's like highway speed limits, we won't bother you if you
|
||||
overdo it by a few km/h".
|
||||
|
||||
**If you're looking for a minimal, black-compatible flake8 configuration:**
|
||||
|
||||
```ini
|
||||
[flake8]
|
||||
max-line-length = 88
|
||||
extend-ignore = E203
|
||||
```
|
||||
|
||||
### Empty lines
|
||||
|
||||
@ -168,35 +227,6 @@ lines on module level left by the original editors, except when they're within
|
||||
parenthesized expressions. Since such expressions are always reformatted to fit minimal
|
||||
space, this whitespace is lost.
|
||||
|
||||
```python
|
||||
# in:
|
||||
|
||||
def function(
|
||||
some_argument: int,
|
||||
|
||||
other_argument: int = 5,
|
||||
) -> EmptyLineInParenWillBeDeleted:
|
||||
|
||||
|
||||
|
||||
print("One empty line above me will be kept!")
|
||||
|
||||
def this_is_okay_too():
|
||||
print("No empty line here")
|
||||
# out:
|
||||
|
||||
def function(
|
||||
some_argument: int,
|
||||
other_argument: int = 5,
|
||||
) -> EmptyLineInParenWillBeDeleted:
|
||||
|
||||
print("One empty line above me will be kept!")
|
||||
|
||||
|
||||
def this_is_okay_too():
|
||||
print("No empty line here")
|
||||
```
|
||||
|
||||
It will also insert proper spacing before and after function definitions. It's one line
|
||||
before and after inner functions and two lines before and after module-level functions
|
||||
and classes. _Black_ will not put empty lines between function/class definitions and
|
||||
@ -209,17 +239,6 @@ following field or method. This conforms to
|
||||
_Black_ won't insert empty lines after function docstrings unless that empty line is
|
||||
required due to an inner function starting immediately after.
|
||||
|
||||
### Comments
|
||||
|
||||
_Black_ does not format comment contents, but it enforces two spaces between code and a
|
||||
comment on the same line, and a space before the comment text begins. Some types of
|
||||
comments that require specific spacing rules are respected: shebangs (`#! comment`), doc
|
||||
comments (`#: comment`), section comments with long runs of hashes, and Spyder cells.
|
||||
Non-breaking spaces after hashes are also preserved. Comments may sometimes be moved
|
||||
because of formatting changes, which can break tools that assign special meaning to
|
||||
them. See [AST before and after formatting](#ast-before-and-after-formatting) for more
|
||||
discussion.
|
||||
|
||||
### Trailing commas
|
||||
|
||||
_Black_ will add trailing commas to expressions that are split by comma where each
|
||||
@ -237,23 +256,16 @@ A pre-existing trailing comma informs _Black_ to always explode contents of the
|
||||
bracket pair into one item per line. Read more about this in the
|
||||
[Pragmatism](#pragmatism) section below.
|
||||
|
||||
(labels/strings)=
|
||||
|
||||
### Strings
|
||||
|
||||
_Black_ prefers double quotes (`"` and `"""`) over single quotes (`'` and `'''`). It
|
||||
will replace the latter with the former as long as it does not result in more backslash
|
||||
escapes than before.
|
||||
|
||||
_Black_ also standardizes string prefixes. Prefix characters are made lowercase with the
|
||||
exception of [capital "R" prefixes](#rstrings-and-rstrings), unicode literal markers
|
||||
(`u`) are removed because they are meaningless in Python 3, and in the case of multiple
|
||||
characters "r" is put first as in spoken language: "raw f-string".
|
||||
|
||||
Another area where Python allows multiple ways to format a string is escape sequences.
|
||||
For example, `"\uabcd"` and `"\uABCD"` evaluate to the same string. _Black_ normalizes
|
||||
such escape sequences to lowercase, but uses uppercase for `\N` named character escapes,
|
||||
such as `"\N{MEETEI MAYEK LETTER HUK}"`.
|
||||
_Black_ also standardizes string prefixes, making them always lowercase. On top of that,
|
||||
if your code is already Python 3.6+ only or it's using the `unicode_literals` future
|
||||
import, _Black_ will remove `u` from the string prefix as it is meaningless in those
|
||||
scenarios.
|
||||
|
||||
The main reason to standardize on a single form of quotes is aesthetics. Having one kind
|
||||
of quotes everywhere reduces reader distraction. It will also enable a future version of
|
||||
@ -277,18 +289,27 @@ If you are adopting _Black_ in a large project with pre-existing string conventi
|
||||
you can pass `--skip-string-normalization` on the command line. This is meant as an
|
||||
adoption helper, avoid using this for new projects.
|
||||
|
||||
As an experimental option, _Black_ splits long strings (using parentheses where
|
||||
appropriate) and merges short ones. When split, parts of f-strings that don't need
|
||||
formatting are converted to plain strings. User-made splits are respected when they do
|
||||
not exceed the line length limit. Line continuation backslashes are converted into
|
||||
parenthesized strings. Unnecessary parentheses are stripped. To enable experimental
|
||||
string processing, pass `--experimental-string-processing` on the command line. Because
|
||||
the functionality is experimental, feedback and issue reports are highly encouraged!
|
||||
|
||||
_Black_ also processes docstrings. Firstly the indentation of docstrings is corrected
|
||||
for both quotations and the text within, although relative indentation in the text is
|
||||
preserved. Superfluous trailing whitespace on each line and unnecessary new lines at the
|
||||
end of the docstring are removed. All leading tabs are converted to spaces, but tabs
|
||||
inside text are preserved. Whitespace leading and trailing one-line docstrings is
|
||||
removed.
|
||||
removed. The quotations of an empty docstring are separated with one space.
|
||||
|
||||
### Numeric literals
|
||||
|
||||
_Black_ standardizes most numeric literals to use lowercase letters for the syntactic
|
||||
parts and uppercase letters for the digits themselves: `0xAB` instead of `0XAB` and
|
||||
`1e10` instead of `1E10`.
|
||||
`1e10` instead of `1E10`. Python 2 long literals are styled as `2L` instead of `2l` to
|
||||
avoid confusion between `l` and `1`.
|
||||
|
||||
### Line breaks & binary operators
|
||||
|
||||
@ -297,26 +318,6 @@ multiple lines. This is so that _Black_ is compliant with the recent changes in
|
||||
[PEP 8](https://www.python.org/dev/peps/pep-0008/#should-a-line-break-before-or-after-a-binary-operator)
|
||||
style guide, which emphasizes that this approach improves readability.
|
||||
|
||||
Almost all operators will be surrounded by single spaces, the only exceptions are unary
|
||||
operators (`+`, `-`, and `~`), and power operators when both operands are simple. For
|
||||
powers, an operand is considered simple if it's only a NAME, numeric CONSTANT, or
|
||||
attribute access (chained attribute access is allowed), with or without a preceding
|
||||
unary operator.
|
||||
|
||||
```python
|
||||
# For example, these won't be surrounded by whitespace
|
||||
a = x**y
|
||||
b = config.base**5.2
|
||||
c = config.base**runtime.config.exponent
|
||||
d = 2**5
|
||||
e = 2**~5
|
||||
|
||||
# ... but these will be surrounded by whitespace
|
||||
f = 2 ** get_exponent()
|
||||
g = get_x() ** get_y()
|
||||
h = config['base'] ** 2
|
||||
```
|
||||
|
||||
### Slices
|
||||
|
||||
PEP 8
|
||||
@ -353,7 +354,7 @@ pair of parentheses to form an atom. There are a few interesting cases:
|
||||
In those cases, parentheses are removed when the entire statement fits in one line, or
|
||||
if the inner expression doesn't have any delimiters to further split on. If there is
|
||||
only a single delimiter and the expression starts or ends with a bracket, the
|
||||
parentheses can also be successfully omitted since the existing bracket pair will
|
||||
parenthesis can also be successfully omitted since the existing bracket pair will
|
||||
organize the expression neatly anyway. Otherwise, the parentheses are added.
|
||||
|
||||
Please note that _Black_ does not add or remove any additional nested parentheses that
|
||||
@ -409,22 +410,16 @@ recommended code style for those files is more terse than PEP 8:
|
||||
_Black_ enforces the above rules. There are additional guidelines for formatting `.pyi`
|
||||
file that are not enforced yet but might be in a future version of the formatter:
|
||||
|
||||
- all function bodies should be empty (contain `...` instead of the body);
|
||||
- do not use docstrings;
|
||||
- prefer `...` over `pass`;
|
||||
- for arguments with a default, use `...` instead of the actual default;
|
||||
- avoid using string literals in type annotations, stub files support forward references
|
||||
natively (like Python 3.7 code with `from __future__ import annotations`);
|
||||
- use variable annotations instead of type comments, even for stubs that target older
|
||||
versions of Python.
|
||||
|
||||
### Line endings
|
||||
|
||||
_Black_ will normalize line endings (`\n` or `\r\n`) based on the first line ending of
|
||||
the file.
|
||||
|
||||
### Form feed characters
|
||||
|
||||
_Black_ will retain form feed characters on otherwise empty lines at the module level.
|
||||
Only one form feed is retained for a group of consecutive empty lines. Where there are
|
||||
two empty lines in a row, the form feed is placed on the second line.
|
||||
versions of Python;
|
||||
- for arguments that default to `None`, use `Optional[]` explicitly;
|
||||
- use `float` instead of `Union[int, float]`.
|
||||
|
||||
## Pragmatism
|
||||
|
||||
@ -434,8 +429,6 @@ there were not many users anyway. Not many edge cases were reported. As a mature
|
||||
_Black_ does make some exceptions to rules it otherwise holds. This section documents
|
||||
what those exceptions are and why this is the case.
|
||||
|
||||
(labels/magic-trailing-comma)=
|
||||
|
||||
### The magic trailing comma
|
||||
|
||||
_Black_ in general does not take existing formatting into account.
|
||||
@ -460,7 +453,7 @@ into one item per line.
|
||||
How do you make it stop? Just delete that trailing comma and _Black_ will collapse your
|
||||
collection into one line if it fits.
|
||||
|
||||
If you must, you can recover the behaviour of early versions of _Black_ with the option
|
||||
If you must, you can recover the behaviour of early versions of Black with the option
|
||||
`--skip-magic-trailing-comma` / `-C`.
|
||||
|
||||
### r"strings" and R"strings"
|
||||
@ -472,26 +465,24 @@ default by (among others) GitHub and Visual Studio Code, differentiates between
|
||||
r-strings and R-strings. The former are syntax highlighted as regular expressions while
|
||||
the latter are treated as true raw strings with no special semantics.
|
||||
|
||||
(labels/ast-changes)=
|
||||
|
||||
### AST before and after formatting
|
||||
|
||||
When run with `--safe` (the default), _Black_ checks that the code before and after is
|
||||
semantically equivalent. This check is done by comparing the AST of the source with the
|
||||
AST of the target. There are three limited cases in which the AST does differ:
|
||||
When run with `--safe`, _Black_ checks that the code before and after is semantically
|
||||
equivalent. This check is done by comparing the AST of the source with the AST of the
|
||||
target. There are three limited cases in which the AST does differ:
|
||||
|
||||
1. _Black_ cleans up leading and trailing whitespace of docstrings, re-indenting them if
|
||||
needed. It's been one of the most popular user-reported features for the formatter to
|
||||
fix whitespace issues with docstrings. While the result is technically an AST
|
||||
difference, due to the various possibilities of forming docstrings, all real-world
|
||||
uses of docstrings that we're aware of sanitize indentation and leading/trailing
|
||||
difference, due to the various possibilities of forming docstrings, all realtime use
|
||||
of docstrings that we're aware of sanitizes indentation and leading/trailing
|
||||
whitespace anyway.
|
||||
|
||||
1. _Black_ manages optional parentheses for some statements. In the case of the `del`
|
||||
2. _Black_ manages optional parentheses for some statements. In the case of the `del`
|
||||
statement, presence of wrapping parentheses or lack of thereof changes the resulting
|
||||
AST but is semantically equivalent in the interpreter.
|
||||
|
||||
1. _Black_ might move comments around, which includes type comments. Those are part of
|
||||
3. _Black_ might move comments around, which includes type comments. Those are part of
|
||||
the AST as of Python 3.8. While the tool implements a number of special cases for
|
||||
those comments, there is no guarantee they will remain where they were in the source.
|
||||
Note that this doesn't change runtime behavior of the source code.
|
@ -1,269 +0,0 @@
|
||||
# The (future of the) Black code style
|
||||
|
||||
## Preview style
|
||||
|
||||
(labels/preview-style)=
|
||||
|
||||
Experimental, potentially disruptive style changes are gathered under the `--preview`
|
||||
CLI flag. At the end of each year, these changes may be adopted into the default style,
|
||||
as described in [The Black Code Style](index.md). Because the functionality is
|
||||
experimental, feedback and issue reports are highly encouraged!
|
||||
|
||||
In the past, the preview style included some features with known bugs, so that we were
|
||||
unable to move these features to the stable style. Therefore, such features are now
|
||||
moved to the `--unstable` style. All features in the `--preview` style are expected to
|
||||
make it to next year's stable style; features in the `--unstable` style will be
|
||||
stabilized only if issues with them are fixed. If bugs are discovered in a `--preview`
|
||||
feature, it is demoted to the `--unstable` style. To avoid thrash when a feature is
|
||||
demoted from the `--preview` to the `--unstable` style, users can use the
|
||||
`--enable-unstable-feature` flag to enable specific unstable features.
|
||||
|
||||
(labels/preview-features)=
|
||||
|
||||
Currently, the following features are included in the preview style:
|
||||
|
||||
- `always_one_newline_after_import`: Always force one blank line after import
|
||||
statements, except when the line after the import is a comment or an import statement
|
||||
- `wrap_long_dict_values_in_parens`: Add parentheses around long values in dictionaries
|
||||
([see below](labels/wrap-long-dict-values))
|
||||
- `fix_fmt_skip_in_one_liners`: Fix `# fmt: skip` behaviour on one-liner declarations,
|
||||
such as `def foo(): return "mock" # fmt: skip`, where previously the declaration
|
||||
would have been incorrectly collapsed.
|
||||
|
||||
(labels/unstable-features)=
|
||||
|
||||
The unstable style additionally includes the following features:
|
||||
|
||||
- `string_processing`: split long string literals and related changes
|
||||
([see below](labels/string-processing))
|
||||
- `multiline_string_handling`: more compact formatting of expressions involving
|
||||
multiline strings ([see below](labels/multiline-string-handling))
|
||||
- `hug_parens_with_braces_and_square_brackets`: more compact formatting of nested
|
||||
brackets ([see below](labels/hug-parens))
|
||||
|
||||
(labels/wrap-long-dict-values)=
|
||||
|
||||
### Improved parentheses management in dicts
|
||||
|
||||
For dict literals with long values, they are now wrapped in parentheses. Unnecessary
|
||||
parentheses are now removed. For example:
|
||||
|
||||
```python
|
||||
my_dict = {
|
||||
"a key in my dict": a_very_long_variable
|
||||
* and_a_very_long_function_call()
|
||||
/ 100000.0,
|
||||
"another key": (short_value),
|
||||
}
|
||||
```
|
||||
|
||||
will be changed to:
|
||||
|
||||
```python
|
||||
my_dict = {
|
||||
"a key in my dict": (
|
||||
a_very_long_variable * and_a_very_long_function_call() / 100000.0
|
||||
),
|
||||
"another key": short_value,
|
||||
}
|
||||
```
|
||||
|
||||
(labels/hug-parens)=
|
||||
|
||||
### Improved multiline dictionary and list indentation for sole function parameter
|
||||
|
||||
For better readability and less verticality, _Black_ now pairs parentheses ("(", ")")
|
||||
with braces ("{", "}") and square brackets ("[", "]") on the same line. For example:
|
||||
|
||||
```python
|
||||
foo(
|
||||
[
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
]
|
||||
)
|
||||
|
||||
nested_array = [
|
||||
[
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
]
|
||||
]
|
||||
```
|
||||
|
||||
will be changed to:
|
||||
|
||||
```python
|
||||
foo([
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
])
|
||||
|
||||
nested_array = [[
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
]]
|
||||
```
|
||||
|
||||
This also applies to list and dictionary unpacking:
|
||||
|
||||
```python
|
||||
foo(
|
||||
*[
|
||||
a_long_function_name(a_long_variable_name)
|
||||
for a_long_variable_name in some_generator
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
will become:
|
||||
|
||||
```python
|
||||
foo(*[
|
||||
a_long_function_name(a_long_variable_name)
|
||||
for a_long_variable_name in some_generator
|
||||
])
|
||||
```
|
||||
|
||||
You can use a magic trailing comma to avoid this compacting behavior; by default,
|
||||
_Black_ will not reformat the following code:
|
||||
|
||||
```python
|
||||
foo(
|
||||
[
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
(labels/string-processing)=
|
||||
|
||||
### Improved string processing
|
||||
|
||||
_Black_ will split long string literals and merge short ones. Parentheses are used where
|
||||
appropriate. When split, parts of f-strings that don't need formatting are converted to
|
||||
plain strings. f-strings will not be merged if they contain internal quotes and it would
|
||||
change their quotation mark style. User-made splits are respected when they do not
|
||||
exceed the line length limit. Line continuation backslashes are converted into
|
||||
parenthesized strings. Unnecessary parentheses are stripped. The stability and status of
|
||||
this feature istracked in [this issue](https://github.com/psf/black/issues/2188).
|
||||
|
||||
(labels/multiline-string-handling)=
|
||||
|
||||
### Improved multiline string handling
|
||||
|
||||
_Black_ is smarter when formatting multiline strings, especially in function arguments,
|
||||
to avoid introducing extra line breaks. Previously, it would always consider multiline
|
||||
strings as not fitting on a single line. With this new feature, _Black_ looks at the
|
||||
context around the multiline string to decide if it should be inlined or split to a
|
||||
separate line. For example, when a multiline string is passed to a function, _Black_
|
||||
will only split the multiline string if a line is too long or if multiple arguments are
|
||||
being passed.
|
||||
|
||||
For example, _Black_ will reformat
|
||||
|
||||
```python
|
||||
textwrap.dedent(
|
||||
"""\
|
||||
This is a
|
||||
multiline string
|
||||
"""
|
||||
)
|
||||
```
|
||||
|
||||
to:
|
||||
|
||||
```python
|
||||
textwrap.dedent("""\
|
||||
This is a
|
||||
multiline string
|
||||
""")
|
||||
```
|
||||
|
||||
And:
|
||||
|
||||
```python
|
||||
MULTILINE = """
|
||||
foobar
|
||||
""".replace(
|
||||
"\n", ""
|
||||
)
|
||||
```
|
||||
|
||||
to:
|
||||
|
||||
```python
|
||||
MULTILINE = """
|
||||
foobar
|
||||
""".replace("\n", "")
|
||||
```
|
||||
|
||||
Implicit multiline strings are special, because they can have inline comments. Strings
|
||||
without comments are merged, for example
|
||||
|
||||
```python
|
||||
s = (
|
||||
"An "
|
||||
"implicit "
|
||||
"multiline "
|
||||
"string"
|
||||
)
|
||||
```
|
||||
|
||||
becomes
|
||||
|
||||
```python
|
||||
s = "An implicit multiline string"
|
||||
```
|
||||
|
||||
A comment on any line of the string (or between two string lines) will block the
|
||||
merging, so
|
||||
|
||||
```python
|
||||
s = (
|
||||
"An " # Important comment concerning just this line
|
||||
"implicit "
|
||||
"multiline "
|
||||
"string"
|
||||
)
|
||||
```
|
||||
|
||||
and
|
||||
|
||||
```python
|
||||
s = (
|
||||
"An "
|
||||
"implicit "
|
||||
# Comment in between
|
||||
"multiline "
|
||||
"string"
|
||||
)
|
||||
```
|
||||
|
||||
will not be merged. Having the comment after or before the string lines (but still
|
||||
inside the parens) will merge the string. For example
|
||||
|
||||
```python
|
||||
s = ( # Top comment
|
||||
"An "
|
||||
"implicit "
|
||||
"multiline "
|
||||
"string"
|
||||
# Bottom comment
|
||||
)
|
||||
```
|
||||
|
||||
becomes
|
||||
|
||||
```python
|
||||
s = ( # Top comment
|
||||
"An implicit multiline string"
|
||||
# Bottom comment
|
||||
)
|
||||
```
|
@ -1,54 +0,0 @@
|
||||
# The Black Code Style
|
||||
|
||||
```{toctree}
|
||||
---
|
||||
hidden:
|
||||
---
|
||||
|
||||
Current style <current_style>
|
||||
Future style <future_style>
|
||||
```
|
||||
|
||||
_Black_ is a PEP 8 compliant opinionated formatter with its own style.
|
||||
|
||||
While keeping the style unchanged throughout releases has always been a goal, the
|
||||
_Black_ code style isn't set in stone. It evolves to accommodate for new features in the
|
||||
Python language and, occasionally, in response to user feedback. Large-scale style
|
||||
preferences presented in {doc}`current_style` are very unlikely to change, but minor
|
||||
style aspects and details might change according to the stability policy presented
|
||||
below. Ongoing style considerations are tracked on GitHub with the
|
||||
[style](https://github.com/psf/black/labels/T%3A%20style) issue label.
|
||||
|
||||
(labels/stability-policy)=
|
||||
|
||||
## Stability Policy
|
||||
|
||||
The following policy applies for the _Black_ code style, in non pre-release versions of
|
||||
_Black_:
|
||||
|
||||
- If code has been formatted with _Black_, it will remain unchanged when formatted with
|
||||
the same options using any other release in the same calendar year.
|
||||
|
||||
This means projects can safely use `black ~= 22.0` without worrying about formatting
|
||||
changes disrupting their project in 2022. We may still fix bugs where _Black_ crashes
|
||||
on some code, and make other improvements that do not affect formatting.
|
||||
|
||||
In rare cases, we may make changes affecting code that has not been previously
|
||||
formatted with _Black_. For example, we have had bugs where we accidentally removed
|
||||
some comments. Such bugs can be fixed without breaking the stability policy.
|
||||
|
||||
- The first release in a new calendar year _may_ contain formatting changes, although
|
||||
these will be minimised as much as possible. This is to allow for improved formatting
|
||||
enabled by newer Python language syntax as well as due to improvements in the
|
||||
formatting logic.
|
||||
|
||||
- The `--preview` and `--unstable` flags are exempt from this policy. There are no
|
||||
guarantees around the stability of the output with these flags passed into _Black_.
|
||||
They are intended for allowing experimentation with proposed changes to the _Black_
|
||||
code style. The `--preview` style at the end of a year should closely match the stable
|
||||
style for the next year, but we may always make changes.
|
||||
|
||||
Documentation for both the current and future styles can be found:
|
||||
|
||||
- {doc}`current_style`
|
||||
- {doc}`future_style`
|
@ -1,53 +0,0 @@
|
||||
# Black Docker image
|
||||
|
||||
Official _Black_ Docker images are available on
|
||||
[Docker Hub](https://hub.docker.com/r/pyfound/black).
|
||||
|
||||
_Black_ images with the following tags are available:
|
||||
|
||||
- release numbers, e.g. `21.5b2`, `21.6b0`, `21.7b0` etc.\
|
||||
ℹ Recommended for users who want to use a particular version of _Black_.
|
||||
- `latest_release` - tag created when a new version of _Black_ is released.\
|
||||
ℹ Recommended for users who want to use released versions of _Black_. It maps to
|
||||
[the latest release](https://github.com/psf/black/releases/latest) of _Black_.
|
||||
- `latest_prerelease` - tag created when a new alpha (prerelease) version of _Black_ is
|
||||
released.\
|
||||
ℹ Recommended for users who want to preview or test alpha versions of _Black_. Note
|
||||
that the most recent release may be newer than any prerelease, because no prereleases
|
||||
are created before most releases.
|
||||
- `latest` - tag used for the newest image of _Black_.\
|
||||
ℹ Recommended for users who always want to use the latest version of _Black_, even
|
||||
before it is released.
|
||||
|
||||
There is one more tag used for _Black_ Docker images - `latest_non_release`. It is
|
||||
created for all unreleased
|
||||
[commits on the `main` branch](https://github.com/psf/black/commits/main). This tag is
|
||||
not meant to be used by external users.
|
||||
|
||||
From version 23.11.0 the Docker image installs a compiled black into the image.
|
||||
|
||||
## Usage
|
||||
|
||||
A permanent container doesn't have to be created to use _Black_ as a Docker image. It's
|
||||
enough to run _Black_ commands for the chosen image denoted as `:tag`. In the below
|
||||
examples, the `latest_release` tag is used. If `:tag` is omitted, the `latest` tag will
|
||||
be used.
|
||||
|
||||
More about _Black_ usage can be found in
|
||||
[Usage and Configuration: The basics](./the_basics.md).
|
||||
|
||||
### Check Black version
|
||||
|
||||
```console
|
||||
$ docker run --rm pyfound/black:latest_release black --version
|
||||
```
|
||||
|
||||
### Check code
|
||||
|
||||
```console
|
||||
$ docker run --rm --volume $(pwd):/src --workdir /src pyfound/black:latest_release black --check .
|
||||
```
|
||||
|
||||
_Remark_: besides [regular _Black_ exit codes](./the_basics.md) returned by `--check`
|
||||
option, [Docker exit codes](https://docs.docker.com/engine/reference/run/#exit-status)
|
||||
should also be considered.
|
@ -1,38 +0,0 @@
|
||||
# File collection and discovery
|
||||
|
||||
You can directly pass _Black_ files, but you can also pass directories and _Black_ will
|
||||
walk them, collecting files to format. It determines what files to format or skip
|
||||
automatically using the inclusion and exclusion regexes and as well their modification
|
||||
time.
|
||||
|
||||
## Ignoring unmodified files
|
||||
|
||||
_Black_ remembers files it has already formatted, unless the `--diff` flag is used or
|
||||
code is passed via standard input. This information is stored per-user. The exact
|
||||
location of the file depends on the _Black_ version and the system on which _Black_ is
|
||||
run. The file is non-portable. The standard location on common operating systems is:
|
||||
|
||||
- Windows:
|
||||
`C:\\Users\<username>\AppData\Local\black\black\Cache\<version>\cache.<line-length>.<file-mode>.pickle`
|
||||
- macOS:
|
||||
`/Users/<username>/Library/Caches/black/<version>/cache.<line-length>.<file-mode>.pickle`
|
||||
- Linux:
|
||||
`/home/<username>/.cache/black/<version>/cache.<line-length>.<file-mode>.pickle`
|
||||
|
||||
`file-mode` is an int flag that determines whether the file was formatted as 3.6+ only,
|
||||
as .pyi, and whether string normalization was omitted.
|
||||
|
||||
To override the location of these files on all systems, set the environment variable
|
||||
`BLACK_CACHE_DIR` to the preferred location. Alternatively on macOS and Linux, set
|
||||
`XDG_CACHE_HOME` to your preferred location. For example, if you want to put the cache
|
||||
in the directory you're running _Black_ from, set `BLACK_CACHE_DIR=.cache/black`.
|
||||
_Black_ will then write the above files to `.cache/black`. Note that `BLACK_CACHE_DIR`
|
||||
will take precedence over `XDG_CACHE_HOME` if both are set.
|
||||
|
||||
## .gitignore
|
||||
|
||||
If `--exclude` is not set, _Black_ will automatically ignore files and directories in
|
||||
`.gitignore` file(s), if present.
|
||||
|
||||
If you want _Black_ to continue using `.gitignore` while also configuring the exclusion
|
||||
rules, please use `--extend-exclude`.
|
@ -1,28 +0,0 @@
|
||||
# Usage and Configuration
|
||||
|
||||
```{toctree}
|
||||
---
|
||||
hidden:
|
||||
---
|
||||
|
||||
the_basics
|
||||
file_collection_and_discovery
|
||||
black_as_a_server
|
||||
black_docker_image
|
||||
```
|
||||
|
||||
Sometimes, running _Black_ with its defaults and passing filepaths to it just won't cut
|
||||
it. Passing each file using paths will become burdensome, and maybe you would like
|
||||
_Black_ to not touch your files and just output diffs. And yes, you _can_ tweak certain
|
||||
parts of _Black_'s style, but please know that configurability in this area is
|
||||
purposefully limited.
|
||||
|
||||
Using many of these more advanced features of _Black_ will require some configuration.
|
||||
Configuration that will either live on the command line or in a TOML configuration file.
|
||||
|
||||
This section covers features of _Black_ and configuring _Black_ in detail:
|
||||
|
||||
- {doc}`The basics <./the_basics>`
|
||||
- {doc}`File collection and discovery <file_collection_and_discovery>`
|
||||
- {doc}`Black as a server (blackd) <./black_as_a_server>`
|
||||
- {doc}`Black Docker image <./black_docker_image>`
|
@ -1,543 +0,0 @@
|
||||
# The basics
|
||||
|
||||
Foundational knowledge on using and configuring Black.
|
||||
|
||||
_Black_ is a well-behaved Unix-style command-line tool:
|
||||
|
||||
- it does nothing if it finds no sources to format;
|
||||
- it will read from standard input and write to standard output if `-` is used as the
|
||||
filename;
|
||||
- it only outputs messages to users on standard error;
|
||||
- exits with code 0 unless an internal error occurred or a CLI option prompted it.
|
||||
|
||||
## Usage
|
||||
|
||||
_Black_ will reformat entire files in place. 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}
|
||||
```
|
||||
|
||||
### Ignoring sections
|
||||
|
||||
Black will not reformat lines that contain `# fmt: skip` or blocks that start with
|
||||
`# fmt: off` and end with `# fmt: on`. `# fmt: skip` can be mixed with other
|
||||
pragmas/comments either with multiple comments (e.g. `# fmt: skip # pylint # noqa`) or
|
||||
as a semicolon separated list (e.g. `# fmt: skip; pylint; noqa`). `# fmt: on/off` must
|
||||
be on the same level of indentation and in the same block, meaning no unindents beyond
|
||||
the initial indentation level between them. Black also recognizes
|
||||
[YAPF](https://github.com/google/yapf)'s block comments to the same effect, as a
|
||||
courtesy for straddling code.
|
||||
|
||||
### Command line options
|
||||
|
||||
The CLI options of _Black_ can be displayed by running `black --help`. All options are
|
||||
also covered in more detail below.
|
||||
|
||||
While _Black_ has quite a few knobs these days, it is still opinionated so style options
|
||||
are deliberately limited and rarely added.
|
||||
|
||||
Note that all command-line options listed above can also be configured using a
|
||||
`pyproject.toml` file (more on that below).
|
||||
|
||||
#### `-h`, `--help`
|
||||
|
||||
Show available command-line options and exit.
|
||||
|
||||
#### `-c`, `--code`
|
||||
|
||||
Format the code passed in as a string.
|
||||
|
||||
```console
|
||||
$ black --code "print ( 'hello, world' )"
|
||||
print("hello, world")
|
||||
```
|
||||
|
||||
#### `-l`, `--line-length`
|
||||
|
||||
How many characters per line to allow. The default is 88.
|
||||
|
||||
See also [the style documentation](labels/line-length).
|
||||
|
||||
#### `-t`, `--target-version`
|
||||
|
||||
Python versions that should be supported by Black's output. You can run `black --help`
|
||||
and look for the `--target-version` option to see the full list of supported versions.
|
||||
You should include all versions that your code supports. If you support Python 3.11
|
||||
through 3.13, you should write:
|
||||
|
||||
```console
|
||||
$ black -t py311 -t py312 -t py313
|
||||
```
|
||||
|
||||
In a [configuration file](#configuration-via-a-file), you can write:
|
||||
|
||||
```toml
|
||||
target-version = ["py311", "py312", "py313"]
|
||||
```
|
||||
|
||||
By default, Black will infer target versions from the project metadata in
|
||||
`pyproject.toml`, specifically the `[project.requires-python]` field. If this does not
|
||||
yield conclusive results, Black will use per-file auto-detection.
|
||||
|
||||
_Black_ uses this option to decide what grammar to use to parse your code. In addition,
|
||||
it may use it to decide what style to use. For example, support for a trailing comma
|
||||
after `*args` in a function call was added in Python 3.5, so _Black_ will add this comma
|
||||
only if the target versions are all Python 3.5 or higher:
|
||||
|
||||
```console
|
||||
$ black --line-length=10 --target-version=py35 -c 'f(a, *args)'
|
||||
f(
|
||||
a,
|
||||
*args,
|
||||
)
|
||||
$ black --line-length=10 --target-version=py34 -c 'f(a, *args)'
|
||||
f(
|
||||
a,
|
||||
*args
|
||||
)
|
||||
$ black --line-length=10 --target-version=py34 --target-version=py35 -c 'f(a, *args)'
|
||||
f(
|
||||
a,
|
||||
*args
|
||||
)
|
||||
```
|
||||
|
||||
#### `--pyi`
|
||||
|
||||
Format all input files like typing stubs regardless of file extension. This is useful
|
||||
when piping source on standard input.
|
||||
|
||||
#### `--ipynb`
|
||||
|
||||
Format all input files like Jupyter Notebooks regardless of file extension. This is
|
||||
useful when piping source on standard input.
|
||||
|
||||
#### `--python-cell-magics`
|
||||
|
||||
When processing Jupyter Notebooks, add the given magic to the list of known python-
|
||||
magics. Useful for formatting cells with custom python magics.
|
||||
|
||||
#### `-x, --skip-source-first-line`
|
||||
|
||||
Skip the first line of the source code.
|
||||
|
||||
#### `-S, --skip-string-normalization`
|
||||
|
||||
By default, _Black_ uses double quotes for all strings and normalizes string prefixes,
|
||||
as described in [the style documentation](labels/strings). If this option is given,
|
||||
strings are left unchanged instead.
|
||||
|
||||
#### `-C, --skip-magic-trailing-comma`
|
||||
|
||||
By default, _Black_ uses existing trailing commas as an indication that short lines
|
||||
should be left separate, as described in
|
||||
[the style documentation](labels/magic-trailing-comma). If this option is given, the
|
||||
magic trailing comma is ignored.
|
||||
|
||||
#### `--preview`
|
||||
|
||||
Enable potentially disruptive style changes that we expect to add to Black's main
|
||||
functionality in the next major release. Use this if you want a taste of what next
|
||||
year's style will look like.
|
||||
|
||||
Read more about [our preview style](labels/preview-style).
|
||||
|
||||
There is no guarantee on the code style produced by this flag across releases.
|
||||
|
||||
#### `--unstable`
|
||||
|
||||
Enable all style changes in `--preview`, plus additional changes that we would like to
|
||||
make eventually, but that have known issues that need to be fixed before they can move
|
||||
back to the `--preview` style. Use this if you want to experiment with these changes and
|
||||
help fix issues with them.
|
||||
|
||||
There is no guarantee on the code style produced by this flag across releases.
|
||||
|
||||
#### `--enable-unstable-feature`
|
||||
|
||||
Enable specific features from the `--unstable` style. See
|
||||
[the preview style documentation](labels/unstable-features) for the list of supported
|
||||
features. This flag can only be used when `--preview` is enabled. Users are encouraged
|
||||
to use this flag if they use `--preview` style and a feature that affects their code is
|
||||
moved from the `--preview` to the `--unstable` style, but they want to avoid the thrash
|
||||
from undoing this change.
|
||||
|
||||
There are no guarantees on the behavior of these features, or even their existence,
|
||||
across releases.
|
||||
|
||||
(labels/exit-code)=
|
||||
|
||||
#### `--check`
|
||||
|
||||
Don't write the files back, just return the status. _Black_ will exit with:
|
||||
|
||||
- code 0 if nothing would change;
|
||||
- code 1 if some files would be reformatted; or
|
||||
- code 123 if there was an internal error
|
||||
|
||||
If used in combination with `--quiet` then only the exit code will be returned, unless
|
||||
there was an internal error.
|
||||
|
||||
```console
|
||||
$ black test.py --check
|
||||
All done! ✨ 🍰 ✨
|
||||
1 file would be left unchanged.
|
||||
$ echo $?
|
||||
0
|
||||
|
||||
$ black test.py --check
|
||||
would reformat test.py
|
||||
Oh no! 💥 💔 💥
|
||||
1 file would be reformatted.
|
||||
$ echo $?
|
||||
1
|
||||
|
||||
$ black test.py --check
|
||||
error: cannot format test.py: INTERNAL ERROR: Black produced code that is not equivalent to the source. Please report a bug on https://github.com/psf/black/issues. This diff might be helpful: /tmp/blk_kjdr1oog.log
|
||||
Oh no! 💥 💔 💥
|
||||
1 file would fail to reformat.
|
||||
$ echo $?
|
||||
123
|
||||
```
|
||||
|
||||
#### `--diff`
|
||||
|
||||
Don't write the files back, just output a diff to indicate what changes _Black_ would've
|
||||
made. They are printed to stdout so capturing them is simple.
|
||||
|
||||
If you'd like colored diffs, you can enable them with `--color`.
|
||||
|
||||
```console
|
||||
$ black test.py --diff
|
||||
--- test.py 2021-03-08 22:23:40.848954+00:00
|
||||
+++ test.py 2021-03-08 22:23:47.126319+00:00
|
||||
@@ -1 +1 @@
|
||||
-print ( 'hello, world' )
|
||||
+print("hello, world")
|
||||
would reformat test.py
|
||||
All done! ✨ 🍰 ✨
|
||||
1 file would be reformatted.
|
||||
```
|
||||
|
||||
#### `--color` / `--no-color`
|
||||
|
||||
Show (or do not show) colored diff. Only applies when `--diff` is given.
|
||||
|
||||
#### `--line-ranges`
|
||||
|
||||
When specified, _Black_ will try its best to only format these lines.
|
||||
|
||||
This option can be specified multiple times, and a union of the lines will be formatted.
|
||||
Each range must be specified as two integers connected by a `-`: `<START>-<END>`. The
|
||||
`<START>` and `<END>` integer indices are 1-based and inclusive on both ends.
|
||||
|
||||
_Black_ may still format lines outside of the ranges for multi-line statements.
|
||||
Formatting more than one file or any ipynb files with this option is not supported. This
|
||||
option cannot be specified in the `pyproject.toml` config.
|
||||
|
||||
Example: `black --line-ranges=1-10 --line-ranges=21-30 test.py` will format lines from
|
||||
`1` to `10` and `21` to `30`.
|
||||
|
||||
This option is mainly for editor integrations, such as "Format Selection".
|
||||
|
||||
```{note}
|
||||
Due to [#4052](https://github.com/psf/black/issues/4052), `--line-ranges` might format
|
||||
extra lines outside of the ranges when ther are unformatted lines with the exact
|
||||
content. It also disables _Black_'s formatting stability check in `--safe` mode.
|
||||
```
|
||||
|
||||
#### `--fast` / `--safe`
|
||||
|
||||
By default, _Black_ performs [an AST safety check](labels/ast-changes) after formatting
|
||||
your code. The `--fast` flag turns off this check and the `--safe` flag explicitly
|
||||
enables it.
|
||||
|
||||
#### `--required-version`
|
||||
|
||||
Require a specific version of _Black_ to be running. This is useful for ensuring that
|
||||
all contributors to your project are using the same version, because different versions
|
||||
of _Black_ may format code a little differently. This option can be set in a
|
||||
configuration file for consistent results across environments.
|
||||
|
||||
```console
|
||||
$ black --version
|
||||
black, 25.1.0 (compiled: yes)
|
||||
$ black --required-version 25.1.0 -c "format = 'this'"
|
||||
format = "this"
|
||||
$ black --required-version 31.5b2 -c "still = 'beta?!'"
|
||||
Oh no! 💥 💔 💥 The required version does not match the running version!
|
||||
```
|
||||
|
||||
You can also pass just the major version:
|
||||
|
||||
```console
|
||||
$ black --required-version 22 -c "format = 'this'"
|
||||
format = "this"
|
||||
$ black --required-version 31 -c "still = 'beta?!'"
|
||||
Oh no! 💥 💔 💥 The required version does not match the running version!
|
||||
```
|
||||
|
||||
Because of our [stability policy](../the_black_code_style/index.md), this will guarantee
|
||||
stable formatting, but still allow you to take advantage of improvements that do not
|
||||
affect formatting.
|
||||
|
||||
#### `--exclude`
|
||||
|
||||
A regular expression that matches files and directories that should be excluded on
|
||||
recursive searches. An empty value means no paths are excluded. Use forward slashes for
|
||||
directories on all platforms (Windows, too). By default, Black also ignores all paths
|
||||
listed in `.gitignore`. Changing this value will override all default exclusions.
|
||||
|
||||
If the regular expression contains newlines, it is treated as a
|
||||
[verbose regular expression](https://docs.python.org/3/library/re.html#re.VERBOSE). This
|
||||
is typically useful when setting these options in a `pyproject.toml` configuration file;
|
||||
see [Configuration format](#configuration-format) for more information.
|
||||
|
||||
#### `--extend-exclude`
|
||||
|
||||
Like `--exclude`, but adds additional files and directories on top of the default values
|
||||
instead of overriding them.
|
||||
|
||||
#### `--force-exclude`
|
||||
|
||||
Like `--exclude`, but files and directories matching this regex will be excluded even
|
||||
when they are passed explicitly as arguments. This is useful when invoking Black
|
||||
programmatically on changed files, such as in a pre-commit hook or editor plugin.
|
||||
|
||||
#### `--stdin-filename`
|
||||
|
||||
The name of the file when passing it through stdin. Useful to make sure Black will
|
||||
respect the `--force-exclude` option on some editors that rely on using stdin.
|
||||
|
||||
#### `--include`
|
||||
|
||||
A regular expression that matches files and directories that should be included on
|
||||
recursive searches. An empty value means all files are included regardless of the name.
|
||||
Use forward slashes for directories on all platforms (Windows, too). Overrides all
|
||||
exclusions, including from `.gitignore` and command line options.
|
||||
|
||||
#### `-W`, `--workers`
|
||||
|
||||
When _Black_ formats multiple files, it may use a process pool to speed up formatting.
|
||||
This option controls the number of parallel workers. This can also be specified via the
|
||||
`BLACK_NUM_WORKERS` environment variable. Defaults to the number of CPUs in the system.
|
||||
|
||||
#### `-q`, `--quiet`
|
||||
|
||||
Stop emitting all non-critical output. Error messages will still be emitted (which can
|
||||
silenced by `2>/dev/null`).
|
||||
|
||||
```console
|
||||
$ black src/ -q
|
||||
error: cannot format src/black_primer/cli.py: Cannot parse: 5:6: mport asyncio
|
||||
```
|
||||
|
||||
#### `-v`, `--verbose`
|
||||
|
||||
Emit messages about files that were not changed or were ignored due to exclusion
|
||||
patterns. If _Black_ is using a configuration file, a message detailing which one it is
|
||||
using will be emitted.
|
||||
|
||||
```console
|
||||
$ black src/ -v
|
||||
Using configuration from /tmp/pyproject.toml.
|
||||
src/blib2to3 ignored: matches the --extend-exclude regular expression
|
||||
src/_black_version.py wasn't modified on disk since last run.
|
||||
src/black/__main__.py wasn't modified on disk since last run.
|
||||
error: cannot format src/black_primer/cli.py: Cannot parse: 5:6: mport asyncio
|
||||
reformatted src/black_primer/lib.py
|
||||
reformatted src/blackd/__init__.py
|
||||
reformatted src/black/__init__.py
|
||||
Oh no! 💥 💔 💥
|
||||
3 files reformatted, 2 files left unchanged, 1 file failed to reformat
|
||||
```
|
||||
|
||||
#### `--version`
|
||||
|
||||
You can check the version of _Black_ you have installed using the `--version` flag.
|
||||
|
||||
```console
|
||||
$ black --version
|
||||
black, 25.1.0
|
||||
```
|
||||
|
||||
#### `--config`
|
||||
|
||||
Read configuration options from a configuration file. See
|
||||
[below](#configuration-via-a-file) for more details on the configuration file.
|
||||
|
||||
### Environment variable options
|
||||
|
||||
_Black_ supports the following configuration via environment variables.
|
||||
|
||||
#### `BLACK_CACHE_DIR`
|
||||
|
||||
The directory where _Black_ should store its cache.
|
||||
|
||||
#### `BLACK_NUM_WORKERS`
|
||||
|
||||
The number of parallel workers _Black_ should use. The command line option `-W` /
|
||||
`--workers` takes precedence over this environment variable.
|
||||
|
||||
### Code input alternatives
|
||||
|
||||
_Black_ supports formatting code via stdin, with the result being printed to stdout.
|
||||
Just let _Black_ know with `-` as the path.
|
||||
|
||||
```console
|
||||
$ echo "print ( 'hello, world' )" | black -
|
||||
print("hello, world")
|
||||
reformatted -
|
||||
All done! ✨ 🍰 ✨
|
||||
1 file reformatted.
|
||||
```
|
||||
|
||||
**Tip:** if you need _Black_ to treat stdin input as a file passed directly via the CLI,
|
||||
use `--stdin-filename`. Useful to make sure _Black_ will respect the `--force-exclude`
|
||||
option on some editors that rely on using stdin.
|
||||
|
||||
You can also pass code as a string using the `--code` option.
|
||||
|
||||
### Writeback and reporting
|
||||
|
||||
By default _Black_ reformats the files given and/or found in place. Sometimes you need
|
||||
_Black_ to just tell you what it _would_ do without actually rewriting the Python files.
|
||||
|
||||
There's two variations to this mode that are independently enabled by their respective
|
||||
flags:
|
||||
|
||||
- `--check` (exit with code 1 if any file would be reformatted)
|
||||
- `--diff` (print a diff instead of reformatting files)
|
||||
|
||||
Both variations can be enabled at once.
|
||||
|
||||
### Output verbosity
|
||||
|
||||
_Black_ in general tries to produce the right amount of output, balancing between
|
||||
usefulness and conciseness. By default, _Black_ emits files modified and error messages,
|
||||
plus a short summary.
|
||||
|
||||
```console
|
||||
$ black src/
|
||||
error: cannot format src/black_primer/cli.py: Cannot parse: 5:6: mport asyncio
|
||||
reformatted src/black_primer/lib.py
|
||||
reformatted src/blackd/__init__.py
|
||||
reformatted src/black/__init__.py
|
||||
Oh no! 💥 💔 💥
|
||||
3 files reformatted, 2 files left unchanged, 1 file failed to reformat.
|
||||
```
|
||||
|
||||
The `--quiet` and `--verbose` flags control output verbosity.
|
||||
|
||||
## Configuration via a file
|
||||
|
||||
_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.
|
||||
|
||||
**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.
|
||||
|
||||
### What on Earth is a `pyproject.toml` file?
|
||||
|
||||
[PEP 518](https://www.python.org/dev/peps/pep-0518/) defines `pyproject.toml` as a
|
||||
configuration file to store build system requirements for Python projects. With the help
|
||||
of tools like [Poetry](https://python-poetry.org/),
|
||||
[Flit](https://flit.readthedocs.io/en/latest/), or
|
||||
[Hatch](https://hatch.pypa.io/latest/) it can fully replace the need for `setup.py` and
|
||||
`setup.cfg` files.
|
||||
|
||||
### Where _Black_ looks for the file
|
||||
|
||||
By default _Black_ looks for `pyproject.toml` containing a `[tool.black]` section
|
||||
starting from the common base directory of all files and directories passed on the
|
||||
command line. If it's not there, it looks in parent directories. It stops looking when
|
||||
it finds the file, or a `.git` directory, or a `.hg` directory, or the root of the file
|
||||
system, whichever comes first.
|
||||
|
||||
If you're formatting standard input, _Black_ will look for configuration starting from
|
||||
the current working directory.
|
||||
|
||||
You can use a "global" configuration, stored in a specific location in your home
|
||||
directory. This will be used as a fallback configuration, that is, it will be used if
|
||||
and only if _Black_ doesn't find any configuration as mentioned above. Depending on your
|
||||
operating system, this configuration file should be stored as:
|
||||
|
||||
- Windows: `~\.black`
|
||||
- Unix-like (Linux, MacOS, etc.): `$XDG_CONFIG_HOME/black` (`~/.config/black` if the
|
||||
`XDG_CONFIG_HOME` environment variable is not set)
|
||||
|
||||
Note that these are paths to the TOML file itself (meaning that they shouldn't be named
|
||||
as `pyproject.toml`), not directories where you store the configuration (i.e.,
|
||||
`black`/`.black` is the file to create and add your configuration options to, in the
|
||||
`~/.config/` directory). Here, `~` refers to the path to your home directory. On
|
||||
Windows, this will be something like `C:\\Users\UserName`.
|
||||
|
||||
You can also explicitly specify the path to a particular file that you want with
|
||||
`--config`. In this situation _Black_ will not look for any other file.
|
||||
|
||||
If you're running with `--verbose`, you will see a message if a file was found and used.
|
||||
|
||||
Please note `blackd` will not use `pyproject.toml` configuration.
|
||||
|
||||
### Configuration format
|
||||
|
||||
As the file extension suggests, `pyproject.toml` is a
|
||||
[TOML](https://github.com/toml-lang/toml) file. It contains separate sections for
|
||||
different tools. _Black_ is using the `[tool.black]` section. The option keys are the
|
||||
same as long names of options on the command line.
|
||||
|
||||
Note that you have to use single-quoted strings in TOML for regular expressions. It's
|
||||
the equivalent of r-strings in Python. Multiline strings are treated as verbose regular
|
||||
expressions by Black. Use `[ ]` to denote a significant space character.
|
||||
|
||||
<details>
|
||||
<summary>Example <code>pyproject.toml</code></summary>
|
||||
|
||||
```toml
|
||||
[tool.black]
|
||||
line-length = 88
|
||||
target-version = ['py37']
|
||||
include = '\.pyi?$'
|
||||
# 'extend-exclude' excludes files or directories in addition to the defaults
|
||||
extend-exclude = '''
|
||||
# A regex preceded with ^/ will apply only to files and directories
|
||||
# in the root of the project.
|
||||
(
|
||||
^/foo.py # exclude a file named foo.py in the root of the project
|
||||
| .*_pb2.py # exclude autogenerated Protocol Buffer files anywhere in the project
|
||||
)
|
||||
'''
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Lookup hierarchy
|
||||
|
||||
Command-line options have defaults that you can see in `--help`. A `pyproject.toml` can
|
||||
override those defaults. Finally, options provided by the user on the command line
|
||||
override both.
|
||||
|
||||
_Black_ will only ever use one `pyproject.toml` file during an entire run. It doesn't
|
||||
look for multiple files, and doesn't compose configuration from different levels of the
|
||||
file hierarchy.
|
||||
|
||||
## Next steps
|
||||
|
||||
A good next step would be configuring auto-discovery so `black .` is all you need
|
||||
instead of laborously listing every file or directory. You can get started by heading
|
||||
over to [File collection and discovery](./file_collection_and_discovery.md).
|
||||
|
||||
Another good choice would be setting up an
|
||||
[integration with your editor](../integrations/editors.md) of choice or with
|
||||
[pre-commit for source version control](../integrations/source_version_control.md).
|
28
docs/version_control_integration.md
Normal file
28
docs/version_control_integration.md
Normal file
@ -0,0 +1,28 @@
|
||||
[//]: # "NOTE: THIS FILE WAS AUTOGENERATED FROM README.md"
|
||||
|
||||
# Version control integration
|
||||
|
||||
Use [pre-commit](https://pre-commit.com/). Once you
|
||||
[have it installed](https://pre-commit.com/#install), add this to the
|
||||
`.pre-commit-config.yaml` in your repository:
|
||||
|
||||
```yaml
|
||||
repos:
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 20.8b1 # Replace by any tag/version: https://github.com/psf/black/tags
|
||||
hooks:
|
||||
- id: black
|
||||
language_version: python3 # Should be a command that runs python3.6+
|
||||
```
|
||||
|
||||
Then run `pre-commit install` and you're ready to go.
|
||||
|
||||
Avoid using `args` in the hook. Instead, store necessary configuration in
|
||||
`pyproject.toml` so that editors and command-line usage of Black all behave consistently
|
||||
for your project. See _Black_'s own
|
||||
[pyproject.toml](https://github.com/psf/black/blob/master/pyproject.toml) for an
|
||||
example.
|
||||
|
||||
If you're already using Python 3.7, switch the `language_version` accordingly. Finally,
|
||||
`stable` is a branch that tracks the latest release on PyPI. If you'd rather run on
|
||||
master, this is also an option.
|
@ -5,11 +5,13 @@
|
||||
a coverage-guided fuzzer I'm working on.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
import hypothesmith
|
||||
from hypothesis import HealthCheck, given, settings
|
||||
from hypothesis import strategies as st
|
||||
from hypothesis import HealthCheck, given, settings, strategies as st
|
||||
|
||||
import black
|
||||
from blib2to3.pgen2.tokenize import TokenError
|
||||
|
||||
|
||||
# This test uses the Hypothesis and Hypothesmith libraries to generate random
|
||||
@ -18,7 +20,7 @@
|
||||
max_examples=1000, # roughly 1k tests/minute, or half that under coverage
|
||||
derandomize=True, # deterministic mode to avoid CI flakiness
|
||||
deadline=None, # ignore Hypothesis' health checks; we already know that
|
||||
suppress_health_check=list(HealthCheck), # this is slow and filter-heavy.
|
||||
suppress_health_check=HealthCheck.all(), # this is slow and filter-heavy.
|
||||
)
|
||||
@given(
|
||||
# Note that while Hypothesmith might generate code unlike that written by
|
||||
@ -30,9 +32,7 @@
|
||||
black.FileMode,
|
||||
line_length=st.just(88) | st.integers(0, 200),
|
||||
string_normalization=st.booleans(),
|
||||
preview=st.booleans(),
|
||||
is_pyi=st.booleans(),
|
||||
magic_trailing_comma=st.booleans(),
|
||||
),
|
||||
)
|
||||
def test_idempotent_any_syntatically_valid_python(
|
||||
@ -42,7 +42,23 @@ def test_idempotent_any_syntatically_valid_python(
|
||||
compile(src_contents, "<string>", "exec") # else the bug is in hypothesmith
|
||||
|
||||
# Then format the code...
|
||||
dst_contents = black.format_str(src_contents, mode=mode)
|
||||
try:
|
||||
dst_contents = black.format_str(src_contents, mode=mode)
|
||||
except black.InvalidInput:
|
||||
# This is a bug - if it's valid Python code, as above, Black should be
|
||||
# able to cope with it. See issues #970, #1012, #1358, and #1557.
|
||||
# TODO: remove this try-except block when issues are resolved.
|
||||
return
|
||||
except TokenError as e:
|
||||
if ( # Special-case logic for backslashes followed by newlines or end-of-input
|
||||
e.args[0] == "EOF in multi-line statement"
|
||||
and re.search(r"\\($|\r?\n)", src_contents) is not None
|
||||
):
|
||||
# This is a bug - if it's valid Python code, as above, Black should be
|
||||
# able to cope with it. See issue #1012.
|
||||
# TODO: remove this block when the issue is resolved.
|
||||
return
|
||||
raise
|
||||
|
||||
# And check that we got equivalent and stable output.
|
||||
black.assert_equivalent(src_contents, dst_contents)
|
||||
@ -60,14 +76,10 @@ def test_idempotent_any_syntatically_valid_python(
|
||||
# (if you want only bounded fuzzing, just use `pytest fuzz.py`)
|
||||
try:
|
||||
import sys
|
||||
|
||||
import atheris
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
test = test_idempotent_any_syntatically_valid_python
|
||||
atheris.Setup(
|
||||
sys.argv,
|
||||
test.hypothesis.fuzz_one_input, # type: ignore[attr-defined]
|
||||
)
|
||||
atheris.Setup(sys.argv, test.hypothesis.fuzz_one_input)
|
||||
atheris.Fuzz()
|
@ -7,20 +7,29 @@
|
||||
import venv
|
||||
import zipfile
|
||||
from argparse import ArgumentParser, Namespace
|
||||
from collections.abc import Generator
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from functools import lru_cache, partial
|
||||
from pathlib import Path
|
||||
from typing import NamedTuple, Optional, Union, cast
|
||||
from typing import ( # type: ignore # typing can't see Literal
|
||||
Generator,
|
||||
List,
|
||||
Literal,
|
||||
NamedTuple,
|
||||
Optional,
|
||||
Tuple,
|
||||
Union,
|
||||
cast,
|
||||
)
|
||||
from urllib.request import urlopen, urlretrieve
|
||||
|
||||
PYPI_INSTANCE = "https://pypi.org/pypi"
|
||||
PYPI_TOP_PACKAGES = (
|
||||
"https://hugovk.github.io/top-pypi-packages/top-pypi-packages.min.json"
|
||||
"https://hugovk.github.io/top-pypi-packages/top-pypi-packages-{days}-days.json"
|
||||
)
|
||||
INTERNAL_BLACK_REPO = f"{tempfile.gettempdir()}/__black"
|
||||
|
||||
ArchiveKind = Union[tarfile.TarFile, zipfile.ZipFile]
|
||||
Days = Union[Literal[30], Literal[365]]
|
||||
|
||||
subprocess.run = partial(subprocess.run, check=True) # type: ignore
|
||||
# https://github.com/python/mypy/issues/1484
|
||||
@ -55,8 +64,8 @@ def get_pypi_download_url(package: str, version: Optional[str]) -> str:
|
||||
return cast(str, source["url"])
|
||||
|
||||
|
||||
def get_top_packages() -> list[str]:
|
||||
with urlopen(PYPI_TOP_PACKAGES) as page:
|
||||
def get_top_packages(days: Days) -> List[str]:
|
||||
with urlopen(PYPI_TOP_PACKAGES.format(days=days)) as page:
|
||||
result = json.load(page)
|
||||
|
||||
return [package["project"] for package in result["rows"]]
|
||||
@ -65,7 +74,7 @@ def get_top_packages() -> list[str]:
|
||||
def get_package_source(package: str, version: Optional[str]) -> str:
|
||||
if package == "cpython":
|
||||
if version is None:
|
||||
version = "main"
|
||||
version = "master"
|
||||
return f"https://github.com/python/cpython/archive/{version}.zip"
|
||||
elif package == "pypy":
|
||||
if version is None:
|
||||
@ -119,12 +128,13 @@ def get_package(
|
||||
|
||||
def download_and_extract_top_packages(
|
||||
directory: Path,
|
||||
days: Days = 365,
|
||||
workers: int = 8,
|
||||
limit: slice = DEFAULT_SLICE,
|
||||
) -> Generator[Path, None, None]:
|
||||
with ThreadPoolExecutor(max_workers=workers) as executor:
|
||||
bound_downloader = partial(get_package, version=None, directory=directory)
|
||||
for package in executor.map(bound_downloader, get_top_packages()[limit]):
|
||||
for package in executor.map(bound_downloader, get_top_packages(days)[limit]):
|
||||
if package is not None:
|
||||
yield package
|
||||
|
||||
@ -151,7 +161,7 @@ def git_switch_branch(
|
||||
subprocess.run(args, cwd=repo)
|
||||
|
||||
|
||||
def init_repos(options: Namespace) -> tuple[Path, ...]:
|
||||
def init_repos(options: Namespace) -> Tuple[Path, ...]:
|
||||
options.output.mkdir(exist_ok=True)
|
||||
|
||||
if options.top_packages:
|
||||
@ -207,7 +217,7 @@ def format_repo_with_version(
|
||||
git_switch_branch(black_version.version, repo=black_repo)
|
||||
git_switch_branch(current_branch, repo=repo, new=True, from_branch=from_branch)
|
||||
|
||||
format_cmd: list[Union[Path, str]] = [
|
||||
format_cmd: List[Union[Path, str]] = [
|
||||
black_runner(black_version.version, black_repo),
|
||||
(black_repo / "black.py").resolve(),
|
||||
".",
|
||||
@ -223,7 +233,7 @@ def format_repo_with_version(
|
||||
return current_branch
|
||||
|
||||
|
||||
def format_repos(repos: tuple[Path, ...], options: Namespace) -> None:
|
||||
def format_repos(repos: Tuple[Path, ...], options: Namespace) -> None:
|
||||
black_versions = tuple(
|
||||
BlackVersion(*version.split(":")) for version in options.versions
|
||||
)
|
||||
@ -238,15 +248,17 @@ def format_repos(repos: tuple[Path, ...], options: Namespace) -> None:
|
||||
black_version=black_version,
|
||||
input_directory=options.input,
|
||||
)
|
||||
git_switch_branch("main", repo=repo)
|
||||
git_switch_branch("master", repo=repo)
|
||||
|
||||
git_switch_branch("main", repo=options.black_repo)
|
||||
git_switch_branch("master", repo=options.black_repo)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = ArgumentParser(description="""Black Gallery is a script that
|
||||
parser = ArgumentParser(
|
||||
description="""Black Gallery is a script that
|
||||
automates the process of applying different Black versions to a selected
|
||||
PyPI package and seeing the results between versions.""")
|
||||
PyPI package and seeing the results between versions."""
|
||||
)
|
||||
|
||||
group = parser.add_mutually_exclusive_group(required=True)
|
||||
group.add_argument("-p", "--pypi-package", help="PyPI package to download.")
|
||||
@ -284,7 +296,7 @@ def main() -> None:
|
||||
type=Path,
|
||||
help="Output directory to download and put result artifacts.",
|
||||
)
|
||||
parser.add_argument("versions", nargs="*", default=("main",), help="")
|
||||
parser.add_argument("versions", nargs="*", default=("master",), help="")
|
||||
|
||||
options = parser.parse_args()
|
||||
repos = init_repos(options)
|
||||
|
37
mypy.ini
Normal file
37
mypy.ini
Normal file
@ -0,0 +1,37 @@
|
||||
[mypy]
|
||||
# Specify the target platform details in config, so your developers are
|
||||
# free to run mypy on Windows, Linux, or macOS and get consistent
|
||||
# results.
|
||||
python_version=3.6
|
||||
platform=linux
|
||||
|
||||
show_column_numbers=True
|
||||
|
||||
# show error messages from unrelated files
|
||||
follow_imports=normal
|
||||
|
||||
# suppress errors about unsatisfied imports
|
||||
ignore_missing_imports=True
|
||||
|
||||
# be strict
|
||||
disallow_untyped_calls=True
|
||||
warn_return_any=True
|
||||
strict_optional=True
|
||||
warn_no_return=True
|
||||
warn_redundant_casts=True
|
||||
warn_unused_ignores=True
|
||||
# Until we're not supporting 3.6 primer needs this
|
||||
disallow_any_generics=False
|
||||
|
||||
# The following are off by default. Flip them on if you feel
|
||||
# adventurous.
|
||||
disallow_untyped_defs=True
|
||||
check_untyped_defs=True
|
||||
|
||||
# No incremental mode
|
||||
cache_dir=/dev/null
|
||||
|
||||
[mypy-aiohttp.*]
|
||||
follow_imports=skip
|
||||
[mypy-_version]
|
||||
follow_imports=skip
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user