From ea3c3a369c696802b87e553791697498e566dcc2 Mon Sep 17 00:00:00 2001 From: LeSingh1 Date: Sat, 8 Aug 2026 19:23:23 -0700 Subject: [PATCH] docs: don't abort the docs build when BUILD_PREVIEW/BUILD_LATEST is empty Both Sphinx configs read the two docs-build flags with a bare int(): if int(os.environ.get("BUILD_PREVIEW", 0)): os.environ.get returns the empty string, not the default, when a variable is exported but empty -- and the build scripts that drive these configs already treat that state as "not set": # cuda_core/docs/build_docs.sh, cuda_python/docs/build_docs.sh if [[ "${LATEST_ONLY}" == "1" && -z "${BUILD_PREVIEW:-}" && -z "${BUILD_LATEST:-}" ]]; then export BUILD_LATEST=1 fi So the shell layer says empty means unset, then conf.py raises on it: ValueError: invalid literal for int() with base 10: '' taking down the whole docs build from inside conf.py, before any page is rendered. `BUILD_PREVIEW= ./build_docs.sh latest-only` is enough to hit it. Add an _env_flag helper to each config and route all ten call sites through it (six in cuda_core, four in cuda_python). Unset, empty, whitespace-only and "0" are all false; any other value is true, so a non-numeric spelling such as BUILD_LATEST=true is honoured rather than aborting the build. The helper is duplicated across the two configs deliberately, matching the existing duplication of _html_baseurl between them. --- cuda_core/docs/source/conf.py | 28 +++++++++++++++++++++++----- cuda_python/docs/source/conf.py | 26 ++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/cuda_core/docs/source/conf.py b/cuda_core/docs/source/conf.py index 451eb8b4453..0948f324cb2 100644 --- a/cuda_core/docs/source/conf.py +++ b/cuda_core/docs/source/conf.py @@ -27,10 +27,28 @@ release = os.environ["SPHINX_CUDA_CORE_VER"] +def _env_flag(name: str) -> bool: + """Read a 0/1 docs-build flag from the environment. + + Unset and empty mean the same thing here: the build scripts test these with + ``-z "${BUILD_PREVIEW:-}"``, so an exported-but-empty value is already + "not set" one layer up. A bare ``int()`` disagreed and raised + ``ValueError: invalid literal for int() with base 10: ''``, aborting the + docs build from conf.py. + """ + raw = os.environ.get(name, "").strip() + if not raw: + return False + try: + return int(raw) != 0 + except ValueError: + return True + + def _github_examples_ref(): if ref := os.environ.get("CUDA_PYTHON_DOCS_GITHUB_REF"): return ref - if int(os.environ.get("BUILD_PREVIEW", 0)) or int(os.environ.get("BUILD_LATEST", 0)): + if _env_flag("BUILD_PREVIEW") or _env_flag("BUILD_LATEST"): return "main" return f"cuda-core-v{release}" @@ -40,9 +58,9 @@ def _github_examples_ref(): def _html_baseurl(): docs_domain = os.environ.get("CUDA_PYTHON_DOCS_DOMAIN", "https://nvidia.github.io/cuda-python") - if int(os.environ.get("BUILD_PREVIEW", 0)): + if _env_flag("BUILD_PREVIEW"): return f"{docs_domain}/pr-preview/pr-{os.environ['PR_NUMBER']}/cuda-core/latest/" - if int(os.environ.get("BUILD_LATEST", 0)): + if _env_flag("BUILD_LATEST"): return f"{docs_domain}/cuda-core/latest/" return f"{docs_domain}/cuda-core/{release}/" @@ -103,11 +121,11 @@ def _html_baseurl(): "show_toc_level": 3, } if os.environ.get("CI"): - if int(os.environ.get("BUILD_PREVIEW", 0)): + if _env_flag("BUILD_PREVIEW"): PR_NUMBER = f"{os.environ['PR_NUMBER']}" PR_TEXT = f'PR {PR_NUMBER}' html_theme_options["announcement"] = f"Warning: This documentation is only a preview for {PR_TEXT}!" - elif int(os.environ.get("BUILD_LATEST", 0)): + elif _env_flag("BUILD_LATEST"): html_theme_options["announcement"] = ( "Warning: This documentation is built from the development branch!" ) diff --git a/cuda_python/docs/source/conf.py b/cuda_python/docs/source/conf.py index f7b447f9dac..52445d11b0e 100644 --- a/cuda_python/docs/source/conf.py +++ b/cuda_python/docs/source/conf.py @@ -26,11 +26,29 @@ release = os.environ["SPHINX_CUDA_PYTHON_VER"] +def _env_flag(name: str) -> bool: + """Read a 0/1 docs-build flag from the environment. + + Unset and empty mean the same thing here: the build scripts test these with + ``-z "${BUILD_PREVIEW:-}"``, so an exported-but-empty value is already + "not set" one layer up. A bare ``int()`` disagreed and raised + ``ValueError: invalid literal for int() with base 10: ''``, aborting the + docs build from conf.py. + """ + raw = os.environ.get(name, "").strip() + if not raw: + return False + try: + return int(raw) != 0 + except ValueError: + return True + + def _html_baseurl(): docs_domain = os.environ.get("CUDA_PYTHON_DOCS_DOMAIN", "https://nvidia.github.io/cuda-python") - if int(os.environ.get("BUILD_PREVIEW", 0)): + if _env_flag("BUILD_PREVIEW"): return f"{docs_domain}/pr-preview/pr-{os.environ['PR_NUMBER']}/latest/" - if int(os.environ.get("BUILD_LATEST", 0)): + if _env_flag("BUILD_LATEST"): return f"{docs_domain}/latest/" return f"{docs_domain}/{release}/" @@ -85,11 +103,11 @@ def _html_baseurl(): "show_toc_level": 3, } if os.environ.get("CI"): - if int(os.environ.get("BUILD_PREVIEW", 0)): + if _env_flag("BUILD_PREVIEW"): PR_NUMBER = f"{os.environ['PR_NUMBER']}" PR_TEXT = f'PR {PR_NUMBER}' html_theme_options["announcement"] = f"Warning: This documentation is only a preview for {PR_TEXT}!" - elif int(os.environ.get("BUILD_LATEST", 0)): + elif _env_flag("BUILD_LATEST"): html_theme_options["announcement"] = ( "Warning: This documentation is built from the development branch!" )