|
From: Günter M. <mi...@us...> - 2026-09-02 15:48:12
|
- **status**: open --> open-fixed - **Comment**: The issue should be fixed in [r10398]. Thank you for the report. --- **[bugs:#522] \`languages.get\_language\(\)\` unsafe fallback import lets PyPI package shadow language module \(e.g. \`id\`\)** **Status:** open-fixed **Created:** Mon Aug 31, 2026 03:59 PM UTC by Bart van der Braak **Last Updated:** Mon Aug 31, 2026 04:00 PM UTC **Owner:** nobody I'm DevOps Engineer at Blender and we noticed an issue popping up while building our the Indonesian language version of our documentation after updating one of our dependencies: ``` [32mpipenv run sphinx-build -b html -j 12 -D language=id ./manual /home/blender/git/blender-manual-v450/build/html/id[0m Courtesy Notice: Pipenv found itself running within a virtual environment, so it will automatically use that environment, instead of creating its own for any project. You can set PIPENV_IGNORE_VIRTUALENVS=1 to force pipenv to ignore that environment and create its own instead. You can set PIPENV_VERBOSITY=-1 to suppress this warning. Running Sphinx v7.4.7 loading translations [id]... done making output directory... done loading intersphinx inventory 'blender_api' from https://docs.blender.org/api/4.5/objects.inv... building [mo]: targets for 0 po files that are out of date writing output... building [html]: targets for 2072 source files that are out of date updating environment: [new config] 2072 added, 0 changed, 0 removed Sphinx parallel build error: AttributeError: module 'id' has no attribute 'bibliographic_fields' ``` Source: https://builder.staging.blender.org/admin/#/builders/16/builds/4 It looks like `docutils.languages.get_language()` falls back to a bare `import <language_code>` when no `docutils.languages.<code>` module exists. If a PyPI package happens to share the name of a language code (e.g. `id`, the PEP 740 attestations package used by `twine`), that package gets imported instead, breaking language support with no clear error. ### Reproduce I crafted the following A/B scenario: #### A: clean venv, no `id` package ```bash [bart@ws-bart:/tmp]$ python3 -m venv /tmp/env_clean [bart@ws-bart:/tmp]$ /tmp/env_clean/bin/pip install -q docutils [notice] A new release of pip is available: 26.1.2 -> 26.2.1 [notice] To update, run: /tmp/env_clean/bin/python3 -m pip install --upgrade pip [bart@ws-bart:/tmp]$ /tmp/env_clean/bin/python -c " from docutils.languages import get_language mod = get_language('id') print(mod) print(hasattr(mod, 'bibliographic_fields')) " <module 'docutils.languages.en' from '/tmp/env_clean/lib/python3.14/site-packages/docutils/languages/en.py'> True ``` #### B: venv with `id` pypi package installed ```bash [bart@ws-bart:/tmp]$ # --- B: venv with `id` pypi package installed --- [bart@ws-bart:/tmp]$ python3 -m venv /tmp/env_poisoned [bart@ws-bart:/tmp]$ /tmp/env_poisoned/bin/pip install -q docutils id [notice] A new release of pip is available: 26.1.2 -> 26.2.1 [notice] To update, run: /tmp/env_poisoned/bin/python3 -m pip install --upgrade pip [bart@ws-bart:/tmp]$ /tmp/env_poisoned/bin/python -c " from docutils.languages import get_language mod = get_language('id') print(mod) print(hasattr(mod, 'bibliographic_fields')) " <module 'id' from '/tmp/env_poisoned/lib/python3.14/site-packages/id/__init__.py'> False ``` ### Versions used ``` docutils 0.21.2, Python 3.12 ``` --- Sent from sourceforge.net because doc...@li... is subscribed to https://sourceforge.net/p/docutils/bugs/ To unsubscribe from further messages, a project admin can change settings at https://sourceforge.net/p/docutils/admin/bugs/options. Or, if this is a mailing list, you can unsubscribe from the mailing list. |