diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
new file mode 100644
index 000000000..ca7306898
--- /dev/null
+++ b/.github/workflows/lint.yml
@@ -0,0 +1,19 @@
+name: Lint
+
+on: [push, pull_request, workflow_dispatch]
+
+env:
+ FORCE_COLOR: 1
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ persist-credentials: false
+ - uses: actions/setup-python@v5
+ with:
+ python-version: "3.x"
+ - uses: tox-dev/action-pre-commit-uv@v1
diff --git a/.github/workflows/update.yml b/.github/workflows/update.yml
index e162106f3..23259e2fe 100644
--- a/.github/workflows/update.yml
+++ b/.github/workflows/update.yml
@@ -15,7 +15,7 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: "3.x"
- - uses: astral-sh/setup-uv@v4
+ - uses: astral-sh/setup-uv@v5
- uses: actions/checkout@v4
- run: sudo apt-get install -y gettext
- run: uv run generate.py # generates "index.html"
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 000000000..1605084dc
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,38 @@
+repos:
+ - repo: https://github.com/astral-sh/ruff-pre-commit
+ rev: v0.8.4
+ hooks:
+ - id: ruff
+ args: [--fix, --exit-non-zero-on-fix]
+ - id: ruff-format
+
+ - repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v5.0.0
+ hooks:
+ - id: check-added-large-files
+ - id: check-case-conflict
+ - id: check-merge-conflict
+ - id: check-toml
+ - id: check-yaml
+ - id: debug-statements
+ - id: end-of-file-fixer
+ - id: forbid-submodules
+ - id: trailing-whitespace
+
+ - repo: https://github.com/python-jsonschema/check-jsonschema
+ rev: 0.30.0
+ hooks:
+ - id: check-github-workflows
+
+ - repo: https://github.com/rhysd/actionlint
+ rev: v1.7.5
+ hooks:
+ - id: actionlint
+
+ - repo: meta
+ hooks:
+ - id: check-hooks-apply
+ - id: check-useless-excludes
+
+ci:
+ autoupdate_schedule: quarterly
diff --git a/completion.py b/completion.py
index 26ca52746..8cd7959a8 100644
--- a/completion.py
+++ b/completion.py
@@ -14,7 +14,7 @@ def branches_from_devguide(devguide_dir: Path) -> list[str]:
p = devguide_dir.joinpath('include/release-cycle.json')
data = json.loads(p.read_text())
return [
- branch for branch in data if data[branch]["status"] in ("bugfix", "security")
+ branch for branch in data if data[branch]['status'] in ('bugfix', 'security')
]
@@ -22,7 +22,9 @@ def get_completion(clones_dir: str, repo: str) -> tuple[float, int]:
clone_path = Path(clones_dir, repo)
for branch in branches_from_devguide(Path(clones_dir, 'devguide')) + ['master']:
try:
- git.Repo.clone_from(f'https://github.com/{repo}.git', clone_path, branch=branch)
+ git.Repo.clone_from(
+ f'https://github.com/{repo}.git', clone_path, branch=branch
+ )
except git.GitCommandError:
print(f'failed to clone {repo} {branch}')
translators_number = 0
@@ -32,6 +34,10 @@ def get_completion(clones_dir: str, repo: str) -> tuple[float, int]:
break
with TemporaryDirectory() as tmpdir:
completion = potodo.merge_and_scan_path(
- clone_path, pot_path=Path(clones_dir, 'cpython/Doc/build/gettext'), merge_path=Path(tmpdir), hide_reserved=False, api_url=''
+ clone_path,
+ pot_path=Path(clones_dir, 'cpython/Doc/build/gettext'),
+ merge_path=Path(tmpdir),
+ hide_reserved=False,
+ api_url='',
).completion
return completion, translators_number
diff --git a/generate.py b/generate.py
index 217a799f6..fca24a121 100644
--- a/generate.py
+++ b/generate.py
@@ -25,13 +25,22 @@
generation_time = datetime.now(timezone.utc)
with TemporaryDirectory() as clones_dir:
- Repo.clone_from(f'https://github.com/python/devguide.git', devguide_dir := Path(clones_dir, 'devguide'), depth=1)
+ Repo.clone_from(
+ 'https://github.com/python/devguide.git',
+ devguide_dir := Path(clones_dir, 'devguide'),
+ depth=1,
+ )
latest_branch = branches_from_devguide(devguide_dir)[0]
Repo.clone_from(
- f'https://github.com/python/cpython.git', Path(clones_dir, 'cpython'), depth=1, branch=latest_branch
+ 'https://github.com/python/cpython.git',
+ Path(clones_dir, 'cpython'),
+ depth=1,
+ branch=latest_branch,
)
subprocess.run(['make', '-C', Path(clones_dir, 'cpython/Doc'), 'venv'], check=True)
- subprocess.run(['make', '-C', Path(clones_dir, 'cpython/Doc'), 'gettext'], check=True)
+ subprocess.run(
+ ['make', '-C', Path(clones_dir, 'cpython/Doc'), 'gettext'], check=True
+ )
switcher_languages = list(switcher.get_languages())
for language, repo in repositories.get_languages_and_repos(devguide_dir):
if repo:
@@ -78,7 +87,7 @@
{{ language }}
-
+
{% if in_switcher %}
in switcher
@@ -111,7 +120,9 @@
"""
)
-output = template.render(completion_progress=completion_progress, generation_time=generation_time)
+output = template.render(
+ completion_progress=completion_progress, generation_time=generation_time
+)
-with open("index.html", "w") as file:
+with open('index.html', 'w') as file:
file.write(output)
diff --git a/repositories.py b/repositories.py
index c7e09323c..c266a8be1 100644
--- a/repositories.py
+++ b/repositories.py
@@ -1,4 +1,3 @@
-import tempfile
import pathlib
import re
from typing import Generator, Optional
@@ -7,7 +6,9 @@
from docutils.nodes import table, row
-def get_languages_and_repos(devguide_dir: pathlib.Path) -> Generator[tuple[str, Optional[str]], None, None]:
+def get_languages_and_repos(
+ devguide_dir: pathlib.Path,
+) -> Generator[tuple[str, Optional[str]], None, None]:
translating = devguide_dir.joinpath('documentation/translating.rst').read_text()
doctree = core.publish_doctree(translating)
@@ -15,6 +16,8 @@ def get_languages_and_repos(devguide_dir: pathlib.Path) -> Generator[tuple[str,
for row_node in node.traverse(row)[1:]:
language = row_node[0].astext()
repo = row_node[2].astext()
- language_code = re.match(r'.* \((.*)\)', language).group(1).lower().replace('_', '-')
+ language_code = (
+ re.match(r'.* \((.*)\)', language).group(1).lower().replace('_', '-')
+ )
repo_match = re.match(':github:`GitHub <(.*)>`', repo)
yield language_code, repo_match and repo_match.group(1)
diff --git a/ruff.toml b/ruff.toml
new file mode 100644
index 000000000..749ef043d
--- /dev/null
+++ b/ruff.toml
@@ -0,0 +1,2 @@
+[format]
+quote-style = "single"
diff --git a/switcher.py b/switcher.py
index 301b54812..717a04748 100644
--- a/switcher.py
+++ b/switcher.py
@@ -6,7 +6,6 @@
"""
import tomllib
-from collections import defaultdict
from typing import Generator
import requests
@@ -14,24 +13,24 @@
def get_languages() -> Generator[str, None, None]:
data = requests.get(
- "https://raw.githubusercontent.com/"
- "python/docsbuild-scripts/refs/heads/main/config.toml",
+ 'https://raw.githubusercontent.com/'
+ 'python/docsbuild-scripts/refs/heads/main/config.toml',
timeout=10,
).text
config = tomllib.loads(data)
- languages = config["languages"]
- defaults = config["defaults"]
+ languages = config['languages']
+ defaults = config['defaults']
for code, language in languages.items():
- if language.get("in_prod", defaults["in_prod"]):
- yield code.lower().replace("_", "-")
+ if language.get('in_prod', defaults['in_prod']):
+ yield code.lower().replace('_', '-')
def main() -> None:
languages = list(get_languages())
print(languages)
- for code in ("en", "pl", "ar", "zh-cn"):
- print(f"{code}: {code in languages}")
+ for code in ('en', 'pl', 'ar', 'zh-cn'):
+ print(f'{code}: {code in languages}')
-if __name__ == "__main__":
+if __name__ == '__main__':
main()
diff --git a/translators.py b/translators.py
index dd3db133f..2fe11ccbc 100644
--- a/translators.py
+++ b/translators.py
@@ -10,9 +10,11 @@ def get_number(path: Path) -> int:
from_git_history = get_number_from_git_history(path)
return max(from_headers, from_git_history)
+
def get_number_from_git_history(path: Path) -> int:
return len(Repo(path).git.shortlog('-s', 'HEAD').splitlines())
+
def yield_from_headers(path: Path) -> Generator[str, None, None]:
for file in path.rglob('*.po'):
try:
@@ -21,7 +23,7 @@ def yield_from_headers(path: Path) -> Generator[str, None, None]:
continue
if 'Translators:' not in header:
continue
- for translator_record in header[header.index('Translators:') + 1:]:
+ for translator_record in header[header.index('Translators:') + 1 :]:
try:
translator, _year = translator_record.split(', ')
except ValueError:
diff --git a/visitors.py b/visitors.py
index 5c4315c76..fde5d593e 100644
--- a/visitors.py
+++ b/visitors.py
@@ -7,8 +7,13 @@
def get_number_of_visitors(language: str) -> int:
- param = urllib.parse.urlencode({'filters': f'[["contains","event:page",["/{language}/"]]]'})
+ param = urllib.parse.urlencode(
+ {'filters': f'[["contains","event:page",["/{language}/"]]]'}
+ )
r = requests.get(f'https://plausible.io/docs.python.org/export?{param}', timeout=10)
- with zipfile.ZipFile(io.BytesIO(r.content), 'r') as z, z.open('visitors.csv') as csv_file:
+ with (
+ zipfile.ZipFile(io.BytesIO(r.content), 'r') as z,
+ z.open('visitors.csv') as csv_file,
+ ):
csv_reader = csv.DictReader(io.TextIOWrapper(csv_file))
- return sum(int(row["visitors"]) for row in csv_reader)
+ return sum(int(row['visitors']) for row in csv_reader)
|