Gettext internationalization broken for requirements-file options list
Description
This issue was found when I was incubating the pip-docs-l10n project.
I found that building the documentation with the gettext builder produces malformed entries for the pip-requirements-file-options-ref-list directive in docs/html/reference/requirements-file-format.md:
- A single merged
msgidthat concatenates every supported option label. - Individual entries whose source location is broken (
#: ../../\n:1) and whosemsgidstill contains raw RST:ref:markup.
Additionally, after translating the extracted entries to .po and building the translated documentation, the rendered page shows :ref: as literal text and the cross-reference links are dropped.
The directive is implemented in docs/pip_sphinxext.py (PipReqFileOptionsReference):
Expected behavior
- Each supported option is extracted as its own well-formed
.potentry with a valid#: <file>:<line>location. - The generated entry's
msgidshould use MyST syntax ({ref}`-i, --index-url <install_--index-url>`) rather than reST syntax (:ref:`-i, --index-url <install_--index-url>`). - Translated builds display the translated option labels while preserving the cross-reference links.
pip version
0ed2d3e775db5c1af01311fbb6c2c6b55b0c4d70
Python version
3.14
OS
Linux
How to Reproduce
BRANCH=main
COMMIT=0ed2d3e775db5c1af01311fbb6c2c6b55b0c4d70
# Clone the repository
git clone --branch=$BRANCH https://github.com/pypa/pip.git
cd pip
git checkout $COMMIT
# Prepare the environment and requirements
conda create --prefix ./.venv --yes
conda activate ./.venv
conda install python=3.14 pip=26 -c conda-forge -c nodefaults --yes
export PYTHONNOUSERSITE=1 LANGUAGE=en_US LANG=en_US.UTF-8
python -m pip install . --group docs
python -m pip install sphinx-intl polib
pushd docs/html
# Build .pot files with gettext builder
sphinx-build -b gettext -Dgettext_compact=0 . ../build/pot
# Print the 'reference/requirements-file-format.pot' file (Output 1)
cat ../build/pot/reference/requirements-file-format.pot
# Update .pot files to .po files with sphinx-intl
sphinx-intl update -l zh_TW -p ../build/pot
# Translate the entry
python - << 'PY'
import polib
po_path = "locales/zh_TW/LC_MESSAGES/reference/requirements-file-format.po"
msgid = ":ref:`-i, --index-url<install_--index-url>`"
msgstr = ":ref:`測試翻譯: -i, --index-url<install_--index-url>`"
po = polib.pofile(po_path)
entry = po.find(msgid)
assert entry is not None, f"entry not found: {msgid}"
entry.msgstr = msgstr
po.save(po_path)
PY
# Build the translated documentation
sphinx-build -b html -Dlanguage=zh_TW -Dgettext_compact=0 . ../build/html/zh_TW
popd
# Preview the translated documentation (Output 2)
firefox docs/build/html/zh_TW/reference/requirements-file-format.htmlOutput
When printing the generated reference/requirements-file-format.pot file, we will see the following content:
#: ../../html/reference/requirements-file-format.md:10
msgid "-i, --index-url --extra-index-url --no-index -c, --constraint -r, --requirement -e, --editable -f, --find-links --no-binary --only-binary --prefer-binary --require-hashes --pre --all-releases --only-final --trusted-host --use-feature"
msgstr ""
#: ../../html/
:1
msgid ":ref:`-i, --index-url<install_--index-url>`"
msgstr ""
#: ../../html/
:1
msgid ":ref:`--extra-index-url<install_--extra-index-url>`"
msgstr ""
#: ../../html/
:1
msgid ":ref:`--no-index<install_--no-index>`"
msgstr ""
#: ../../html/
:1
msgid ":ref:`-c, --constraint<install_--constraint>`"
msgstr ""
#: ../../html/
:1
msgid ":ref:`-r, --requirement<install_--requirement>`"
msgstr ""
#: ../../html/
:1
msgid ":ref:`-e, --editable<install_--editable>`"
msgstr ""
#: ../../html/
:1
msgid ":ref:`-f, --find-links<install_--find-links>`"
msgstr ""
#: ../../html/
:1
msgid ":ref:`--no-binary<install_--no-binary>`"
msgstr ""
#: ../../html/
:1
msgid ":ref:`--only-binary<install_--only-binary>`"
msgstr ""
#: ../../html/
:1
msgid ":ref:`--prefer-binary<install_--prefer-binary>`"
msgstr ""
#: ../../html/
:1
msgid ":ref:`--require-hashes<install_--require-hashes>`"
msgstr ""
#: ../../html/
:1
msgid ":ref:`--pre<install_--pre>`"
msgstr ""
#: ../../html/
:1
msgid ":ref:`--all-releases<install_--all-releases>`"
msgstr ""
#: ../../html/
:1
msgid ":ref:`--only-final<install_--only-final>`"
msgstr ""
#: ../../html/
:1
msgid ":ref:`--trusted-host<--trusted-host>`"
msgstr ""
#: ../../html/
:1
msgid ":ref:`--use-feature<--use-feature>`"
msgstr ""When previewing the reference/requirements-file-format.html file in the web browser, we will see the following content:
Code of Conduct
- I agree to follow the PSF Code of Conduct.
Source: pypa/pip