Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .flake8
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
[flake8]
# B905 should be enabled when we drop support for 3.9
ignore = E203, E266, E501, E701, E704, W503, B905, B907
ignore = E203, E266, E501, E701, E704, W503, B907
# 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
max-line-length = 80
Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ this = "code"
And run it with these arguments:

```sh
$ black file.py --target-version py39
$ black file.py --target-version py310
```

The resulting error is:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/fuzz.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12.4", "3.13", "3.14"]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]

steps:
- uses: actions/checkout@v5
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pypi_upload.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ jobs:
github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'ci: build all wheels')
run: |
{
CIBW_BUILD="cp39-*" cibuildwheel --print-build-identifiers --platform linux | pyp 'json.dumps({"only": x, "os": "ubuntu-latest"})'
CIBW_BUILD="cp310-*" cibuildwheel --print-build-identifiers --platform linux | pyp 'json.dumps({"only": x, "os": "ubuntu-latest"})'
CIBW_BUILD="cp314-*" 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:
Expand Down
8 changes: 3 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,14 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12.10", "3.13", "3.14", "pypy-3.9"]
python-version: ["3.10", "3.11", "3.12.10", "3.13", "3.14", "pypy-3.11"]
os: [ubuntu-latest, macOS-latest, windows-latest, windows-11-arm]
exclude:
# setup-python only supports 3.11+ on arm64 windows
- os: windows-11-arm
python-version: "3.9"
# setup-python only supports CPython 3.11+ on arm64 windows
- os: windows-11-arm
python-version: "3.10"
- os: windows-11-arm
python-version: "pypy-3.9"
python-version: "pypy-3.11"

steps:
- uses: actions/checkout@v5
Expand Down
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

<!-- Include any especially major or disruptive changes here -->

- Black no longer supports running with Python 3.9 (#4842)

### Stable style

<!-- Changes that affect Black's stable style -->
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ 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.10+ to
run. If you want to format Jupyter Notebooks, install with
`pip install "black[jupyter]"`.

### Usage

Expand Down
3 changes: 1 addition & 2 deletions action/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
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"
Expand Down Expand Up @@ -95,7 +94,7 @@ def read_version_specifier_from_pyproject() -> str:
return version


def find_black_version_in_array(array: object) -> Union[str, None]:
def find_black_version_in_array(array: object) -> str | None:
if not isinstance(array, list):
return None
try:
Expand Down
4 changes: 2 additions & 2 deletions autoload/black.vim
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ def _initialize_black_env(upgrade=False):
return True

pyver = sys.version_info[:3]
if pyver < (3, 9):
print("Sorry, Black requires Python 3.9+ to run.")
if pyver < (3, 10):
print("Sorry, Black requires Python 3.10+ to run.")
return False

from pathlib import Path
Expand Down
2 changes: 1 addition & 1 deletion docs/contributing/the_basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Further examples of invoking the tests
(.venv)$ tox --parallel=auto

# Run tests on a specific python version
(.venv)$ tox -e py39
(.venv)$ tox -e py314

# Run an individual test
(.venv)$ pytest -k <test name>
Expand Down
5 changes: 3 additions & 2 deletions docs/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ Also, you can try out _Black_ online for minimal fuss on 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.10+ 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`.

Expand Down
4 changes: 2 additions & 2 deletions docs/integrations/editors.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,8 @@ Configuration:

#### 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
This plugin **requires Vim 7.0+ built with Python 3.10+ support**. It needs Python 3.10
to be able to run _Black_ inside the Vim process which is much faster than calling an
external command.

##### `vim-plug`
Expand Down
20 changes: 10 additions & 10 deletions gallery/gallery.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
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 NamedTuple, Union, cast
from urllib.request import urlopen, urlretrieve

PYPI_INSTANCE = "https://pypi.org/pypi"
Expand All @@ -28,10 +28,10 @@

class BlackVersion(NamedTuple):
version: str
config: Optional[str] = None
config: str | None = None


def get_pypi_download_url(package: str, version: Optional[str]) -> str:
def get_pypi_download_url(package: str, version: str | None) -> str:
with urlopen(PYPI_INSTANCE + f"/{package}/json") as page:
metadata = json.load(page)

Expand Down Expand Up @@ -62,7 +62,7 @@ def get_top_packages() -> list[str]:
return [package["project"] for package in result["rows"]]


def get_package_source(package: str, version: Optional[str]) -> str:
def get_package_source(package: str, version: str | None) -> str:
if package == "cpython":
if version is None:
version = "main"
Expand Down Expand Up @@ -93,7 +93,7 @@ def get_first_archive_member(archive: ArchiveKind) -> str:
return archive.namelist()[0]


def download_and_extract(package: str, version: Optional[str], directory: Path) -> Path:
def download_and_extract(package: str, version: str | None, directory: Path) -> Path:
source = get_package_source(package, version)

local_file, _ = urlretrieve(source, directory / f"{package}-src")
Expand All @@ -104,8 +104,8 @@ def download_and_extract(package: str, version: Optional[str], directory: Path)


def get_package(
package: str, version: Optional[str], directory: Path
) -> Optional[Path]:
package: str, version: str | None, directory: Path
) -> Path | None:
try:
return download_and_extract(package, version, directory)
except Exception:
Expand Down Expand Up @@ -140,7 +140,7 @@ def git_add_and_commit(msg: str, repo: Path) -> None:


def git_switch_branch(
branch: str, repo: Path, new: bool = False, from_branch: Optional[str] = None
branch: str, repo: Path, new: bool = False, from_branch: str | None = None
) -> None:
args = ["git", "checkout"]
if new:
Expand Down Expand Up @@ -198,7 +198,7 @@ def black_runner(version: str, black_repo: Path) -> Path:

def format_repo_with_version(
repo: Path,
from_branch: Optional[str],
from_branch: str | None,
black_repo: Path,
black_version: BlackVersion,
input_directory: Path,
Expand All @@ -207,7 +207,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[Path | str] = [
black_runner(black_version.version, black_repo),
(black_repo / "black.py").resolve(),
".",
Expand Down
4 changes: 2 additions & 2 deletions plugin/black.vim
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ if v:version < 700 || !has('python3')
call add(messages, "vim7.0+")
endif
if !has('python3')
call add(messages, "Python 3.9 support")
call add(messages, "Python 3.10 support")
endif

echo "The black.vim plugin requires" join(messages, " and ")
Expand Down Expand Up @@ -81,11 +81,11 @@ endif

function BlackComplete(ArgLead, CmdLine, CursorPos)
return [
\ 'target_version=py39',
\ 'target_version=py310',
\ 'target_version=py311',
\ 'target_version=py312',
\ 'target_version=py313',
\ 'target_version=py314',
\ ]
endfunction

Expand Down
11 changes: 5 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

[tool.black]
line-length = 88
target-version = ['py39']
target-version = ['py310']
include = '\.pyi?$'
extend-exclude = '''
/(
Expand Down Expand Up @@ -35,7 +35,7 @@ name = "black"
description = "The uncompromising code formatter."
license = "MIT"
license-files = ["LICENSE"]
requires-python = ">=3.9"
requires-python = ">=3.10"
authors = [
{ name = "Łukasz Langa", email = "lukasz@langa.pl" },
]
Expand All @@ -55,7 +55,6 @@ classifiers = [
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
Expand Down Expand Up @@ -153,10 +152,10 @@ options = { debug_level = "0" }
build-verbosity = 1

# So these are the environments we target:
# - Python: CPython 3.9+ only
# - Python: CPython 3.10+ only
# - Architecture (64-bit only): amd64 / x86_64, universal2, and arm64
# - OS: Linux (no musl), Windows, and macOS
build = "cp3*"
build = "cp31*"
skip = [
"*-manylinux_i686",
"*-musllinux_*",
Expand Down Expand Up @@ -229,7 +228,7 @@ branch = true
# 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.9"
python_version = "3.10"
mypy_path = "src"
strict = true
strict_bytes = true
Expand Down
4 changes: 2 additions & 2 deletions scripts/check_pre_commit_rev_in_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ def main(changes: str, source_version_control: str) -> None:
changes_html = commonmark.commonmark(changes)
changes_soup = BeautifulSoup(changes_html, "html.parser")
headers = changes_soup.find_all("h2")
latest_tag, *_ = [
latest_tag, *_ = (
header.string for header in headers if header.string != "Unreleased"
]
)

source_version_control_html = commonmark.commonmark(source_version_control)
source_version_control_soup = BeautifulSoup(
Expand Down
2 changes: 1 addition & 1 deletion scripts/migrate-black.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def blackify(base_branch: str, black_command: str, logger: logging.Logger) -> in

git("checkout", base_branch, f"-b{current_branch}-black")

for last_commit, commit in zip(commits, commits[1:]):
for last_commit, commit in zip(commits, commits[1:], strict=False):
allow_empty = (
b"--allow-empty" in run(["git", "apply", "-h"], stdout=PIPE).stdout
)
Expand Down
Loading