diff --git a/.babel.cfg b/.babel.cfg new file mode 100644 index 00000000..cc4c9de0 --- /dev/null +++ b/.babel.cfg @@ -0,0 +1,3 @@ +[javascript: **.js] + +[jinja2: **.html] diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 2bcd70e3..00000000 --- a/.flake8 +++ /dev/null @@ -1,2 +0,0 @@ -[flake8] -max-line-length = 88 diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 8452ef07..5621e4b7 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -10,3 +10,5 @@ updates: actions: patterns: - "*" + cooldown: + default-days: 7 diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 00000000..5f89818f --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,5 @@ +changelog: + exclude: + authors: + - dependabot[bot] + - pre-commit-ci[bot] diff --git a/.github/workflows/documentation-links.yml b/.github/workflows/documentation-links.yml index f05df37b..a4de7dcd 100644 --- a/.github/workflows/documentation-links.yml +++ b/.github/workflows/documentation-links.yml @@ -6,9 +6,6 @@ on: pull_request_target: types: - opened - paths: - - 'Doc/**' - - '.github/workflows/doc.yml' permissions: pull-requests: write diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 88c0c7cb..3a2f8524 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -2,19 +2,21 @@ name: Lint on: [push, pull_request, workflow_dispatch] +permissions: {} + env: FORCE_COLOR: 1 - -permissions: - contents: read + RUFF_OUTPUT_FORMAT: github jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: actions/setup-python@v6 with: python-version: "3.x" - uses: pre-commit/action@v3.0.1 diff --git a/.github/workflows/pypi-package.yml b/.github/workflows/pypi-package.yml index c7acc055..885c30bb 100644 --- a/.github/workflows/pypi-package.yml +++ b/.github/workflows/pypi-package.yml @@ -8,8 +8,10 @@ on: - published workflow_dispatch: -permissions: - contents: read +permissions: {} + +env: + FORCE_COLOR: 1 jobs: # Always build & lint package. @@ -18,7 +20,16 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: actions/setup-python@v6 + + - name: Compile translations + run: | + pip install --upgrade pip + pip install -r requirements.txt + python babel_runner.py compile - uses: hynek/build-and-inspect-python-package@v2 @@ -38,7 +49,7 @@ jobs: steps: - name: Download packages built by build-and-inspect-python-package - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v6 with: name: Packages path: dist diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1b58d3ed..7b9875e2 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -2,6 +2,8 @@ name: Tests on: [push, pull_request, workflow_dispatch] +permissions: {} + env: FORCE_COLOR: 1 @@ -12,12 +14,17 @@ jobs: strategy: fail-fast: false matrix: - branch: ["origin/main", "3.12", "3.11", "3.10"] + python-version: ["3.15", "3.14", "3.13", "3.12"] + include: + - python-version: "3.15" + branch: "main" steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: actions/setup-python@v6 with: - python-version: 3 + python-version: ${{ matrix.python-version }} allow-prereleases: true cache: pip - name: Clone docsbuild scripts @@ -34,17 +41,55 @@ jobs: --build-root ./build_root --www-root ./www --log-directory ./logs - --group $(id -g) + --group "$(id -g)" --skip-cache-invalidation - --theme $(pwd) - --language en - --branch ${{ matrix.branch }} + --theme "$(pwd)" + --languages en + --branches ${{ matrix.branch || matrix.python-version }} + ${{ matrix.branch == 'main' && '--select-output no-html' || '' }} - name: Show logs if: failure() run: | cat ./logs/docsbuild.log - name: Upload - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: - name: doc-html-${{ matrix.branch }} + name: doc-html-${{ matrix.python-version }} path: www/ + + translations: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: ["ubuntu-latest", "windows-latest"] + # Test minimum supported and latest stable from 3.x series + python-version: ["3.12", "3"] + steps: + - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: actions/setup-python@v6 + with: + python-version: ${{ matrix.python-version }} + allow-prereleases: true + cache: pip + - name: Install dependencies + run: | + pip install --upgrade pip + pip install -r requirements.txt + - name: Remove locale file for testing + shell: bash + run: rm -rf python_docs_theme/locale/pt_BR/ + - run: python babel_runner.py extract + - run: python babel_runner.py init -l pt_BR + - run: python babel_runner.py update + - run: python babel_runner.py update -l pt_BR + - run: python babel_runner.py compile + - run: python babel_runner.py compile -l pt_BR + - name: Print .pot file + shell: bash + run: cat python_docs_theme/locale/python-docs-theme.pot + - name: Print .po file + shell: bash + run: cat python_docs_theme/locale/pt_BR/LC_MESSAGES/python-docs-theme.po diff --git a/.github/zizmor.yml b/.github/zizmor.yml new file mode 100644 index 00000000..9b42b47c --- /dev/null +++ b/.github/zizmor.yml @@ -0,0 +1,10 @@ +# Configuration for the zizmor static analysis tool, run via pre-commit in CI +# https://woodruffw.github.io/zizmor/configuration/ +rules: + dangerous-triggers: + ignore: + - documentation-links.yml + unpinned-uses: + config: + policies: + "*": ref-pin diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 70b4e19a..af1d14d3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,34 +1,17 @@ repos: - - repo: https://github.com/asottile/pyupgrade - rev: v3.15.0 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.9.3 hooks: - - id: pyupgrade - args: [--py38-plus] + - id: ruff + args: [--exit-non-zero-on-fix] - repo: https://github.com/psf/black-pre-commit-mirror - rev: 24.1.1 + rev: 24.10.0 hooks: - id: black - - repo: https://github.com/PyCQA/isort - rev: 5.13.2 - hooks: - - id: isort - - - repo: https://github.com/PyCQA/flake8 - rev: 7.0.0 - hooks: - - id: flake8 - additional_dependencies: - [flake8-2020, flake8-implicit-str-concat, flake8-logging] - - - repo: https://github.com/pre-commit/pygrep-hooks - rev: v1.10.0 - hooks: - - id: python-check-blanket-noqa - - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v5.0.0 hooks: - id: check-case-conflict - id: check-merge-conflict @@ -38,14 +21,29 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace + - repo: https://github.com/python-jsonschema/check-jsonschema + rev: 0.31.0 + hooks: + - id: check-dependabot + - id: check-github-workflows + + - repo: https://github.com/rhysd/actionlint + rev: v1.7.7 + hooks: + - id: actionlint + + - repo: https://github.com/woodruffw/zizmor-pre-commit + rev: v1.17.0 + hooks: + - id: zizmor + - repo: https://github.com/tox-dev/pyproject-fmt - rev: 1.7.0 + rev: v2.5.0 hooks: - id: pyproject-fmt - args: [--max-supported-python=3.13] - repo: https://github.com/abravalheri/validate-pyproject - rev: v0.16 + rev: v0.23 hooks: - id: validate-pyproject diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..069a1149 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,250 @@ +# Changelog + +## [2025.12](https://github.com/python/python-docs-theme/releases/tag/2025.12) + +* Add support for green, red and yellow side borders for code examples by @hugovk in https://github.com/python/python-docs-theme/pull/285 +* Add Portuguese translation by @NyaPuma in https://github.com/python/python-docs-theme/pull/281 +* Add support for Python 3.15 by @hugovk in https://github.com/python/python-docs-theme/pull/282 +* Convert CHANGELOG and CONTRIBUTING from .rst to .md by @hugovk in https://github.com/python/python-docs-theme/pull/277 +* Add zizmor to CI and fix findings by @hugovk in https://github.com/python/python-docs-theme/pull/283 + +## [2025.10](https://github.com/python/python-docs-theme/releases/tag/2025.10) + +* Add Romanian translation by @octaG-M in https://github.com/python/python-docs-theme/pull/272 +* Add Arabic and Russian translations by @StanFromIreland in https://github.com/python/python-docs-theme/pull/274 +* Add French translation by @JulienPalard in https://github.com/python/python-docs-theme/pull/275 +* Update authors in `pyproject.toml` by @StanFromIreland in https://github.com/python/python-docs-theme/pull/271 +* Add link to devguide in README by @StanFromIreland in https://github.com/python/python-docs-theme/pull/266 + +## [2025.9.2](https://github.com/python/python-docs-theme/releases/tag/2025.9.2) + +* Add Korean and Indonesian translations from Transifex in https://github.com/python/python-docs-theme/pull/264 +* Add German translation by @cmaureir in https://github.com/python/python-docs-theme/pull/262 +* Fix compilation of translations and loading of translations on pages with html + source in https://github.com/python/python-docs-theme/pull/263 +* Fix search button cutting off long translations in https://github.com/python/python-docs-theme/pull/268 +* Fix `Copy` button copying line numbers by @StanFromIreland in https://github.com/python/python-docs-theme/pull/270 + +## [2025.9.1](https://github.com/python/python-docs-theme/releases/tag/2025.9.1) + +* Add Japanese, Turkish and Spanish translations from Transifex in https://github.com/python/python-docs-theme/pull/259 + +## [2025.9](https://github.com/python/python-docs-theme/releases/tag/2025.9) + +* Enable theme translation and add Polish by @StanFromIreland in https://github.com/python/python-docs-theme/pull/246 +* Add Greek translation by @lysnikolaou and @skpanagiotis in https://github.com/python/python-docs-theme/pull/256 and https://github.com/python/python-docs-theme/pull/257 +* Add Swedish translation by @yeager in https://github.com/python/python-docs-theme/pull/250 +* Add Brazilian Portuguese, Simplified Chinese and Traditional Chinese translations from [Transifex](https://explore.transifex.com/python-doc/python-docs-theme/) in https://github.com/python/python-docs-theme/pull/253 + +## [2025.5](https://github.com/python/python-docs-theme/releases/tag/2025.5) + +* Make the copy button only appear when hovered over or clicked on by @kevteg in https://github.com/python/python-docs-theme/pull/243 + +## [2025.4.1](https://github.com/python/python-docs-theme/releases/tag/2025.4.1) + +* Fix copy button with multiple tracebacks by @tomasr8 in https://github.com/python/python-docs-theme/pull/240 + +## [2025.4](https://github.com/python/python-docs-theme/releases/tag/2025.4) + +* Require Sphinx 7.3 by @AA-Turner in https://github.com/python/python-docs-theme/pull/221 +* Add support for Python 3.14 by @hugovk https://github.com/python/python-docs-theme/pull/236 +* Drop support for Python 3.10 and 3.11 by @hugovk in https://github.com/python/python-docs-theme/pull/234 +* Add a copy button to code samples by @tomasr8 in https://github.com/python/python-docs-theme/pull/231 +* Add missing i18n for copy button titles by @tomasr8 in https://github.com/python/python-docs-theme/pull/225 +* Use consistent line-height for light & dark theme by @tomasr8 in https://github.com/python/python-docs-theme/pull/227 +* Remove self-closing tags by @hugovk in https://github.com/python/python-docs-theme/pull/226 +* Replace deprecated classifier with licence expression (PEP 639) by @hugovk in https://github.com/python/python-docs-theme/pull/237 + +## [2025.2](https://github.com/python/python-docs-theme/releases/tag/2025.2) + +- Note minimum requirements for Sphinx (#216) + Contributed by Adam Turner +- Horizontally centre the sidebar collapse button (#219) + Contributed by Tomas Roun +- Make sidebar width more flexible (#218) + Contributed by Tomas Roun +- Set `__version__` in the runtime package (#222) + Contributed by Adam Turner + +## [2024.12](https://github.com/python/python-docs-theme/releases/tag/2024.12) + +- Hide header and search bar when printing (#204) + Contributed by Hugo van Kemenade + +## [2024.10](https://github.com/python/python-docs-theme/releases/tag/2024.10) + +- Add support for Python 3.13 (#196) + Contributed by Hugo van Kemenade +- Drop support for Python 3.8 (#197) + Contributed by Hugo van Kemenade +- Add script for handling translations (#195) + Contributed by Rafael Fontenelle +- Generate digital attestations for PyPI (PEP 740) (#198) + Contributed by Hugo van Kemenade + +## [2024.6](https://github.com/python/python-docs-theme/releases/tag/2024.6) + +- Add backgrounds and borders to admonitions (#190) + Contributed by Hugo van Kemenade +- Use different colour for 'Return value: Borrowed reference' (#188) + Contributed by Hugo van Kemenade + +## [2024.4](https://github.com/python/python-docs-theme/releases/tag/2024.4) + +- Add colour to version change directives (#185) + Contributed by Hugo van Kemenade +- Only show 'Last updated on ...' when `last_updated` defined (#183) + Contributed by Hugo van Kemenade +- Use system font stack for all code (#186) + Contributed by Hugo van Kemenade + +## [2024.3](https://github.com/python/python-docs-theme/releases/tag/2024.3) + +- Modernise font: use system font stack to improve text readability and webpage performance (#174) + Contributed by Hugo van Kemenade +- Remove incorrect CSS property (#178) + Contributed by Kerim Kabirov + +## [2024.2](https://github.com/python/python-docs-theme/releases/tag/2024.2) + +- Do not underline navigation links (#169) + Contributed by Hugo van Kemenade +- Only apply underline offset to code formatting for underline visibility (#171) + Contributed by Hugo van Kemenade + +## [2024.1](https://github.com/python/python-docs-theme/releases/tag/2024.1) + +- Underline links for readability and a11y (#160, #166) + Contributed by Hugo van Kemenade +- Add `hosted_on` variable for a link in the footer (#165) + Contributed by Hugo van Kemenade +- Consistently reference `theme_root_icon` (#163) + Contributed by Marko Budiselic +- Dark mode: fix contrast of footer highlight (#162) + Contributed by Hugo van Kemenade + +## [2023.9](https://github.com/python/python-docs-theme/releases/tag/2023.9) + +- Focus search box when pressing slash (#153) + Contributed by Hugo van Kemenade + +## [2023.8](https://github.com/python/python-docs-theme/releases/tag/2023.8) + +- Add Python 3.12 and 3.13 classifiers (#147) + Contributed by Hugo van Kemenade +- Dark mode: Also give aside.topic a dark background (#150) + Contributed by Hugo van Kemenade +- Restore the menu on mobile devices (inadvertently broken in 2023.7) (#146) + Contributed by Hugo van Kemenade + +## [2023.7](https://github.com/python/python-docs-theme/releases/tag/2023.7) + +- Fix compatibility with Sphinx 7.1 (#137) + Contributed by Pradyun Gedam +- Enable the slash keypress to focus the search field (#141) + Contributed by Mike Fiedler +- Sphinx 6.2 fix: add `nav.contents` where `div.topic` is used (#138) + Contributed by Hugo van Kemenade +- Dark mode: fix contrast for C++ specific styling (#133) + Contributed by Hugo van Kemenade +- Don't let long code literals extend beyond the right side of the screen (#139) + Contributed by Hugo van Kemenade +- Test with Python 3.12 (#140) + Contributed by Hugo van Kemenade + +## [2023.5](https://github.com/python/python-docs-theme/releases/tag/2023.5) + +- Add a dark theme. (#44) + Contributed by Nils K +- Fix: Remove searchbox id from form. (fixes #117) + Contributed by Nils K +- Update `python-docs-theme` to work with Sphinx 5 & 6. (#99 & #127) + Contributed by Adam Turner +- Override font for `.sig` for consistency with other code blocks. (#121) + Contributed by Chris Warrick +- Dark mode: add class to invert image brightness. (#128) + Contributed by Hugo van Kemenade + + +## [2023.3.1](https://github.com/python/python-docs-theme/releases/tag/2023.3.1) + +- Skip cache-busting for old Sphinx #113 + + +## [2023.3](https://github.com/python/python-docs-theme/releases/tag/2023.3) + +- Fix problem with monospace rendering in Vivaldi #104 +- Fix mobile nav obstructing content #96 +- Reduce footer margin only for desktop #106 +- Append a hash ?digest to CSS files for cache-busting #108 + + +## [2022.1](https://github.com/python/python-docs-theme/releases/tag/2022.1) + +- Add a configuration for license URL. (#90) +- Exclude the floating navbar from CHM help. (#84) +- Make sidebar scrollable and sticky (on modern browsers) (#91) + + +## [2021.11.1](https://github.com/python/python-docs-theme/releases/tag/2021.11.1) + +- Fix monospace again, on buggy Google Chrome (#87) + Contributed by Tushar Sadhwani + + +## [2021.11](https://github.com/python/python-docs-theme/releases/tag/2021.11) + +- Fix monospace on buggy Google Chrome (#85) + Contributed by Tushar Sadhwani + + +## [2021.8](https://github.com/python/python-docs-theme/releases/tag/2021.8) + +- Add the copyright_url variable in the theme (#67) + Contributed by jablonskidev +- Improve readability (#79) + Contributed by Olga Bulat +- Remove #searchbox on mobile to fix a layout bug (#76) + Contributed by Olga Bulat +- Fix the appearance of version/language selects (#74) + Contributed by Olga Bulat + + +## [2021.5](https://github.com/python/python-docs-theme/releases/tag/2021.5) + +- Make the theme responsive (#46) + Contributed by Olga Bulat. +- Use Python 3.8 for the Github Actions (#71) + Contributed by Stéphane Wirtel. +- Use default pygments theme (#68) + Contributed by Aaron Carlisle. +- Test Github action to validate the theme against docsbuild scripts. (#69) + Contributed by Julien Palard. +- Add the copy button to pycon3 highlighted code blocks. (#64) + Contributed by Julien Palard. + + +## [2020.12](https://github.com/python/python-docs-theme/releases/tag/v2020.12) + +- Updated the readme, to remind user to install the package in a virtual environment. (#41) + Contributed by Mariatta. +- Updated the package url, using the GitHub repository instead of docs.python.org (#49) + Contributed by Pradyun Gedam. +- Added license information to the footer of the doc (#36) + Contributed by Todd. +- Fixed typo in the footer (#52) + Contributed by Dominic Davis-Foster. +- Added information on how to use the package (#32) + Contributed by Tapasweni Pathak. +- Fixed code formatting (#53). + Contributed by Hugo van Kemenade. +- Fixed code bgcolor and codetextcolor for Sphinx 3.1.0+ (#57) + Contributed by Zhiming Wang. + +## 2018.7 +Corresponds to [44a8f30](https://github.com/python/python-docs-theme/commit/44a8f306db9ec86d277a8a687538d5d51e415130) + + +## [2018.2](https://github.com/python/python-docs-theme/releases/tag/2018.2) + +Initial release. diff --git a/CHANGELOG.rst b/CHANGELOG.rst deleted file mode 100644 index 07f7d4c7..00000000 --- a/CHANGELOG.rst +++ /dev/null @@ -1,170 +0,0 @@ -Changelog -========= - -`2024.3 `_ ----------------------------------------------------------------------------- - -- Modernise font: use system font stack to improve text readability and webpage performance (#174) - Contributed by Hugo van Kemenade -- Remove incorrect CSS property (#178) - Contributed by Kerim Kabirov - -`2024.2 `_ ----------------------------------------------------------------------------- - -- Do not underline navigation links (#169) - Contributed by Hugo van Kemenade -- Only apply underline offset to code formatting for underline visibility (#171) - Contributed by Hugo van Kemenade - -`2024.1 `_ ----------------------------------------------------------------------------- - -- Underline links for readability and a11y (#160, #166) - Contributed by Hugo van Kemenade -- Add ``hosted_on`` variable for a link in the footer (#165) - Contributed by Hugo van Kemenade -- Consistently reference ``theme_root_icon`` (#163) - Contributed by Marko Budiselic -- Dark mode: fix contrast of footer highlight (#162) - Contributed by Hugo van Kemenade - -`2023.9 `_ ----------------------------------------------------------------------------- - -- Focus search box when pressing slash (#153) - Contributed by Hugo van Kemenade - -`2023.8 `_ ----------------------------------------------------------------------------- - -- Add Python 3.12 and 3.13 classifiers (#147) - Contributed by Hugo van Kemenade -- Dark mode: Also give aside.topic a dark background (#150) - Contributed by Hugo van Kemenade -- Restore the menu on mobile devices (inadvertently broken in 2023.7) (#146) - Contributed by Hugo van Kemenade - -`2023.7 `_ ----------------------------------------------------------------------------- - -- Fix compatibility with Sphinx 7.1 (#137) - Contributed by Pradyun Gedam -- Enable the slash keypress to focus the search field (#141) - Contributed by Mike Fiedler -- Sphinx 6.2 fix: add ``nav.contents`` where ``div.topic`` is used (#138) - Contributed by Hugo van Kemenade -- Dark mode: fix contrast for C++ specific styling (#133) - Contributed by Hugo van Kemenade -- Don't let long code literals extend beyond the right side of the screen (#139) - Contributed by Hugo van Kemenade -- Test with Python 3.12 (#140) - Contributed by Hugo van Kemenade - -`2023.5 `_ ----------------------------------------------------------------------------- - -- Add a dark theme. (#44) - Contributed by Nils K -- Fix: Remove searchbox id from form. (fixes #117) - Contributed by Nils K -- Update ``python-docs-theme`` to work with Sphinx 5 & 6. (#99 & #127) - Contributed by Adam Turner -- Override font for ``.sig`` for consistency with other code blocks. (#121) - Contributed by Chris Warrick -- Dark mode: add class to invert image brightness. (#128) - Contributed by Hugo van Kemenade - - -`2023.3.1 `_ --------------------------------------------------------------------------------- - -- Skip cache-busting for old Sphinx #113 - - -`2023.3 `_ ----------------------------------------------------------------------------- - -- Fix problem with monospace rendering in Vivaldi #104 -- Fix mobile nav obstructing content #96 -- Reduce footer margin only for desktop #106 -- Append a hash ?digest to CSS files for cache-busting #108 - - -`2022.1 `_ ----------------------------------------------------------------------------------- - -- Add a configuration for license URL. (#90) -- Exclude the floating navbar from CHM help. (#84) -- Make sidebar scrollable and sticky (on modern browsers) (#91) - - -`2021.11.1 `_ ------------------------------------------------------------------------------------ - -- Fix monospace again, on buggy Google Chrome (#87) - Contributed by Tushar Sadhwani - - -`2021.11 `_ -------------------------------------------------------------------------------- - -- Fix monospace on buggy Google Chrome (#85) - Contributed by Tushar Sadhwani - - -`2021.8 `_ ------------------------------------------------------------------------------- - -- Add the copyright_url variable in the theme (#67) - Contributed by jablonskidev -- Improve readability (#79) - Contributed by Olga Bulat -- Remove #searchbox on mobile to fix a layout bug (#76) - Contributed by Olga Bulat -- Fix the appearance of version/language selects (#74) - Contributed by Olga Bulat - - -`2021.5 `_ ------------------------------------------------------------------------------- - -- Make the theme responsive (#46) - Contributed by Olga Bulat. -- Use Python 3.8 for the Github Actions (#71) - Contributed by Stéphane Wirtel. -- Use default pygments theme (#68) - Contributed by Aaron Carlisle. -- Test Github action to validate the theme against docsbuild scripts. (#69) - Contributed by Julien Palard. -- Add the copy button to pycon3 highlighted code blocks. (#64) - Contributed by Julien Palard. - - -`2020.12 `_ ------------------------------------------------------------------------------- - -- Updated the readme, to remind user to install the package in a virtual environment. (#41) - Contributed by Mariatta. -- Updated the package url, using the GitHub repository instead of docs.python.org (#49) - Contributed by Pradyun Gedam. -- Added license information to the footer of the doc (#36) - Contributed by Todd. -- Fixed typo in the footer (#52) - Contributed by Dominic Davis-Foster. -- Added information on how to use the package (#32) - Contributed by Tapasweni Pathak. -- Fixed code formatting (#53). - Contributed by Hugo van Kemenade. -- Fixed code bgcolor and codetextcolor for Sphinx 3.1.0+ (#57) - Contributed by Zhiming Wang. - -2018.7 ------- -Corresponds to `44a8f30 `_ - - -`2018.2 `_ ---------------------------------------------------------------------------- - -Initial release. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..f26b902a --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,26 @@ +# How to release + +- Update `CHANGELOG.md` +- Bump version (YYYY.MM) in `python_docs_theme/__init__.py` +- Commit +- Push to check tests pass on + [GitHub Actions](https://github.com/python/python-docs-theme/actions) +- Go to https://github.com/python/python-docs-theme/releases +- Click "Draft a new release" +- Click "Choose a tag" +- Type the next YYYY.MM version (no leading zero) and + select "**Create new tag: YYYY.MM** on publish" +- Leave the "Release title" blank (it will be autofilled) +- Click "Generate release notes" and amend as required +- Click "Publish release" +- Check the tagged [GitHub Actions build](https://github.com/python/python-docs-theme/actions/workflows/pypi-package.yml) + has deployed to [PyPI](https://pypi.org/project/python-docs-theme/#history) + +# Makefile usage + +This project includes a simple Makefile for syncing changes to the theme with +the main CPython repository. Run `make help` for details on available rules. + +There is one configurable variable, `CPYTHON_PATH`, which should be the path +to the CPython repository on your machine. By default, it points to +`../cpython`. diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst deleted file mode 100644 index 2533e96a..00000000 --- a/CONTRIBUTING.rst +++ /dev/null @@ -1,28 +0,0 @@ -How to release --------------- - -- Update ``CHANGELOG.rst`` -- Bump version (YYYY.MM) in ``pyproject.toml`` -- Commit -- Push to check tests pass on - `GitHub Actions `__ -- Go to https://github.com/python/python-docs-theme/releases -- Click "Draft a new release" -- Click "Choose a tag" -- Type the next YYYY.MM version (no leading zero) and - select "**Create new tag: YYYY.MM** on publish" -- Leave the "Release title" blank (it will be autofilled) -- Click "Generate release notes" and amend as required -- Click "Publish release" -- Check the tagged `GitHub Actions build `__ - has deployed to `PyPI `__ - -Makefile usage --------------- - -This project includes a simple Makefile for syncing changes to the theme with -the main CPython repository. Run ``make help`` for details on available rules. - -There is one configurable variable, ``CPYTHON_PATH``, which should be the path -to the CPython repository on your machine. By default, it points to -``../cpython``. diff --git a/Makefile b/Makefile index bae89325..dda3c238 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,7 @@ CPYTHON_PATH = ../cpython PYTHON = python3 PACKAGE_ABS_PATH = $(shell pwd)/$(shell find dist/python-docs-theme-*.tar.gz) +SPHINXOPTS = .PHONY: help @@ -22,7 +23,7 @@ venv: .PHONY: html html: venv cd $(CPYTHON_PATH)/Doc && \ - make html + make SPHINXOPTS="$(SPHINXOPTS)" html .PHONY: htmlview htmlview: html diff --git a/README.md b/README.md new file mode 100644 index 00000000..6d89793a --- /dev/null +++ b/README.md @@ -0,0 +1,40 @@ +# Python Docs Sphinx Theme + +This is the theme for the Python documentation. +It requires Python 3.12 or newer and Sphinx 7.3 or newer. + +Note that when adopting this theme, you're also borrowing an element of the +trust and credibility established by the CPython core developers over the +years. That's fine, and you're welcome to do so for other Python community +projects if you so choose, but please keep in mind that in doing so you're also +choosing to accept some of the responsibility for maintaining that collective +trust. + +To use the theme, install it into your docs build environment via `pip` +(preferably in a virtual environment). + + +## Configuration options + +To use this theme, add the following to `conf.py`: + +- `html_theme = 'python_docs_theme'` + +- `html_sidebars`, defaults taken from https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-html_sidebars + + +## Translation + +This theme supports localization. For more information see the [Python Developer's +Guide](https://devguide.python.org/documentation/translations/translating/#how-do-i-translate-the-python-docs-sphinx-theme). + + +## Preview + +See a demo of the CPython docs using this theme: + +- https://python-docs-theme-previews.readthedocs.io + +The kitchen sink is a showcase of every Sphinx feature: + +- https://sphinx-themes.org/sample-sites/python-docs-theme/kitchen-sink/ diff --git a/README.rst b/README.rst deleted file mode 100644 index 5055bad1..00000000 --- a/README.rst +++ /dev/null @@ -1,31 +0,0 @@ -Python Docs Sphinx Theme -========================= - -This is the theme for the Python documentation. - -Note that when adopting this theme, you're also borrowing an element of the -trust and credibility established by the CPython core developers over the -years. That's fine, and you're welcome to do so for other Python community -projects if you so choose, but please keep in mind that in doing so you're also -choosing to accept some of the responsibility for maintaining that collective -trust. - -To use the theme, install it into your docs build environment via ``pip`` -(preferably in a virtual environment). - - -Configuration options ---------------------- - -To use this theme, add the following to ``conf.py``: - -- ``html_theme = 'python_docs_theme'`` - -- ``html_sidebars``, defaults taken from https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-html_sidebars - -Preview -------- - -See a demo of the CPython docs using this theme: - -- https://python-docs-theme-previews.readthedocs.io diff --git a/babel_runner.py b/babel_runner.py new file mode 100755 index 00000000..677f6da2 --- /dev/null +++ b/babel_runner.py @@ -0,0 +1,139 @@ +"""Script for handling translations with Babel""" + +from __future__ import annotations + +import argparse +import ast +import subprocess +import tomllib +from pathlib import Path + +# Global variables used by pybabel below (paths relative to PROJECT_DIR) +DOMAIN = "python-docs-theme" +COPYRIGHT_HOLDER = "Python Software Foundation" +SOURCE_DIR = "python_docs_theme" +MAPPING_FILE = ".babel.cfg" + +PROJECT_DIR = Path(__file__).resolve().parent +PYPROJECT_TOML = Path(PROJECT_DIR, "pyproject.toml") +INIT_PY = PROJECT_DIR / SOURCE_DIR / "__init__.py" +LOCALES_DIR = Path(f"{SOURCE_DIR}", "locale") +POT_FILE = Path(LOCALES_DIR, f"{DOMAIN}.pot") + + +def get_project_info() -> dict: + """Retrieve project's info to populate the message catalog template""" + pyproject_text = PYPROJECT_TOML.read_text(encoding="utf-8") + project_data = tomllib.loads(pyproject_text)["project"] + + # read __version__ from __init__.py + for child in ast.parse(INIT_PY.read_bytes()).body: + if not isinstance(child, ast.Assign): + continue + target = child.targets[0] + if not isinstance(target, ast.Name) or target.id != "__version__": + continue + version_node = child.value + if not isinstance(version_node, ast.Constant): + continue + project_data["version"] = version_node.value + break + + return project_data + + +def extract_messages() -> None: + """Extract messages from all source files into message catalog template""" + Path(PROJECT_DIR, LOCALES_DIR).mkdir(parents=True, exist_ok=True) + project_data = get_project_info() + subprocess.run( + [ + "pybabel", + "extract", + "-F", + MAPPING_FILE, + "--copyright-holder", + COPYRIGHT_HOLDER, + "--project", + project_data["name"], + "--version", + project_data["version"], + "--msgid-bugs-address", + project_data["urls"]["Issue tracker"], + "-o", + POT_FILE, + SOURCE_DIR, + ], + cwd=PROJECT_DIR, + check=True, + ) + + +def init_locale(locale: str) -> None: + """Initialize a new locale based on existing message catalog template""" + pofile = PROJECT_DIR / LOCALES_DIR / locale / "LC_MESSAGES" / f"{DOMAIN}.po" + if pofile.exists(): + print(f"There is already a message catalog for locale {locale}, skipping.") + return + cmd = [ + "pybabel", + "init", + "-i", + POT_FILE, + "-d", + LOCALES_DIR, + "-D", + DOMAIN, + "-l", + locale, + ] + subprocess.run(cmd, cwd=PROJECT_DIR, check=True) + + +def update_catalogs(locale: str) -> None: + """Update translations from existing message catalogs""" + cmd = ["pybabel", "update", "-i", POT_FILE, "-d", LOCALES_DIR, "-D", DOMAIN] + if locale: + cmd.extend(["-l", locale]) + subprocess.run(cmd, cwd=PROJECT_DIR, check=True) + + +def compile_catalogs(locale: str) -> None: + """Compile existing message catalogs""" + cmd = ["pybabel", "compile", "-d", LOCALES_DIR, "-D", DOMAIN] + if locale: + cmd.extend(["-l", locale]) + subprocess.run(cmd, cwd=PROJECT_DIR, check=True) + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + "command", + choices=["extract", "init", "update", "compile"], + help="command to be executed", + ) + parser.add_argument( + "-l", + "--locale", + default="", + help="language code (needed for init, optional for update and compile)", + ) + + args = parser.parse_args() + locale = args.locale + + if args.command == "extract": + extract_messages() + elif args.command == "init": + if not locale: + parser.error("init requires passing the --locale option") + init_locale(locale) + elif args.command == "update": + update_catalogs(locale) + elif args.command == "compile": + compile_catalogs(locale) + + +if __name__ == "__main__": + main() diff --git a/code_of_conduct.rst b/code_of_conduct.rst deleted file mode 100644 index 4bc6630f..00000000 --- a/code_of_conduct.rst +++ /dev/null @@ -1,13 +0,0 @@ -Code of Conduct -=============== - -Please note that all interactions on -`Python Software Foundation `__-supported -infrastructure is `covered -`__ -by the `PSF Code of Conduct `__, -which includes all infrastructure used in the development of Python itself -(e.g. mailing lists, issue trackers, GitHub, etc.). - -In general this means everyone is expected to be open, considerate, and -respectful of others no matter what their position is within the project. diff --git a/pyproject.toml b/pyproject.toml index fc5f5513..b8598f52 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,49 +1,74 @@ [build-system] build-backend = "flit_core.buildapi" requires = [ - "flit_core>=3.7", + "flit-core>=3.7", ] [project] name = "python-docs-theme" -version = "2024.3" description = "The Sphinx theme for the CPython docs and related projects" -readme = "README.rst" -license.file = "LICENSE" -authors = [{name = "PyPA", email = "distutils-sig@python.org"}] -requires-python = ">=3.8" +readme = "README.md" +license = "PSF-2.0" +license-files = [ "LICENSE" ] +authors = [ { name = "Python Docs Sphinx Theme maintainers" } ] +requires-python = ">=3.12" classifiers = [ "Development Status :: 5 - Production/Stable", "Framework :: Sphinx :: Theme", "Intended Audience :: Developers", - "License :: OSI Approved :: Python Software Foundation License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", + "Programming Language :: Python :: 3.15", "Topic :: Documentation", "Topic :: Software Development :: Documentation", ] +dynamic = [ "version" ] + +dependencies = [ + "sphinx>=7.3", +] + urls.Code = "https://github.com/python/python-docs-theme" urls.Download = "https://pypi.org/project/python-docs-theme/" urls.Homepage = "https://github.com/python/python-docs-theme/" urls."Issue tracker" = "https://github.com/python/python-docs-theme/issues" -[project.entry-points."sphinx.html_themes"] -python_docs_theme = 'python_docs_theme' +entry-points."sphinx.html_themes".python_docs_theme = "python_docs_theme" [tool.flit.module] name = "python_docs_theme" [tool.flit.sdist] -include = [ - "python_docs_theme/", +include = [ "python_docs_theme/" ] + +[tool.ruff] +fix = true + +lint.select = [ + "C4", # flake8-comprehensions + "E", # pycodestyle errors + "F", # pyflakes errors + "I", # isort + "ISC", # flake8-implicit-str-concat + "LOG", # flake8-logging + "PGH", # pygrep-hooks + "PYI", # flake8-pyi + "RUF022", # unsorted-dunder-all + "RUF100", # unused noqa (yesqa) + "UP", # pyupgrade + "W", # pycodestyle warnings + "YTT", # flake8-2020 +] +lint.ignore = [ + "E203", # Whitespace before ':' + "E221", # Multiple spaces before operator + "E226", # Missing whitespace around arithmetic operator + "E241", # Multiple spaces after ',' ] +lint.isort.required-imports = [ "from __future__ import annotations" ] -[tool.isort] -add_imports = "from __future__ import annotations" -profile = "black" +[tool.pyproject-fmt] +max_supported_python = "3.15" diff --git a/python_docs_theme/__init__.py b/python_docs_theme/__init__.py index 77476754..a6c8f18a 100644 --- a/python_docs_theme/__init__.py +++ b/python_docs_theme/__init__.py @@ -1,64 +1,51 @@ from __future__ import annotations -import hashlib -import os -from functools import lru_cache from pathlib import Path -from typing import Any -import sphinx.application -from sphinx.builders.html import StandaloneHTMLBuilder +from sphinx.locale import get_translation -THEME_PATH = Path(__file__).parent.resolve() +TYPE_CHECKING = False +if TYPE_CHECKING: + from typing import Any + from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata -@lru_cache(maxsize=None) -def _asset_hash(path: str) -> str: - """Append a `?digest=` to an url based on the file content.""" - full_path = THEME_PATH / path.replace("_static/", "static/") - digest = hashlib.sha1(full_path.read_bytes()).hexdigest() +__version__ = "2025.12" - return f"{path}?digest={digest}" +THEME_PATH = Path(__file__).resolve().parent +LOCALE_DIR = THEME_PATH / "locale" +MESSAGE_CATALOG_NAME = "python-docs-theme" -def _add_asset_hashes(static: list[str], add_digest_to: list[str]) -> None: - for asset in add_digest_to: - index = static.index(asset) - static[index].filename = _asset_hash(asset) # type: ignore - - -def _html_page_context( - app: sphinx.application.Sphinx, +def add_translation_to_context( + app: Sphinx, pagename: str, templatename: str, context: dict[str, Any], - doctree: Any, + doctree: None, ) -> None: - if app.config.html_theme != "python_docs_theme": - return - - assert isinstance(app.builder, StandaloneHTMLBuilder) + theme_gettext = get_translation(MESSAGE_CATALOG_NAME) + sphinx_gettext = get_translation("sphinx") - if (4,) <= sphinx.version_info < (7, 1) and "css_files" in context: - if "_static/pydoctheme.css" not in context["css_files"]: - raise ValueError( - "This documentation is not using `pydoctheme.css` as the stylesheet. " - "If you have set `html_style` in your conf.py file, remove it." - ) + def combined(message: str) -> str: + translation = theme_gettext(message) + if translation == message: + return sphinx_gettext(message) + return translation - _add_asset_hashes( - context["css_files"], - ["_static/pydoctheme.css"], - ) + context["_"] = context["gettext"] = context["ngettext"] = combined -def setup(app): - current_dir = os.path.abspath(os.path.dirname(__file__)) - app.add_html_theme("python_docs_theme", current_dir) +def setup(app: Sphinx) -> ExtensionMetadata: + app.require_sphinx("7.3") - app.connect("html-page-context", _html_page_context) + app.add_html_theme("python_docs_theme", str(THEME_PATH)) + app.add_message_catalog(MESSAGE_CATALOG_NAME, LOCALE_DIR) + app.connect("html-page-context", add_translation_to_context) return { + "version": __version__, "parallel_read_safe": True, "parallel_write_safe": True, } diff --git a/python_docs_theme/footerdonate.html b/python_docs_theme/footerdonate.html index 2aef2ac2..010014d6 100644 --- a/python_docs_theme/footerdonate.html +++ b/python_docs_theme/footerdonate.html @@ -1,3 +1,3 @@ {% trans %}The Python Software Foundation is a non-profit corporation.{% endtrans %} {% trans %}Please donate.{% endtrans %} -
+
diff --git a/python_docs_theme/layout.html b/python_docs_theme/layout.html index d387ef38..1903fad4 100644 --- a/python_docs_theme/layout.html +++ b/python_docs_theme/layout.html @@ -14,7 +14,7 @@

{{ _('Navigation') }}

{%- endfor %} {%- block rootrellink %} -
  • {{ theme_root_icon_alt_text }}
  • +
  • {{ theme_root_icon_alt_text }}
  • {{theme_root_name}}{{ reldelim1 }}
  • @@ -48,8 +48,8 @@

    {{ _('Navigation') }}

    {%- if builder != "htmlhelp" %} {%- endif %} @@ -71,7 +71,7 @@

    {{ _('Navigation') }}

    {%- block extrahead -%} - + {%- if builder != "htmlhelp" %} {%- if not embedded %} @@ -93,14 +93,14 @@

    {{ _('Navigation') }}

    {%- if builder != 'htmlhelp' %}
    + aria-pressed="false" aria-expanded="false" role="button" aria-label="{{ _('Menu')}}">