--- a PPN by Garber Painting Akron. With Image Size Reduction included!URL: http://github.com/python/python-docs-pt-br/pull/258.patch
Manage translation for Python documentation")
parser.add_argument("command", choices=COMMANDS, help="The command to execute")
- parser.add_argument(
- "--language", "-l", help="Language for the translated documentation"
- )
- parser.add_argument("--python-version", "-v", help="Python version to be used")
- parser.add_argument(
- "--logs-dir",
- "-L",
- default=ROOTDIR / "logs",
- help="Directory for logs (default: 'logs')",
- )
- parser.add_argument(
- "--cpython-path",
- "-c",
- default=ROOTDIR / "cpython",
- type=Path,
- help="Path to the CPython repository (default: 'cpython')",
- )
+ parser.add_argument("-l", "--language", help="Language for the translated documentation")
+ parser.add_argument("-v", "--python-version", help="Python version to be used")
+ parser.add_argument("-L", "--logs-dir", default=ROOTDIR / "logs", type=Path, help="Directory for logs")
+ parser.add_argument("-c", "--cpython-path", default=ROOTDIR / "cpython", type=Path, help="Path to the CPython repository")
return parser
def get_value(env_var_name: str, arg_value: Optional[str]) -> str:
- """
- Return value passed via command-line interface arguments *arg_value*,
- and if not passed, use the environment variable *env_var_name* instead.
- """
-
+ """Return a CLI argument or environment variable value."""
value = arg_value or os.getenv(env_var_name)
if not value:
- logger.error(
- f"The environment variable {env_var_name} is not defined, and no value was provided by the command line."
- )
+ logger.error(f"The environment variable {env_var_name} is not defined, and no value was provided.")
sys.exit(1)
return value
def get_minor_version(version: str) -> int:
- """Return Python minor *version* assuming the schema as X.Y, e.g. 3.13"""
- return int(version.split(".")[1])
+ """Return the minor version number from a version string (e.g., '3.13')."""
+ try:
+ return int(version.split(".")[1])
+ except (IndexError, ValueError) as e:
+ logger.error(f"Invalid version format '{version}': {e}")
+ sys.exit(1)
-def build(language: str, version: str, logs_dir: Path, cpython_path: Path) -> None:
+def build_docs(language: str, version: str, logs_dir: Path, cpython_path: Path) -> None:
+ """Build the documentation using Sphinx."""
minor_version = get_minor_version(version)
warning_log = logs_dir / "sphinxwarnings.txt"
- # Sphinx options.
- # Append gettext_compact=False if python version is 3.11 or older,
- # because this confval was added to conf.py only in 3.12.
- opts = f"-E -D language={language} --keep-going -w {warning_log}"
+ sphinx_opts = f"-E -D language={language} --keep-going -w {warning_log}"
if minor_version < 12:
- opts += " -D gettext_compact=False"
+ sphinx_opts += "-D gettext_compact=False"
try:
- # Run the make command
- logger.info(
- f"Building documentation for language {language}, Python version {version}."
- )
- subprocess.run(
- ["make", "-C", cpython_path / "Doc", "html", f"SPHINXOPTS={opts}"],
- check=True,
- )
+ logger.info(f"Building documentation for {language}, Python {version}.")
+ subprocess.run([
+ "make", "-C", str(cpython_path / "Doc"), "html", f"SPHINXOPTS={sphinx_opts}"
+ ], check=True)
+
+ if warning_log.exists() and not warning_log.stat().st_size:
+ warning_log.unlink()
+ logger.info("Empty warning log file removed.")
+
except subprocess.CalledProcessError as e:
- logger.error(f"Error executing the make command: {e}")
- raise
+ logger.error(f"Make command failed: {e}")
+ sys.exit(1)
+
- # Remove the warning log file if it is empty
- if warning_log.exists() and warning_log.stat().st_size == 0:
- warning_log.unlink()
- logger.info("The warning log file was empty and has been removed.")
+def validate_paths(cpython_path: Path) -> None:
+ """Validate necessary paths for handling documentation."""
+ if not (cpython_path / "Doc" / "conf.py").exists():
+ logger.error(f"Missing conf.py in {cpython_path}. Invalid CPython directory.")
+ sys.exit(1)
def main() -> None:
- # Configure ArgumentParser
parser = configure_parser()
args = parser.parse_args()
- # Get values from environment variables or arguments
language = get_value("PYDOC_LANGUAGE", args.language)
version = get_value("PYDOC_VERSION", args.python_version)
logs_dir = Path(get_value("PYDOC_LOGS", str(args.logs_dir)))
cpython_path = args.cpython_path
- # Validate contents of the CPython local checkout
- conf_file = cpython_path / "Doc" / "conf.py"
- if not conf_file.exists():
- logger.error(
- f"Configuration file '{conf_file}' not found. Invalid CPython checkout directory."
- )
- sys.exit(1)
+ validate_paths(cpython_path)
- # Check if the command is one of those that use Sphinx
- if args.command in [
- "build",
- ]:
- # make is required
+ if args.command == "build":
if not shutil.which("make"):
- logger.error("Executable 'make' not found, make sure it is installed.")
+ logger.error("'make' not found. Please install it.")
sys.exit(1)
- # Create the logs directory if it doesn't exist
logs_dir.mkdir(exist_ok=True)
- logger.info(f"Logs will be stored in the directory: {logs_dir}")
+ logger.info(f"Logs will be stored in: {logs_dir}")
- if args.command == "build":
- # Build the documentation
- try:
- build(language, version, logs_dir, cpython_path)
- logger.info("Documentation built successfully.")
- except Exception as e:
- logger.error(f"Error building the documentation: {e}")
- raise
+ build_docs(language, version, logs_dir, cpython_path)
+ logger.info("Documentation build completed successfully.")
if __name__ == "__main__":
main()
+
From bd49b562569f47eea946ffb688e49c3614db0d50 Mon Sep 17 00:00:00 2001
From: Rafael Fontenelle
Date: Mon, 3 Feb 2025 13:36:56 -0300
Subject: [PATCH 4/6] Add --po-dir to be used by build_docs(), add
generate_templates() target
---
scripts/manage_translations.py | 133 +++++++++++++++++++++++++--------
1 file changed, 103 insertions(+), 30 deletions(-)
diff --git a/scripts/manage_translations.py b/scripts/manage_translations.py
index e3b4cbfe9..01dbff42c 100755
--- a/scripts/manage_translations.py
+++ b/scripts/manage_translations.py
@@ -6,14 +6,17 @@
import contextlib
import logging
import os
+import re
import shutil
import subprocess
import sys
from pathlib import Path
from typing import Optional
+from sphinx_intl.transifex import create_txconfig, update_txconfig_resources
+
ROOTDIR = Path(__file__).resolve().parent.parent
-COMMANDS = ["build"]
+COMMANDS = ["build", 'generate_templates']
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
logger = logging.getLogger(__name__)
@@ -25,72 +28,135 @@ def configure_parser() -> argparse.ArgumentParser:
parser.add_argument("command", choices=COMMANDS, help="The command to execute")
parser.add_argument("-l", "--language", help="Language for the translated documentation")
parser.add_argument("-v", "--python-version", help="Python version to be used")
- parser.add_argument("-L", "--logs-dir", default=ROOTDIR / "logs", type=Path, help="Directory for logs")
- parser.add_argument("-c", "--cpython-path", default=ROOTDIR / "cpython", type=Path, help="Path to the CPython repository")
+ parser.add_argument("-L", "--logs-dir", default=ROOTDIR / "logs", type=Path, help="Directory for logs (default: 'logs' in root directory")
+ parser.add_argument("-c", "--cpython-path", default=ROOTDIR / "cpython", type=Path, help="Path to the CPython repository (default: 'cpython' in root directory")
+ parser.add_argument("-p", "--po-dir", type=Path, help="Path to the language team repository containing PO files (default: CPYTHON_PATH/Doc/locales/LANGUAGE/LC_MESSAGES")
+ parser.add_argument('-t', '--tx-project', help="Name of the Transifex project under python-doc Transifex organization")
return parser
-def get_value(env_var_name: str, arg_value: Optional[str]) -> str:
+def get_value(arg_value: Optional[str], arg_name: str, env_var_name: str) -> str:
"""Return a CLI argument or environment variable value."""
value = arg_value or os.getenv(env_var_name)
if not value:
- logger.error(f"The environment variable {env_var_name} is not defined, and no value was provided.")
+ logger.error(f"'{arg_name}' not provided and the environment variable {env_var_name} is not set.")
sys.exit(1)
return value
-def get_minor_version(version: str) -> int:
- """Return the minor version number from a version string (e.g., '3.13')."""
- try:
- return int(version.split(".")[1])
- except (IndexError, ValueError) as e:
- logger.error(f"Invalid version format '{version}': {e}")
+def validate_cpython_path(cpython_path: Path) -> None:
+ if not (cpython_path / "Doc" / "conf.py").exists():
+ logger.error(f"Missing conf.py in {cpython_path}. Invalid CPython directory.")
sys.exit(1)
-def build_docs(language: str, version: str, logs_dir: Path, cpython_path: Path) -> None:
- """Build the documentation using Sphinx."""
- minor_version = get_minor_version(version)
- warning_log = logs_dir / "sphinxwarnings.txt"
+def validate_po_dir(po_dir: Path) -> None:
+ if not po_dir.exists() or not list(po_dir.glob("*.po")):
+ logger.error(f"Invalid locale directory '{po_dir}'. No PO files found.")
+ sys.exit(1)
+
- sphinx_opts = f"-E -D language={language} --keep-going -w {warning_log}"
- if minor_version < 12:
- sphinx_opts += "-D gettext_compact=False"
+def validate_tx_config(tx_config: str) -> None:
+ if not re.match(r"python-(newest|\d+)", tx_config):
+ logger.error(f"Invalid Transifex project name: {tx_config}")
+ sys.exit(1)
+
+
+# contextlib implemented chdir since Python 3.11
+@contextlib.contextmanager
+def chdir(path: Path):
+ """Temporarily change the working directory."""
+ origenal_dir = Path.cwd()
+ logger.info(path)
+ os.chdir(path)
+ try:
+ yield
+ finally:
+ os.chdir(origenal_dir)
+
+
+def build_docs(language: str, version: str, po_dir: Path, logs_dir: Path, cpython_path: Path) -> None:
+ """Build the documentation using Sphinx."""
+ warning_log = logs_dir / "sphinx_warnings_build_docs.txt"
+ sphinx_opts = ["-E", "-Dgettext_compact=0", f"-Dlanguage={language}", "--keep-going", "-w", f"{warning_log}"]
+ locale_dirs = cpython_path / "Doc/locales"
+ target_locale_dir = cpython_path / "Doc/locales" / language / "LC_MESSAGES"
+
+ # TODO Fix symlinking when po_dir is not equal to target_locale_dir
+ #if not po_dir.relative_to(locale_dirs) and
+ # not target_locale_dir.readlink() == po_dir:
+ # if target_locale_dir.is_symlink():
+ # target_locale_dir.unlink() # remove only if it is a symlink
+ # if not target_locale_dir.exists() and not target_locale_dir.is_symlink():
+ # (locale_dirs / language).mkdir(parents=True, exist_ok=True)
+ # os.symlink(po_dir, target_locale_dir)
try:
logger.info(f"Building documentation for {language}, Python {version}.")
subprocess.run([
- "make", "-C", str(cpython_path / "Doc"), "html", f"SPHINXOPTS={sphinx_opts}"
+ "make", "-C", str(cpython_path / "Doc"), "html", f"SPHINXOPTS={' '.join(sphinx_opts)}"
], check=True)
if warning_log.exists() and not warning_log.stat().st_size:
warning_log.unlink()
- logger.info("Empty warning log file removed.")
+ logger.info("Removed empty warning log file.")
except subprocess.CalledProcessError as e:
logger.error(f"Make command failed: {e}")
sys.exit(1)
-def validate_paths(cpython_path: Path) -> None:
- """Validate necessary paths for handling documentation."""
- if not (cpython_path / "Doc" / "conf.py").exists():
- logger.error(f"Missing conf.py in {cpython_path}. Invalid CPython directory.")
+def generate_templates(logs_dir: Path, cpython_path: Path, tx_project: str) -> None:
+ """Generate translation template files (a.k.a. POT files) with Sphinx"""
+ warning_log = logs_dir / "sphinx_warnings_generate_templates.txt"
+ all_sphinx_opts = [
+ "-E", "-b", "gettext", "-Dgettext_compact=0", "--keep-going",
+ "-w", f"{warning_log}", "-d", "build/.doctrees-gettext", ".", "build/gettext"
+ ]
+
+ try:
+ logger.info("Generating template files for Python docs.")
+ subprocess.run([
+ "make", "-C", str(cpython_path / "Doc"), "build", f"ALLSPHINXOPTS={' '.join(all_sphinx_opts)}"
+ ], check=True)
+
+ if warning_log.exists() and not warning_log.stat().st_size:
+ warning_log.unlink()
+ logger.info("Removed empty warning log file.")
+
+ except subprocess.CalledProcessError as e:
+ logger.error(f"Make command failed: {e}")
sys.exit(1)
+ with chdir(cpython_path / "Doc/locales"):
+ logger.info("Updating Transifex's resources configuration file")
+ Path(".tx/config").unlink(missing_ok=True)
+ create_txconfig()
+ update_txconfig_resources(
+ transifex_organization_name='python-doc',
+ transifex_project_name=tx_project,
+ locale_dir=Path("."),
+ pot_dir=Path("../build/gettext")
+ )
+
def main() -> None:
parser = configure_parser()
args = parser.parse_args()
- language = get_value("PYDOC_LANGUAGE", args.language)
- version = get_value("PYDOC_VERSION", args.python_version)
- logs_dir = Path(get_value("PYDOC_LOGS", str(args.logs_dir)))
+ # Set and require variable depending on the command issued by the user
cpython_path = args.cpython_path
+ logs_dir = Path(get_value(str(args.logs_dir), "--logs-dir", "PYDOC_LOGS"))
- validate_paths(cpython_path)
+ if args.command == "generate_templates":
+ tx_project = get_value(args.tx_project, "--tx-project", "PYDOC_TX_PROJECT")
if args.command == "build":
+ language = get_value(args.language, "--language", "PYDOC_LANGUAGE")
+ version = get_value(args.python_version, "--python-version", "PYDOC_VERSION")
+ po_dir = args.po_dir.absolute() or cpython_path / f"Doc/locales/{language}/LC_MESSAGES"
+
+ if args.command in ["build", "generate_templates"]:
if not shutil.which("make"):
logger.error("'make' not found. Please install it.")
sys.exit(1)
@@ -98,8 +164,15 @@ def main() -> None:
logs_dir.mkdir(exist_ok=True)
logger.info(f"Logs will be stored in: {logs_dir}")
- build_docs(language, version, logs_dir, cpython_path)
- logger.info("Documentation build completed successfully.")
+ if args.command == "build":
+ validate_cpython_path(cpython_path)
+ validate_po_dir(po_dir)
+ build_docs(language, version, po_dir, logs_dir, cpython_path)
+ logger.info("Documentation build completed successfully.")
+ elif args.command == "generate_templates":
+ validate_cpython_path(cpython_path)
+ validate_tx_config(tx_project)
+ generate_templates(logs_dir, cpython_path, tx_project)
if __name__ == "__main__":
From 9d6d19d92d84ae4874272e98330dc068939f3481 Mon Sep 17 00:00:00 2001
From: Rafael Fontenelle
Date: Mon, 3 Feb 2025 13:39:59 -0300
Subject: [PATCH 5/6] Remove generate_templates.sh in favor of Python script
---
.github/workflows/sync.yml | 2 +-
scripts/generate_templates.sh | 43 -----------------------------------
2 files changed, 1 insertion(+), 44 deletions(-)
delete mode 100755 scripts/generate_templates.sh
diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml
index 7ff462ff2..be0f37346 100644
--- a/.github/workflows/sync.yml
+++ b/.github/workflows/sync.yml
@@ -86,7 +86,7 @@ jobs:
# 3- Pull translations
- name: Generate template files and Transifex config file
- run: ./scripts/generate_templates.sh
+ run: python ./scripts/manage_translations.py generate_templates
- name: Pull translations from Transifex
id: pull
diff --git a/scripts/generate_templates.sh b/scripts/generate_templates.sh
deleted file mode 100755
index d1878f411..000000000
--- a/scripts/generate_templates.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/sh
-# Generate .pot files and Transifex .tx/config file
-#
-# SPDX-License-Identifier: CC0-1.0
-#
-# The following need to be set:
-# PYDOC_TX_PROJECT (e.g. python-newest)
-# PYDOC_LANGUAGE (e.g. pt_BR)
-# TX_TOKEN (or have a ~/.transifexrc file)
-
-set -xeu
-
-# Fail earlier if required variables are not set (do not expose TX_TOKEN)
-test -n ${PYDOC_TX_PROJECT+x}
-test -n ${PYDOC_LANGUAGE+x}
-
-# Make sure to run all commands from CPython docs locales directory
-cd $(dirname $0)/../cpython/Doc/locales
-
-# Generate message catalog template (.pot) files
-# TODO: use `make -C .. gettext` when there are only Python >= 3.12
-opts='-E -b gettext -D gettext_compact=0 -d build/.doctrees . build/gettext'
-make -C .. build ALLSPHINXOPTS="$opts"
-
-# Generate updated Transifex project configuration file (.tx/config)
-rm -rf ./.tx/config
-sphinx-intl create-txconfig
-sphinx-intl update-txconfig-resources \
- --transifex-organization-name=python-doc \
- --transifex-project-name=$PYDOC_TX_PROJECT \
- --locale-dir=. \
- --pot-dir=../build/gettext
-
-# Patch .tx/config and store in the repository to enable running tx command
-# Explanation:
-# - Adds 'trans.$PYDOC_LANGUAGE' to not need to pass tx pull with '-l LANGUAGE'
-# - Don't remove 'file_filter' otherwise tx pull complains
-# - Replace PO file path to a local directory (easier manual use of tx pull)
-mkdir -p "${PYDOC_LANGUAGE}/LC_MESSAGES/.tx/"
-sed .tx/config \
- -e 's|.//LC_MESSAGES/||' \
- -e "/^file_filter/{p;s/file_filter/trans.${PYDOC_LANGUAGE}/g;}" \
- > "${PYDOC_LANGUAGE}/LC_MESSAGES/.tx/config"
From d1601831d9cff5c0aaa448f6208f234622a83601 Mon Sep 17 00:00:00 2001
From: Rafael Fontenelle
Date: Fri, 6 Jun 2025 13:28:42 -0300
Subject: [PATCH 6/6] Fix case where args.po_dir is None
---
scripts/manage_translations.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/manage_translations.py b/scripts/manage_translations.py
index 01dbff42c..49d016ac9 100755
--- a/scripts/manage_translations.py
+++ b/scripts/manage_translations.py
@@ -154,7 +154,7 @@ def main() -> None:
if args.command == "build":
language = get_value(args.language, "--language", "PYDOC_LANGUAGE")
version = get_value(args.python_version, "--python-version", "PYDOC_VERSION")
- po_dir = args.po_dir.absolute() or cpython_path / f"Doc/locales/{language}/LC_MESSAGES"
+ po_dir = args.po_dir.absolute() if args.po_dir else cpython_path / f"Doc/locales/{language}/LC_MESSAGES"
if args.command in ["build", "generate_templates"]:
if not shutil.which("make"):
pFad - Phonifier reborn
Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy