Skip to content

Commit 72685e3

Browse files
authored
Implement Python formatting with black (#720)
1 parent 9a35078 commit 72685e3

File tree

10 files changed

+182
-10
lines changed

10 files changed

+182
-10
lines changed

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ lint:
1212
flatpak run --user --command=/usr/lib/sdk/node18/bin/node --filesystem=host:ro org.gnome.Sdk//45 node_modules/.bin/eslint --max-warnings=0 src
1313
# rustfmt
1414
flatpak run --user --command=/usr/lib/sdk/rust-stable/bin/rustfmt --filesystem=host:ro org.gnome.Sdk//45 --check --edition 2021 src/**/*.rs
15+
# black
16+
./black.sh --check src/**/*.py
1517
# gettext
1618
find po/ -type f -name "*po" -print0 | xargs -0 -n1 msgfmt -o /dev/null --check
1719
# Flatpak manifests

black.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/usr/bin/env bash
2+
# This is a small wrapper around black - the Python code formatter.
3+
# The script will setup and activate a virtual env in .venv if black is not
4+
# found in PATH.
5+
#
6+
# Still requires Python 3.
7+
set -e
8+
9+
if ! which black &>/dev/null; then
10+
if [ ! -d ".venv" ]; then
11+
echo "Note: black was not found on your system. A virtualenv is created in .venv."
12+
python3 -m venv .venv
13+
fi
14+
source .venv/bin/activate
15+
if ! which black &>/dev/null; then
16+
pip3 install black
17+
fi
18+
fi
19+
20+
exec black "$@"

build-aux/README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Build Utilities
2+
3+
This directory contains the Flatpak Manifest and other build utilities.
4+
5+
## Workbench Flatpak Manifests
6+
7+
### Python Black Dependency
8+
9+
`modules/python-black.json` contains the Flatpak modules to install [https://github.com/psf/black](black), the
10+
uncompromising Python code formatter.
11+
12+
This file is partially auto-generated. Here is how to generate it:
13+
14+
1. Obtain an up-to-date copy of [flatpak-builder-tools](https://github.com/flatpak/flatpak-builder-tools).
15+
2. Make sure you have a Python virtualenv activated with the dependencies for the `pip` generator from the repo above.
16+
3. Run `python3 <...>/flatpak-builder-tools/pip/flatpak-pip-generator black -o modules/python-black --build-isolation`
17+
18+
You will notice that Workbench will now not build. This is due to these issues:
19+
20+
- https://github.com/flatpak/flatpak-builder-tools/issues/380
21+
- https://github.com/pypa/pip/issues/7863
22+
23+
This means that the generated JSON file now needs its build dependencies manually added. Check the build dependencies
24+
of black and their dependencies and add them to the JSON as well. Brute-forcing the build to obtain missing packages
25+
may help as does referencing old commits of the file. You can also use the generator command to generate dependencies
26+
for them and then merge it into the file by hand, but note that you will also need to manually collect their build
27+
dependencies too.
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
{
2+
"name": "python3-black",
3+
"buildsystem": "simple",
4+
"build-commands": [
5+
"pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"black\""
6+
],
7+
"sources": [
8+
{
9+
"type": "file",
10+
"url": "https://files.pythonhosted.org/packages/36/bf/a462f36723824c60dc3db10528c95656755964279a6a5c287b4f9fd0fa84/black-23.10.1.tar.gz",
11+
"sha256": "1f8ce316753428ff68749c65a5f7844631aa18c8679dfd3ca9dc1a289979c258"
12+
},
13+
{
14+
"type": "file",
15+
"url": "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl",
16+
"sha256": "ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"
17+
},
18+
{
19+
"type": "file",
20+
"url": "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl",
21+
"sha256": "4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"
22+
},
23+
{
24+
"type": "file",
25+
"url": "https://files.pythonhosted.org/packages/ec/1a/610693ac4ee14fcdf2d9bf3c493370e4f2ef7ae2e19217d7a237ff42367d/packaging-23.2-py3-none-any.whl",
26+
"sha256": "8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"
27+
},
28+
{
29+
"type": "file",
30+
"url": "https://files.pythonhosted.org/packages/b4/2a/9b1be29146139ef459188f5e420a66e835dda921208db600b7037093891f/pathspec-0.11.2-py3-none-any.whl",
31+
"sha256": "1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"
32+
},
33+
{
34+
"type": "file",
35+
"url": "https://files.pythonhosted.org/packages/56/29/3ec311dc18804409ecf0d2b09caa976f3ae6215559306b5b530004e11156/platformdirs-3.11.0-py3-none-any.whl",
36+
"sha256": "e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e"
37+
},
38+
{
39+
"type": "file",
40+
"url": "https://files.pythonhosted.org/packages/6b/be/0f2f4a5e8adc114a02b63d92bf8edbfa24db6fc602fca83c885af2479e0e/editables-0.5-py3-none-any.whl",
41+
"sha256": "61e5ffa82629e0d8bfe09bc44a07db3c1ab8ed1ce78a6980732870f19b5e7d4c"
42+
},
43+
{
44+
"type": "file",
45+
"url": "https://files.pythonhosted.org/packages/76/56/8ccca673e2c896931722f876bf040c0b6a7d8c1a128be60516a8a55bb27a/hatchling-1.18.0-py3-none-any.whl",
46+
"sha256": "b66dc254931ec42aa68b5febd1d342c58142cc5267b7ff3b12ba3fa5b4900c93"
47+
},
48+
{
49+
"type": "file",
50+
"url": "https://files.pythonhosted.org/packages/ec/1a/610693ac4ee14fcdf2d9bf3c493370e4f2ef7ae2e19217d7a237ff42367d/packaging-23.2-py3-none-any.whl",
51+
"sha256": "8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"
52+
},
53+
{
54+
"type": "file",
55+
"url": "https://files.pythonhosted.org/packages/b4/2a/9b1be29146139ef459188f5e420a66e835dda921208db600b7037093891f/pathspec-0.11.2-py3-none-any.whl",
56+
"sha256": "1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"
57+
},
58+
{
59+
"type": "file",
60+
"url": "https://files.pythonhosted.org/packages/05/b8/42ed91898d4784546c5f06c60506400548db3f7a4b3fb441cba4e5c17952/pluggy-1.3.0-py3-none-any.whl",
61+
"sha256": "d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"
62+
},
63+
{
64+
"type": "file",
65+
"url": "https://files.pythonhosted.org/packages/ec/40/05cb2725ca7e6c844c66af626c5749efd254ec4506f17a1d01ba79ae9da6/trove_classifiers-2023.10.18-py3-none-any.whl",
66+
"sha256": "20a3da8e3cb65587cc9f5d5b837bf74edeb480bba9bd8cd4f03ab056d6b06c4c"
67+
},
68+
{
69+
"type": "file",
70+
"url": "https://files.pythonhosted.org/packages/00/b1/90cc7881c2e870333eeafa6afb7b27de53418aad1ba5409ad331c96608a1/hatch_vcs-0.3.0-py3-none-any.whl",
71+
"sha256": "60ce59a3fa4664057e4a858b6a96ab0b9dec21bf8f562f836139315bb361be8c"
72+
},
73+
{
74+
"type": "file",
75+
"url": "https://files.pythonhosted.org/packages/0e/a3/b9a8b0adfe672bf0df5901707aa929d30a97ee390ba651910186776746d2/setuptools_scm-8.0.4-py3-none-any.whl",
76+
"sha256": "b47844cd2a84b83b3187a5782c71128c28b4c94cad8bfb871da2784a5cb54c4f"
77+
},
78+
{
79+
"type": "file",
80+
"url": "https://files.pythonhosted.org/packages/24/21/7d397a4b7934ff4028987914ac1044d3b7d52712f30e2ac7a2ae5bc86dd0/typing_extensions-4.8.0-py3-none-any.whl",
81+
"sha256": "8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"
82+
},
83+
{
84+
"type": "file",
85+
"url": "https://files.pythonhosted.org/packages/6b/74/74a15619861065fa75f6170c649cd2fd5467726bb407ec2017d4a3f92d28/hatch_fancy_pypi_readme-23.1.0-py3-none-any.whl",
86+
"sha256": "9a2c0e5d527611701858083bfb355876f26e04a075342b7d4da725ba5a6dd6ea"
87+
},
88+
{
89+
"type": "file",
90+
"url": "https://files.pythonhosted.org/packages/ef/cc/93f7213b2ab5ed383f98ce8020e632ef256b406b8569606c3f160ed8e1c9/setuptools-68.2.2.tar.gz",
91+
"sha256": "4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87"
92+
},
93+
{
94+
"type": "file",
95+
"url": "https://files.pythonhosted.org/packages/a4/99/78c4f3bd50619d772168bec6a0f34379b02c19c9cced0ed833ecd021fd0d/wheel-0.41.2.tar.gz",
96+
"sha256": "0c5ac5ff2afb79ac23ab82bab027a0be7b5dbcf2e54dc50efe4bf507de1f7985"
97+
},
98+
{
99+
"type": "file",
100+
"url": "https://files.pythonhosted.org/packages/c4/e6/c1ac50fe3eebb38a155155711e6e864e254ce4b6e17fe2429b4c4d5b9e80/flit_core-3.9.0.tar.gz",
101+
"sha256": "72ad266176c4a3fcfab5f2930d76896059851240570ce9a98733b658cb786eba"
102+
}
103+
]
104+
}

build-aux/re.sonny.Workbench.Devel.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"modules/blueprint-compiler.json",
4646
"modules/biome.json",
4747
"modules/icon-development-kit.json",
48+
"modules/python-black.json",
4849
{
4950
"name": "Workbench",
5051
"buildsystem": "meson",

build-aux/re.sonny.Workbench.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"modules/blueprint-compiler.json",
4646
"modules/biome.json",
4747
"modules/icon-development-kit.json",
48+
"modules/python-black.json",
4849
{
4950
"name": "Workbench",
5051
"buildsystem": "meson",

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"lint-staged": {
2828
"*.{css,json,md,yaml,yml}": "prettier --write",
2929
"*.{js,cjs,mjs}": "eslint --fix",
30+
"*.py": "./black.sh",
3031
"*.rs": "flatpak run --user --command=/usr/lib/sdk/rust-stable/bin/rustfmt --filesystem=host org.gnome.Sdk//45 --edition 2021"
3132
}
3233
}

src/Library/demos/Welcome/main.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,7 @@
77

88

99
def greet(_widget):
10-
dialog = Adw.MessageDialog(
11-
body="Hello World!",
12-
transient_for=workbench.window
13-
)
10+
dialog = Adw.MessageDialog(body="Hello World!", transient_for=workbench.window)
1411

1512
dialog.add_response("ok", "Ok")
1613
dialog.connect("response", dialog_response)
@@ -24,11 +21,7 @@ def dialog_response(dialog: Adw.MessageDialog, response: str):
2421

2522
subtitle_box: Gtk.Box = workbench.builder.get_object("subtitle")
2623

27-
button = Gtk.Button(
28-
label="Press me",
29-
margin_top=6,
30-
css_classes=["suggested-action"]
31-
)
24+
button = Gtk.Button(label="Press me", margin_top=6, css_classes=["suggested-action"])
3225
button.connect("clicked", greet)
3326

3427
subtitle_box.append(button)

src/langs/python/python-previewer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
gi.require_version("Gtk", "4.0")
2323
gi.require_version("Adw", "1")
2424
gi.require_version("Graphene", "1.0")
25-
gi.require_version('Gsk', '4.0')
25+
gi.require_version("Gsk", "4.0")
2626

2727
from gi.repository import GLib, Gdk, Gtk, Adw, Graphene, Gio, Gsk
2828
from gi.repository.Gio import DBusConnection, DBusConnectionFlags

src/window.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,25 @@ export default function Window({ application, session }) {
242242
return stdout;
243243
}
244244

245+
function formatPythonCode(text) {
246+
const blackLauncher = Gio.SubprocessLauncher.new(
247+
Gio.SubprocessFlags.STDIN_PIPE |
248+
Gio.SubprocessFlags.STDOUT_PIPE |
249+
Gio.SubprocessFlags.STDERR_PIPE,
250+
);
251+
252+
const blackProcess = blackLauncher.spawnv(["black", "--quiet", "-"]);
253+
254+
const [success, stdout, stderr] = blackProcess.communicate_utf8(text, null);
255+
256+
if (!success || stderr !== "") {
257+
console.error(`Error running black: ${stderr}`);
258+
return text;
259+
}
260+
261+
return stdout;
262+
}
263+
245264
async function formatCode() {
246265
if (panel_code.panel.visible) {
247266
if (panel_code.language === "JavaScript") {
@@ -255,6 +274,10 @@ export default function Window({ application, session }) {
255274
await format(langs.rust.document.code_view, (text) => {
256275
return formatRustCode(text);
257276
});
277+
} else if (panel_code.language === "Python") {
278+
await format(langs.python.document.code_view, (text) => {
279+
return formatPythonCode(text);
280+
});
258281
}
259282
}
260283

0 commit comments

Comments
 (0)