1{
2 stdenv,
3 lib,
4 buildPythonPackage,
5 fetchPypi,
6 fetchpatch,
7 pythonOlder,
8 pytestCheckHook,
9 aiohttp,
10 click,
11 colorama,
12 hatch-fancy-pypi-readme,
13 hatch-vcs,
14 hatchling,
15 ipython,
16 mypy-extensions,
17 packaging,
18 pathspec,
19 parameterized,
20 platformdirs,
21 tokenize-rt,
22 tomli,
23 typing-extensions,
24 uvloop,
25}:
26
27buildPythonPackage rec {
28 pname = "black";
29 version = "25.1.0";
30 format = "pyproject";
31
32 disabled = pythonOlder "3.8";
33
34 src = fetchPypi {
35 inherit pname version;
36 hash = "sha256-M0ltXNEiKtczkTUrSujaFSU8Xeibk6gLPiyNmhnsJmY=";
37 };
38
39 patches = [
40 (fetchpatch {
41 name = "click-8.2-compat-1.patch";
42 url = "https://github.com/psf/black/commit/14e1de805a5d66744a08742cad32d1660bf7617a.patch";
43 hash = "sha256-fHRlMetE6+09MKkuFNQQr39nIKeNrqwQuBNqfIlP4hc=";
44 })
45 (fetchpatch {
46 name = "click-8.2-compat-2.patch";
47 url = "https://github.com/psf/black/commit/ed64d89faa7c738c4ba0006710f7e387174478af.patch";
48 hash = "sha256-df/J6wiRqtnHk3mAY3ETiRR2G4hWY1rmZMfm2rjP2ZQ=";
49 })
50 (fetchpatch {
51 name = "click-8.2-compat-3.patch";
52 url = "https://github.com/psf/black/commit/b0f36f5b4233ef4cf613daca0adc3896d5424159.patch";
53 hash = "sha256-SGLCxbgrWnAi79IjQOb2H8mD/JDbr2SGfnKyzQsJrOA=";
54 })
55 ];
56
57 nativeBuildInputs = [
58 hatch-fancy-pypi-readme
59 hatch-vcs
60 hatchling
61 ];
62
63 propagatedBuildInputs = [
64 click
65 mypy-extensions
66 packaging
67 pathspec
68 platformdirs
69 ]
70 ++ lib.optionals (pythonOlder "3.11") [
71 tomli
72 typing-extensions
73 ];
74
75 optional-dependencies = {
76 colorama = [ colorama ];
77 d = [ aiohttp ];
78 uvloop = [ uvloop ];
79 jupyter = [
80 ipython
81 tokenize-rt
82 ];
83 };
84
85 # Necessary for the tests to pass on Darwin with sandbox enabled.
86 # Black starts a local server and needs to bind a local address.
87 __darwinAllowLocalNetworking = true;
88
89 nativeCheckInputs = [
90 pytestCheckHook
91 parameterized
92 ]
93 ++ lib.flatten (lib.attrValues optional-dependencies);
94
95 pytestFlags = [
96 "-Wignore::DeprecationWarning"
97 ];
98
99 preCheck = ''
100 export PATH="$PATH:$out/bin"
101
102 # The top directory /build matches black's DEFAULT_EXCLUDE regex.
103 # Make /build the project root for black tests to avoid excluding files.
104 touch ../.git
105 ''
106 + lib.optionalString stdenv.hostPlatform.isDarwin ''
107 # Work around https://github.com/psf/black/issues/2105
108 export TMPDIR="/tmp"
109 '';
110
111 disabledTests = [
112 # requires network access
113 "test_gen_check_output"
114 # broken on Python 3.13.4
115 # FIXME: remove this when fixed upstream
116 "test_simple_format[pep_701]"
117 ]
118 ++ lib.optionals stdenv.hostPlatform.isDarwin [
119 # fails on darwin
120 "test_expression_diff"
121 # Fail on Hydra, see https://github.com/NixOS/nixpkgs/pull/130785
122 "test_bpo_2142_workaround"
123 "test_skip_magic_trailing_comma"
124 ];
125 # multiple tests exceed max open files on hydra builders
126 doCheck = !(stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isAarch64);
127
128 meta = with lib; {
129 description = "Uncompromising Python code formatter";
130 homepage = "https://github.com/psf/black";
131 changelog = "https://github.com/psf/black/blob/${version}/CHANGES.md";
132 license = licenses.mit;
133 mainProgram = "black";
134 maintainers = with maintainers; [
135 sveitser
136 autophagy
137 ];
138 };
139}