pax_global_header00006660000000000000000000000064147504251040014514gustar00rootroot0000000000000052 comment=24ed1541324a8d94e5113b4116943aec0ec43681 python-docs-theme-2025.2/000077500000000000000000000000001475042510400151555ustar00rootroot00000000000000python-docs-theme-2025.2/.babel.cfg000066400000000000000000000000221475042510400167530ustar00rootroot00000000000000[jinja2: **.html] python-docs-theme-2025.2/.github/000077500000000000000000000000001475042510400165155ustar00rootroot00000000000000python-docs-theme-2025.2/.github/dependabot.yml000066400000000000000000000003301475042510400213410ustar00rootroot00000000000000version: 2 updates: - package-ecosystem: "github-actions" directory: "/" schedule: interval: monthly assignees: - "ezio-melotti" groups: actions: patterns: - "*" python-docs-theme-2025.2/.github/release.yml000066400000000000000000000001141475042510400206540ustar00rootroot00000000000000changelog: exclude: authors: - dependabot - pre-commit-ci python-docs-theme-2025.2/.github/workflows/000077500000000000000000000000001475042510400205525ustar00rootroot00000000000000python-docs-theme-2025.2/.github/workflows/documentation-links.yml000066400000000000000000000010631475042510400252640ustar00rootroot00000000000000name: Read the Docs PR preview # Automatically edits a pull request's descriptions with a link # to the documentation's preview on Read the Docs. on: pull_request_target: types: - opened permissions: pull-requests: write concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true jobs: documentation-links: runs-on: ubuntu-latest steps: - uses: readthedocs/actions/preview@v1 with: project-slug: "python-docs-theme-previews" single-version: "true" python-docs-theme-2025.2/.github/workflows/lint.yml000066400000000000000000000005011475042510400222370ustar00rootroot00000000000000name: Lint on: [push, pull_request, workflow_dispatch] env: FORCE_COLOR: 1 permissions: contents: read jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.x" - uses: pre-commit/action@v3.0.1 python-docs-theme-2025.2/.github/workflows/pypi-package.yml000066400000000000000000000020571475042510400236530ustar00rootroot00000000000000name: Build & maybe upload PyPI package on: push: pull_request: release: types: - published workflow_dispatch: permissions: contents: read env: FORCE_COLOR: 1 jobs: # Always build & lint package. build-package: name: Build & verify package runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: hynek/build-and-inspect-python-package@v2 # Upload to real PyPI on GitHub Releases. release-pypi: name: Publish to PyPI environment: release-pypi # Only run for published releases. if: | github.repository_owner == 'python' && github.event.action == 'published' runs-on: ubuntu-latest needs: build-package permissions: id-token: write steps: - name: Download packages built by build-and-inspect-python-package uses: actions/download-artifact@v4 with: name: Packages path: dist - name: Upload package to PyPI uses: pypa/gh-action-pypi-publish@release/v1 with: attestations: true python-docs-theme-2025.2/.github/workflows/tests.yml000066400000000000000000000050421475042510400224400ustar00rootroot00000000000000name: Tests on: [push, pull_request, workflow_dispatch] env: FORCE_COLOR: 1 jobs: build_doc: name: Build CPython docs runs-on: ubuntu-latest strategy: fail-fast: false matrix: branch: ["origin/main", "3.13", "3.12", "3.11", "3.10"] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: 3 allow-prereleases: true cache: pip - name: Clone docsbuild scripts run: | git clone https://github.com/python/docsbuild-scripts/ - name: Set up requirements run: | python -m pip install --upgrade pip python -m pip install -r docsbuild-scripts/requirements.txt - name: Build documentation run: > python ./docsbuild-scripts/build_docs.py --quick --build-root ./build_root --www-root ./www --log-directory ./logs --group "$(id -g)" --skip-cache-invalidation --theme "$(pwd)" --language en --branch ${{ matrix.branch }} - name: Show logs if: failure() run: | cat ./logs/docsbuild.log - name: Upload uses: actions/upload-artifact@v4 with: name: doc-html-${{ matrix.branch }} 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.9", "3"] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 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 locales/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 locales/messages.pot - name: Print .po file shell: bash run: cat locales/pt_BR/LC_MESSAGES/messages.po - name: list files in locales dir shell: bash run: ls -R locales/ python-docs-theme-2025.2/.gitignore000066400000000000000000000022051475042510400171440ustar00rootroot00000000000000# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python env/ build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ *.egg-info/ .installed.cfg *.egg # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover .hypothesis/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # Jupyter Notebook .ipynb_checkpoints # pyenv .python-version # celery beat schedule file celerybeat-schedule # SageMath parsed files *.sage.py # dotenv .env # virtualenv .venv venv/ ENV/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ python-docs-theme-2025.2/.pre-commit-config.yaml000066400000000000000000000022421475042510400214360ustar00rootroot00000000000000repos: - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.9.3 hooks: - id: ruff args: [--exit-non-zero-on-fix] - repo: https://github.com/psf/black-pre-commit-mirror rev: 24.10.0 hooks: - id: black - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 hooks: - id: check-case-conflict - id: check-merge-conflict - id: check-toml - id: check-yaml - id: debug-statements - 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/tox-dev/pyproject-fmt rev: v2.5.0 hooks: - id: pyproject-fmt args: [--max-supported-python=3.13] - repo: https://github.com/abravalheri/validate-pyproject rev: v0.23 hooks: - id: validate-pyproject - repo: meta hooks: - id: check-hooks-apply - id: check-useless-excludes ci: autoupdate_schedule: quarterly python-docs-theme-2025.2/.readthedocs.yml000066400000000000000000000006221475042510400202430ustar00rootroot00000000000000# Read the Docs configuration file # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details # Project page: https://readthedocs.org/projects/python-docs-theme-previews/ version: 2 build: os: ubuntu-22.04 tools: python: "3" commands: - git clone --depth=1 https://github.com/python/cpython - make html CPYTHON_PATH=cpython - mv cpython/Doc/build _readthedocs python-docs-theme-2025.2/CHANGELOG.rst000066400000000000000000000210341475042510400171760ustar00rootroot00000000000000Changelog ========= `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 `_ ----------------------------------------------------------------------------- - Hide header and search bar when printing (#204) Contributed by Hugo van Kemenade `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 `_ --------------------------------------------------------------------------- - 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 `_ --------------------------------------------------------------------------- - 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 `_ --------------------------------------------------------------------------- - 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. python-docs-theme-2025.2/CONTRIBUTING.rst000066400000000000000000000021761475042510400176240ustar00rootroot00000000000000How to release -------------- - Update ``CHANGELOG.rst`` - Bump version (YYYY.MM) in ``python_docs_theme/__init__.py`` - 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``. python-docs-theme-2025.2/LICENSE000066400000000000000000000046341475042510400161710ustar00rootroot00000000000000PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 -------------------------------------------- 1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and the Individual or Organization ("Licensee") accessing and otherwise using this software ("Python") in source or binary form and its associated documentation. 2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Python Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared by Licensee. 3. In the event Licensee prepares a derivative work that is based on or incorporates Python or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python. 4. PSF is making Python available to Licensee on an "AS IS" basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 6. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 7. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between PSF and Licensee. This License Agreement does not grant permission to use PSF trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party. 8. By copying, installing or otherwise using Python, Licensee agrees to be bound by the terms and conditions of this License Agreement. python-docs-theme-2025.2/Makefile000066400000000000000000000015711475042510400166210ustar00rootroot00000000000000# You can set these variables from the command line. CPYTHON_PATH = ../cpython PYTHON = python3 PACKAGE_ABS_PATH = $(shell pwd)/$(shell find dist/python-docs-theme-*.tar.gz) .PHONY: help help: @echo "Please use \`make ' where is one of" @echo " venv to create a venv with necessary tools at $(CPYTHON_PATH)/Doc/venv" @echo " html to make standalone CPython HTML files" @echo " htmlview to open the index page built by the html target in your browser" .PHONY: venv venv: $(PYTHON) -m pip install build $(PYTHON) -m build cd $(CPYTHON_PATH)/Doc \ && make venv \ && ./venv/bin/pip install $(PACKAGE_ABS_PATH) .PHONY: html html: venv cd $(CPYTHON_PATH)/Doc && \ make html .PHONY: htmlview htmlview: html $(PYTHON) -c "import os, webbrowser; webbrowser.open('file://' + os.path.realpath('$(CPYTHON_PATH)/Doc/build/html/index.html'))" python-docs-theme-2025.2/README.md000066400000000000000000000021431475042510400164340ustar00rootroot00000000000000# Python Docs Sphinx Theme This is the theme for the Python documentation. It requires Python 3.9 or newer and Sphinx 3.4 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 ## 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/ python-docs-theme-2025.2/babel_runner.py000077500000000000000000000100261475042510400201670ustar00rootroot00000000000000#!/usr/bin/venv python3 """Script for handling translations with Babel""" from __future__ import annotations import argparse import ast import subprocess from pathlib import Path try: import tomllib except ImportError: try: import tomli as tomllib except ImportError as ie: raise ImportError( "tomli or tomllib is required to parse pyproject.toml" ) from ie PROJECT_DIR = Path(__file__).resolve().parent PYPROJECT_TOML = PROJECT_DIR / "pyproject.toml" INIT_PY = PROJECT_DIR / "python_docs_theme" / "__init__.py" # Global variables used by pybabel below (paths relative to PROJECT_DIR) DOMAIN = "messages" COPYRIGHT_HOLDER = "Python Software Foundation" LOCALES_DIR = "locales" POT_FILE = Path(LOCALES_DIR, f"{DOMAIN}.pot") SOURCE_DIR = "python_docs_theme" MAPPING_FILE = ".babel.cfg" 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, "-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] 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] 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() python-docs-theme-2025.2/pyproject.toml000066400000000000000000000041651475042510400200770ustar00rootroot00000000000000[build-system] build-backend = "flit_core.buildapi" requires = [ "flit-core>=3.7", ] [project] name = "python-docs-theme" description = "The Sphinx theme for the CPython docs and related projects" readme = "README.md" license.file = "LICENSE" authors = [ { name = "PyPA", email = "distutils-sig@python.org" } ] requires-python = ">=3.9" 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.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Topic :: Documentation", "Topic :: Software Development :: Documentation", ] dynamic = [ "version" ] dependencies = [ "sphinx>=3.4", ] 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" 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/" ] [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" ] python-docs-theme-2025.2/python_docs_theme/000077500000000000000000000000001475042510400206705ustar00rootroot00000000000000python-docs-theme-2025.2/python_docs_theme/__init__.py000066400000000000000000000037141475042510400230060ustar00rootroot00000000000000from __future__ import annotations import hashlib from functools import cache from pathlib import Path import sphinx.application from sphinx.builders.html import StandaloneHTMLBuilder TYPE_CHECKING = False if TYPE_CHECKING: from typing import Any from sphinx.application import Sphinx from sphinx.util.typing import ExtensionMetadata __version__ = "2025.2" THEME_PATH = Path(__file__).resolve().parent @cache 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() return f"{path}?digest={digest}" 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[attr-defined] def _html_page_context( app: sphinx.application.Sphinx, pagename: str, templatename: str, context: dict[str, Any], doctree: Any, ) -> None: if app.config.html_theme != "python_docs_theme": return assert isinstance(app.builder, StandaloneHTMLBuilder) 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." ) _add_asset_hashes( context["css_files"], ["_static/pydoctheme.css"], ) def setup(app: Sphinx) -> ExtensionMetadata: app.require_sphinx("3.4") app.add_html_theme("python_docs_theme", str(THEME_PATH)) app.connect("html-page-context", _html_page_context) return { "version": __version__, "parallel_read_safe": True, "parallel_write_safe": True, } python-docs-theme-2025.2/python_docs_theme/footerdonate.html000066400000000000000000000002701475042510400242460ustar00rootroot00000000000000{% trans %}The Python Software Foundation is a non-profit corporation.{% endtrans %} {% trans %}Please donate.{% endtrans %}
python-docs-theme-2025.2/python_docs_theme/layout.html000066400000000000000000000173231475042510400231010ustar00rootroot00000000000000{% extends "classic/layout.html" %} {%- macro relbar() %} {# modified from sphinx/themes/basic/layout.html #} {%- endmacro %} {%- macro searchbox() %} {# modified from sphinx/themes/basic/searchbox.html #} {%- if builder != "htmlhelp" %} {%- endif %} {%- endmacro %} {%- macro themeselector() %} {%- endmacro %} {% block relbar1 %} {% if builder != 'qthelp' %} {{ relbar() }} {% endif %} {% endblock %} {% block relbar2 %} {% if builder != 'qthelp' %} {{ relbar() }} {% endif %} {% endblock %} {%- block extrahead -%} {%- if builder != "htmlhelp" %} {%- if not embedded %} {%- endif -%} {%- endif -%} {{ super() }} {%- endblock -%} {%- block css -%} {{ super() }} {%- endblock -%} {%- block body_tag %} {{ super() }} {%- if builder != 'htmlhelp' %}
{% endif -%} {% endblock %} {% block footer %} {% endblock %} python-docs-theme-2025.2/python_docs_theme/static/000077500000000000000000000000001475042510400221575ustar00rootroot00000000000000python-docs-theme-2025.2/python_docs_theme/static/copybutton.js000066400000000000000000000066641475042510400247370ustar00rootroot00000000000000// ``function*`` denotes a generator in JavaScript, see // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function* function* getHideableCopyButtonElements(rootElement) { // yield all elements with the "go" (Generic.Output), // "gp" (Generic.Prompt), or "gt" (Generic.Traceback) CSS class for (const el of rootElement.querySelectorAll('.go, .gp, .gt')) { yield el } // tracebacks (.gt) contain bare text elements that need to be // wrapped in a span to hide or show the element for (let el of rootElement.querySelectorAll('.gt')) { while ((el = el.nextSibling) && el.nodeType !== Node.DOCUMENT_NODE) { // stop wrapping text nodes when we hit the next output or // prompt element if (el.nodeType === Node.ELEMENT_NODE && el.matches(".gp, .go")) { break } // if the node is a text node with content, wrap it in a // span element so that we can control visibility if (el.nodeType === Node.TEXT_NODE && el.textContent.trim()) { const wrapper = document.createElement("span") el.after(wrapper) wrapper.appendChild(el) el = wrapper } yield el } } } const loadCopyButton = () => { /* Add a [>>>] button in the top-right corner of code samples to hide * the >>> and ... prompts and the output and thus make the code * copyable. */ const hide_text = "Hide the prompts and output" const show_text = "Show the prompts and output" const button = document.createElement("span") button.classList.add("copybutton") button.innerText = ">>>" button.title = hide_text button.dataset.hidden = "false" const buttonClick = event => { // define the behavior of the button when it's clicked event.preventDefault() const buttonEl = event.currentTarget const codeEl = buttonEl.nextElementSibling if (buttonEl.dataset.hidden === "false") { // hide the code output for (const el of getHideableCopyButtonElements(codeEl)) { el.hidden = true } buttonEl.title = show_text buttonEl.dataset.hidden = "true" } else { // show the code output for (const el of getHideableCopyButtonElements(codeEl)) { el.hidden = false } buttonEl.title = hide_text buttonEl.dataset.hidden = "false" } } const highlightedElements = document.querySelectorAll( ".highlight-python .highlight," + ".highlight-python3 .highlight," + ".highlight-pycon .highlight," + ".highlight-pycon3 .highlight," + ".highlight-default .highlight" ) // create and add the button to all the code blocks that contain >>> highlightedElements.forEach(el => { el.style.position = "relative" // if we find a console prompt (.gp), prepend the (deeply cloned) button const clonedButton = button.cloneNode(true) // the onclick attribute is not cloned, set it on the new element clonedButton.onclick = buttonClick if (el.querySelector(".gp") !== null) { el.prepend(clonedButton) } }) } if (document.readyState !== "loading") { loadCopyButton() } else { document.addEventListener("DOMContentLoaded", loadCopyButton) } python-docs-theme-2025.2/python_docs_theme/static/menu.js000066400000000000000000000041311475042510400234600ustar00rootroot00000000000000document.addEventListener("DOMContentLoaded", function () { // Make tables responsive by wrapping them in a div and making them scrollable const tables = document.querySelectorAll("table.docutils") tables.forEach(function(table){ table.outerHTML = '
' + table.outerHTML + "
" }) const togglerInput = document.querySelector(".toggler__input") const togglerLabel = document.querySelector(".toggler__label") const sideMenu = document.querySelector(".menu-wrapper") const menuItems = document.querySelectorAll(".menu") const doc = document.querySelector(".document") const body = document.querySelector("body") function closeMenu() { togglerInput.checked = false sideMenu.setAttribute("aria-expanded", "false") sideMenu.setAttribute("aria-hidden", "true") togglerLabel.setAttribute("aria-pressed", "false") body.style.overflow = "visible" } function openMenu() { togglerInput.checked = true sideMenu.setAttribute("aria-expanded", "true") sideMenu.setAttribute("aria-hidden", "false") togglerLabel.setAttribute("aria-pressed", "true") body.style.overflow = "hidden" } // Close menu when link on the sideMenu is clicked sideMenu.addEventListener("click", function (event) { let target = event.target if (target.tagName.toLowerCase() !== "a") { return } closeMenu() }) // Add accessibility data when sideMenu is opened/closed togglerInput.addEventListener("change", function (_event) { togglerInput.checked ? openMenu() : closeMenu() }) // Make sideMenu links tabbable only when visible for(let menuItem of menuItems) { if(togglerInput.checked) { menuItem.setAttribute("tabindex", "0") } else { menuItem.setAttribute("tabindex", "-1") } } // Close sideMenu when document body is clicked doc.addEventListener("click", function () { if (togglerInput.checked) { closeMenu() } }) }) python-docs-theme-2025.2/python_docs_theme/static/py.png000066400000000000000000000012671475042510400233230ustar00rootroot00000000000000PNG  IHDRasRGBbKGD pHYs  tIME8!3'^7IDAT8eOHUA{߳w{"&hS6ZmB*xPMQA ")mZH FEF2y3g޼;7̜]3isޙvMU}\· x'GjN,ZXwQ1 *{ 8k9g'v;͏;j/t?|[{\ NjE%g J=M}WҎ}xv^{TnJN\}Xnܯzw/umY5;mgQ" SQ},/|i'}S@BځWk)`j'J/NK@e1MFN,j}yhbwp+щKSXb‹@:ɗ_=mU5EqR'4IN&t:c祝j.l `zF6guGfpm"J(p oٞqG0"n:",%84+!್`DoY-4ً,߳53 gob;3c]IiވC h\nf]IENDB`python-docs-theme-2025.2/python_docs_theme/static/py.svg000066400000000000000000000037711475042510400233400ustar00rootroot00000000000000 python-docs-theme-2025.2/python_docs_theme/static/pydoctheme.css000066400000000000000000000361531475042510400250420ustar00rootroot00000000000000@import url('classic.css'); /* Common colours */ :root { --good-color: rgb(41 100 51); --good-border: rgb(79 196 100); --middle-color: rgb(133 72 38); --middle-border: rgb(244, 227, 76); --bad-color: rgb(159 49 51); --bad-border: rgb(244, 76, 78); } /* unset some styles from the classic stylesheet */ div.document, div.body, div.related, div.body h1, div.body h2, div.body h3, div.body h4, div.body h5, div.body h6, div.sphinxsidebar a, div.sphinxsidebar p, div.sphinxsidebar ul, div.sphinxsidebar h3, div.sphinxsidebar h3 a, div.sphinxsidebar h4, .menu a, .menu p, .menu ul, .menu h3, .menu h3 a, .menu h4, table.docutils td, table.indextable tr.cap, pre { background-color: inherit; color: inherit; } /* Add underlines to links */ a[href] { text-decoration: underline 1px; } /* Increase the underline offset for code to avoid obscuring underscores */ a[href]:has(> code) { text-underline-offset: 0.25em; } /* No underline for navigation */ a.headerlink, div.genindex-jumpbox a, div.modindex-jumpbox a, div#search-results a, div.sphinxsidebar a, div.toctree-wrapper a, div[role=navigation] a, table.contentstable a, table.indextable a { text-decoration: none; } /* Except when hovered */ div.genindex-jumpbox a:hover, div.modindex-jumpbox a:hover, div#search-results a:hover, div.sphinxsidebar a:hover, div.toctree-wrapper a:hover, div[role=navigation] a:hover, table.contentstable a:hover, table.indextable a:hover { text-decoration: underline; text-underline-offset: auto; } body { margin-left: 1em; margin-right: 1em; } .mobile-nav, .menu-wrapper { display: none; } div.related { margin-top: 0.5em; margin-bottom: 1.2em; padding: 0.5em 0; border-width: 1px; border-color: #ccc; } .mobile-nav + div.related { border-bottom-style: solid; } .document + div.related { border-top-style: solid; } div.related a:hover { color: #0095c4; } .related .switchers { display: inline-flex; } .switchers > div { margin-right: 5px; } div.related ul::after { content: ''; clear: both; display: block; } .inline-search, form.inline-search input { display: inline; } form.inline-search input[type='submit'] { width: 40px; } div.document { display: flex; /* Don't let long code literals extend beyond the right side of the screen */ overflow-wrap: break-word; } /* Don't let long code literals extend beyond the right side of the screen */ span.pre { white-space: unset; } div.sphinxsidebar { display: flex; width: min(25vw, 350px); float: none; position: sticky; top: 0; max-height: 100vh; color: #444; background-color: #eee; border-radius: 5px; line-height: 130%; font-size: smaller; } div.sphinxsidebar h3, div.sphinxsidebar h4 { margin-top: 1.5em; } div.bodywrapper { margin-left: min(25vw, 350px); } div.sphinxsidebarwrapper { box-sizing: border-box; height: 100%; overflow-x: hidden; overflow-y: auto; float: none; flex-grow: 1; } div.sphinxsidebarwrapper > h3:first-child { margin-top: 0.2em; } div.sphinxsidebarwrapper > ul > li > ul > li { margin-bottom: 0.4em; } div.sphinxsidebar a:hover { color: #0095c4; } form.inline-search input, div.sphinxsidebar input, div.related input { font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif; border: 1px solid #999999; font-size: smaller; border-radius: 3px; } div.sphinxsidebar input[type='text'] { max-width: 150px; } #sidebarbutton { display: flex; justify-content: center; align-items: center; /* Sphinx 4.x and earlier compat */ height: 100%; background-color: #CCCCCC; margin-left: 0; color: #444444; font-size: 1.2em; cursor: pointer; padding-top: 1px; float: none; /* after Sphinx 4.x and earlier is dropped, only the below is needed */ width: 12px; min-width: 12px; border-radius: 0 5px 5px 0; border-left: none; } #sidebarbutton:hover { background-color: #AAAAAA; } div.body { padding: 0 0 0 1.2em; } div.body p, div.body dd, div.body li, div.body blockquote { text-align: left; line-height: 1.6; } div.body h1, div.body h2, div.body h3, div.body h4, div.body h5, div.body h6 { margin: 0; border: 0; padding: 0.3em 0; } div.body hr { border: 0; background-color: #ccc; height: 1px; } div.body pre { border-radius: 3px; border: 1px solid #ac9; } /* Admonitions */ :root { --admonition-background: #eee; --admonition-border: #ccc; --admonition-color: black; --attention-background: #bbddff5c; --attention-border: #0000ff36; --caution-background: #ffc; --caution-border: #dd6; --danger-background: #ffe4e4; --danger-border: red; --error-background: #ffe4e4; --error-border: red; --hint-background: #dfd; --hint-border: green; --seealso-background: #ffc; --seealso-border: #dd6; --tip-background: #dfd; --tip-border: green; --warning-background: #ffe4e4; --warning-border: red; } div.body div.admonition { background-color: var(--admonition-background); border: 1px solid var(--admonition-border); border-radius: 3px; color: var(--admonition-color); } div.body div.admonition.attention { background-color: var(--attention-background); border-color: var(--attention-border); } div.body div.admonition.caution { background-color: var(--caution-background); border-color: var(--caution-border); } div.body div.admonition.danger { background-color: var(--danger-background); border-color: var(--danger-border); } div.body div.admonition.error { background-color: var(--error-background); border-color: var(--error-border); } div.body div.admonition.hint { background-color: var(--hint-background); border-color: var(--hint-border); } div.body div.admonition.seealso { background-color: var(--seealso-background); border-color: var(--seealso-border); } div.body div.admonition.tip { background-color: var(--tip-background); border-color: var(--tip-border); } div.body div.admonition.warning { background-color: var(--warning-background); border-color: var(--warning-border); } div.body div.impl-detail { border-radius: 3px; } div.body div.impl-detail > p { margin: 0; } div.body a { color: #0072aa; } div.body a:visited { color: #6363bb; } div.body a:hover { color: #00b0e4; } tt, code, pre { font-family: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace; font-size: 96.5%; } div.body tt, div.body code { border-radius: 3px; } div.body tt.descname, div.body code.descname { font-size: 120%; } div.body tt.xref, div.body a tt, div.body code.xref, div.body a code { font-weight: normal; } table.docutils { border: 1px solid #ddd; min-width: 20%; border-radius: 3px; margin-top: 10px; margin-bottom: 10px; } table.docutils td, table.docutils th { border: 1px solid #ddd !important; border-radius: 3px; padding: 0.3em 0.5em; } table p, table li { text-align: left !important; } table.docutils th { background-color: #eee; } table.footnote, table.footnote td { border: 0 !important; } div.footer { line-height: 150%; text-align: right; width: auto; margin-right: 10px; } div.footer a { text-underline-offset: auto; } div.footer a:hover { color: #0095c4; } /* C API return value annotations */ :root { --refcount: var(--good-color); --refcount-return-borrowed-ref: var(--middle-color); } .refcount { color: var(--refcount); } .refcount.return_borrowed_ref { color: var(--refcount-return-borrowed-ref) } .stableabi { color: #229; } dl > dt span ~ em, .sig { font-family: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace; } .toctree-wrapper ul { padding-left: 20px; } .theme-selector { margin-left: .5em; } div.genindex-jumpbox, div.genindex-jumpbox > p { display: inline-flex; flex-wrap: wrap; } div.genindex-jumpbox a { margin: 0 5px; min-width: 30px; text-align: center; } .copybutton { cursor: pointer; position: absolute; top: 0; right: 0; font-family: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace; padding-left: 0.2em; padding-right: 0.2em; border-radius: 0 3px 0 0; color: #ac9; /* follows div.body pre */ border-color: #ac9; /* follows div.body pre */ border-style: solid; /* follows div.body pre */ border-width: 1px; /* follows div.body pre */ } .copybutton[data-hidden='true'] { text-decoration: line-through; } @media (max-width: 1023px) { /* Body layout */ div.body { min-width: 100%; padding: 0; font-size: 0.875rem; } div.bodywrapper { margin: 0; } /* Typography */ div.body h1 { font-size: 1.625rem; } div.body h2 { font-size: 1.25rem; } div.body h3, div.body h4, div.body h5 { font-size: 1rem; } /* Override default styles to make more readable */ div.body ul { padding-inline-start: 1rem; } div.body blockquote { margin-inline-start: 1rem; margin-inline-end: 0; } /* Remove sidebar and top related bar */ div.related, div.sphinxsidebar { display: none; } /* Anchorlinks are not hidden by fixed-positioned navbar when scrolled to */ html { scroll-padding-top: 40px; } body { margin-top: 40px; } /* Top navigation bar */ .mobile-nav { display: block; height: 40px; width: 100%; position: fixed; top: 0; left: 0; box-shadow: rgba(0, 0, 0, 0.25) 0 0 2px 0; z-index: 1; } .mobile-nav * { box-sizing: border-box; } .nav-content { position: absolute; z-index: 1; height: 40px; width: 100%; display: flex; background-color: white; } .nav-items-wrapper { display: flex; flex: auto; padding: .25rem; align-items: stretch; } .nav-logo { margin-right: 1rem; flex-shrink: 0; align-self: center; } .nav-content img { display: block; width: 20px; } .version_switcher_placeholder { margin-right: 1rem; } .version_switcher_placeholder > select { height: 100%; } .nav-content .search { display: flex; flex: auto; border: 1px solid #a9a9a9; align-items: stretch; } .nav-content .search input[type=search] { border: 0; padding-left: 24px; width: 100%; flex: 1; } .nav-content .search input[type=submit] { height: 100%; box-shadow: none; border: 0; border-left: 1px solid #a9a9a9; cursor: pointer; margin-right: 0; } .nav-content .search svg { position: absolute; align-self: center; padding-left: 4px; } .toggler__input { display: none; } .toggler__label { width: 40px; cursor: pointer; display: flex; align-items: center; justify-content: center; padding: 8px; flex-shrink: 0; } .toggler__label:hover, .toggler__label:focus { background-color: rgba(127 127 127 / 50%); } .toggler__label > span { position: relative; flex: none; height: 2px; width: 100%; background: currentColor; transition: all 400ms ease; } .toggler__label > span::before, .toggler__label > span::after { content: ''; height: 2px; width: 100%; background: inherit; position: absolute; left: 0; top: -8px; } .toggler__label > span::after { top: 8px; } .toggler__input:checked ~ nav > .toggler__label span { transform: rotate(135deg); } .toggler__input:checked ~ nav > .toggler__label span::before { transform: rotate(90deg); } .toggler__input:checked ~ nav > .toggler__label span::before, .toggler__input:checked ~ nav > .toggler__label span::after { top: 0; } .toggler__input:checked:hover ~ nav > .toggler__label span { transform: rotate(315deg); } .toggler__input:checked ~ .menu-wrapper { visibility: visible; left: 0; } /* Sliding side menu */ .menu-wrapper { display: block; position: fixed; top: 0; transition: left 400ms ease; left: -310px; width: 300px; height: 100%; background-color: #eee; color: #444444; box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); overflow-y: auto; } .menu-wrapper.open { visibility: visible; left: 0; } .menu { padding: 40px 10px 30px 20px; } .menu-wrapper h3, .menu-wrapper h4 { margin-bottom: 0; font-weight: normal; } .menu-wrapper h4 { font-size: 1.3em; } .menu-wrapper h3 { font-size: 1.4em; } .menu-wrapper h3 + p, .menu-wrapper h4 + p { margin-top: 0.5rem; } .menu a { font-size: smaller; text-decoration: none; } .menu ul { list-style: none; line-height: 1.4; overflow-wrap: break-word; padding-left: 0; } .menu ul ul { margin-left: 20px; list-style: square; } .menu ul li { margin-bottom: 0.5rem; } .language_switcher_placeholder { margin-top: 2rem; } .language_switcher_placeholder select { width: 100%; } .document { position: relative; z-index: 0; } /*Responsive tables*/ .responsive-table__container { width: 100%; overflow-x: auto; } .menu .theme-selector-label { margin-top: .5em; display: flex; width: 100%; } .menu .theme-selector { flex: auto; } } @media (min-width: 1024px) { div.footer { margin-top: -2em; } } /* Version change directives */ :root { --versionadded: var(--good-color); --versionchanged: var(--middle-color); --deprecated: var(--bad-color); --versionadded-border: var(--good-border); --versionchanged-border: var(--middle-border); --deprecated-border: var(--bad-border); } div.versionadded, div.versionchanged, div.deprecated, div.deprecated-removed { border-left: 3px solid; padding: 0 1rem; } div.versionadded { border-left-color: var(--versionadded-border); } div.versionchanged { border-left-color: var(--versionchanged-border); } div.deprecated, div.deprecated-removed, div.versionremoved { border-left-color: var(--deprecated-border); } div.versionadded .versionmodified { color: var(--versionadded); } div.versionchanged .versionmodified { color: var(--versionchanged); } div.deprecated .versionmodified, div.deprecated-removed .versionmodified, div.versionremoved .versionmodified { color: var(--deprecated); } /* Hide header when printing */ @media print { div.mobile-nav { display: none; } } python-docs-theme-2025.2/python_docs_theme/static/pydoctheme_dark.css000066400000000000000000000062641475042510400260430ustar00rootroot00000000000000/* Common colours */ :root { --good-color: rgb(79 196 100); --good-border: var(--good-color); --middle-color: rgb(244, 227, 76); --middle-border: var(--middle-color); --bad-color: rgb(244, 76, 78); --bad-border: var(--bad-color); } /* Browser elements */ :root { scrollbar-color: #616161 transparent; color-scheme: dark; } html, body { background-color: #222; color: rgba(255, 255, 255, 0.87); } div.related { color: rgba(255, 255, 255, 0.7); /* classic overwrite */ border-color: #424242; } /* SIDEBAR */ div.sphinxsidebar, .menu-wrapper { background-color: #333; color: inherit; } #sidebarbutton { /* important to overwrite style attribute */ background-color: #555 !important; color: inherit !important; } div.sidebar, aside.sidebar { background-color: #424242; border-color: #616161; } /* ANCHORS AND HIGHLIGHTS */ div.body a { color: #7af; } div.body a:visited { color: #09e; } a.headerlink:hover { background-color: #424242; } div.related a { color: currentColor; } div.footer, div.footer a { color: currentColor; /* classic overwrites */ } dt:target, span.highlighted { background-color: #616161; } .footnote:target { background-color: #2c3e50; } /* Below for most things in text */ dl.field-list > dt { background-color: #434; } table.docutils td, table.docutils th { border-color: #616161 !important; } table.docutils th { background-color: #424242; } .stableabi { color: #bbf; } div.body pre { border-color: #616161; } code { background-color: #424242; } div.body div.seealso { background-color: rgba(255, 255, 0, 0.1); } div.warning { background-color: rgba(255, 0, 0, 0.2); } .warning code { background-color: rgba(255, 0, 0, 0.5); } /* Admonitions */ :root { --admonition-background: #ffffff1a; --admonition-border: currentColor; --admonition-color: #ffffffde; --attention-background: #ffffff1a; --attention-border: currentColor; --caution-background: #ffff001a; --caution-border: #dd6; --danger-background: #f003; --danger-border: #f66; --error-background: #f003; --error-border: #f66; --hint-background: #0044117a; --hint-border: green; --seealso-background: #ffff001a; --seealso-border: #dd6; --tip-background: #0044117a; --tip-border: green; --warning-background: #ff000033; --warning-border: #ff6666; } aside.topic, div.topic, div.note, nav.contents { background-color: rgba(255, 255, 255, 0.1); border-color: currentColor; } .note code { background-color: rgba(255, 255, 255, 0.1); } .mobile-nav { box-shadow: rgba(255, 255, 255, 0.25) 0 0 2px 0; } .nav-content { background-color: black; } img.invert-in-dark-mode { filter: invert(1) hue-rotate(.5turn); } /* -- object description styles --------------------------------------------- */ /* C++ specific styling */ /* Override Sphinx's basic.css to fix colour contrast */ .sig.c .k, .sig.c .kt, .sig.cpp .k, .sig.cpp .kt { color: #5283ff; } /* Version change directives */ :root { --versionadded: var(--good-color); --versionchanged: var(--middle-color); --deprecated: var(--bad-color); } python-docs-theme-2025.2/python_docs_theme/static/search-focus.js000066400000000000000000000010571475042510400251020ustar00rootroot00000000000000function isInputFocused() { const activeElement = document.activeElement; return ( activeElement.tagName === 'INPUT' || activeElement.tagName === 'TEXTAREA' || activeElement.isContentEditable ); } document.addEventListener('keydown', function(event) { if (event.key === '/') { if (!isInputFocused()) { // Prevent "/" from being entered in the search box event.preventDefault(); // Set the focus on the search box const searchBox = document.getElementById('search-box'); searchBox.focus(); } } }); python-docs-theme-2025.2/python_docs_theme/static/sidebar.js_t000066400000000000000000000064261475042510400244610ustar00rootroot00000000000000/* * sidebar.js * ~~~~~~~~~~ * * This file is functionally identical to "sidebar.js" in Sphinx 5.0. * When support for Sphinx 4 and earlier is dropped from the theme, * this file can be removed. * * This script makes the Sphinx sidebar collapsible. * * .sphinxsidebar contains .sphinxsidebarwrapper. This script adds * in .sphinxsidebar, after .sphinxsidebarwrapper, the #sidebarbutton * used to collapse and expand the sidebar. * * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden * and the width of the sidebar and the margin-left of the document * are decreased. When the sidebar is expanded the opposite happens. * This script saves a per-browser/per-session cookie used to * remember the position of the sidebar among the pages. * Once the browser is closed the cookie is deleted and the position * reset to the default (expanded). * * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ const initialiseSidebar = () => { // global elements used by the functions. const bodyWrapper = document.getElementsByClassName("bodywrapper")[0] const sidebar = document.getElementsByClassName("sphinxsidebar")[0] const sidebarWrapper = document.getElementsByClassName("sphinxsidebarwrapper")[0] // exit early if the document has no sidebar for some reason if (typeof sidebar === "undefined") { return } {# Check if we need to dynamically insert the sidebar button. # We prefer the ``sphinx_version_tuple`` variable, and if it is undefined we # know we are running a Sphinx version older than 4.2. # # See: https://www.sphinx-doc.org/en/master/development/templating.html#sphinx_version_tuple #} {% if sphinx_version_tuple is defined and sphinx_version_tuple[0] >= 5 %} const sidebarButton = document.getElementById("sidebarbutton") const sidebarArrow = sidebarButton.querySelector('span') {% else %} // create the sidebar button element const sidebarButton = document.createElement("div") sidebarButton.id = "sidebarbutton" // create the sidebar button arrow element const sidebarArrow = document.createElement("span") sidebarArrow.innerText = "«" sidebarButton.appendChild(sidebarArrow) sidebar.appendChild(sidebarButton) {% endif %} const collapse_sidebar = () => { bodyWrapper.style.marginLeft = ".8em" sidebar.style.width = ".8em" sidebarWrapper.style.display = "none" sidebarArrow.innerText = "»" sidebarButton.title = _("Expand sidebar") window.localStorage.setItem("sidebar", "collapsed") } const expand_sidebar = () => { bodyWrapper.style.marginLeft = "" sidebar.style.removeProperty("width") sidebarWrapper.style.display = "" sidebarArrow.innerText = "«" sidebarButton.title = _("Collapse sidebar") window.localStorage.setItem("sidebar", "expanded") } sidebarButton.addEventListener("click", () => { (sidebarWrapper.style.display === "none") ? expand_sidebar() : collapse_sidebar() }) const sidebar_state = window.localStorage.getItem("sidebar") if (sidebar_state === "collapsed") { collapse_sidebar() } else if (sidebar_state === "expanded") { expand_sidebar() } } if (document.readyState !== "loading") { initialiseSidebar() } else { document.addEventListener("DOMContentLoaded", initialiseSidebar) } python-docs-theme-2025.2/python_docs_theme/static/themetoggle.js000066400000000000000000000014131475042510400250200ustar00rootroot00000000000000const pydocthemeDark = document.getElementById('pydoctheme_dark_css') const pygmentsDark = document.getElementById('pygments_dark_css') const themeSelectors = document.getElementsByClassName('theme-selector') function activateTheme(theme) { localStorage.setItem('currentTheme', theme); [...themeSelectors].forEach(e => e.value = theme) switch (theme) { case 'light': pydocthemeDark.media = 'not all' pygmentsDark.media = 'not all' break; case 'dark': pydocthemeDark.media = 'all' pygmentsDark.media = 'all' break; default: // auto pydocthemeDark.media = '(prefers-color-scheme: dark)' pygmentsDark.media = '(prefers-color-scheme: dark)' } } activateTheme(localStorage.getItem('currentTheme') || 'auto') python-docs-theme-2025.2/python_docs_theme/theme.conf000066400000000000000000000020201475042510400226330ustar00rootroot00000000000000[theme] inherit = default stylesheet = pydoctheme.css pygments_style = default pygments_dark_style = monokai [options] bodyfont = -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif headfont = -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif footerbgcolor = white footertextcolor = #555555 relbarbgcolor = white relbartextcolor = #666666 relbarlinkcolor = #444444 sidebarbgcolor = white sidebartextcolor = #444444 sidebarlinkcolor = #444444 sidebarbtncolor = #cccccc bgcolor = white textcolor = #222222 linkcolor = #0090c0 visitedlinkcolor = #00608f headtextcolor = #1a1a1a headbgcolor = white headlinkcolor = #aaaaaa codebgcolor = #eeffcc codetextcolor = #333333 hosted_on = issues_url = license_url = root_name = Python root_url = https://www.python.org/ root_icon = py.svg root_icon_alt_text = Python logo root_include_title = True copyright_url = python-docs-theme-2025.2/requirements.txt000066400000000000000000000001151475042510400204360ustar00rootroot00000000000000# for babel_runner.py setuptools Babel Jinja2 tomli; python_version < "3.11"