Skip to content

Commit 75efd63

Browse files
committed
Add an envvar_bool helper and use it for the version-check flag
Replaces the flag-specific _warning_disabled with a shared envvar_bool, exported from cuda.bindings.utils. It recognises 1/true/yes/on and 0/false/no/off case-insensitively, falls back to C truthiness for other integers, and treats unset, empty, and whitespace-only as the caller's default. The helper lives in utils/_envvar.py rather than directly in utils/__init__.py because __init__ already imports _version_check, which needs the helper -- defining it in __init__ would make that import circular. It is re-exported so the public name is cuda.bindings.utils.envvar_bool. The parsing test moves to test_envvar.py and drives an arbitrary variable name instead of the version-check one.
1 parent de3df79 commit 75efd63

5 files changed

Lines changed: 90 additions & 52 deletions

File tree

‎cuda_bindings/cuda/bindings/utils/__init__.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# SPDX-License-Identifier: Apache-2.0
33
from typing import Any, Callable
44

5+
from ._envvar import envvar_bool
56
from ._nvvm_utils import check_nvvm_compiler_options
67
from ._ptx_utils import get_minimal_required_cuda_ver_from_ptx_ver, get_ptx_ver
78
from ._version_check import warn_if_cuda_major_version_mismatch
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
import os
5+
6+
_TRUE_VALUES = frozenset({"1", "true", "yes", "on"})
7+
_FALSE_VALUES = frozenset({"0", "false", "no", "off"})
8+
9+
10+
def envvar_bool(name: str, default: bool = False) -> bool:
11+
"""Read a bool-like environment variable.
12+
13+
Unset, empty, or whitespace-only means ``default``. ``1/true/yes/on`` and
14+
``0/false/no/off`` are recognised case-insensitively, and any other integer
15+
follows C truthiness, so ``2`` is true and ``-0`` is false.
16+
17+
A value that is none of those keeps the historical set-means-true
18+
behaviour rather than raising, because these variables are read during
19+
import and a raise would turn a typo into an import failure.
20+
"""
21+
raw = os.environ.get(name)
22+
if raw is None:
23+
return default
24+
raw = raw.strip()
25+
if not raw:
26+
return default
27+
lowered = raw.lower()
28+
if lowered in _TRUE_VALUES:
29+
return True
30+
if lowered in _FALSE_VALUES:
31+
return False
32+
try:
33+
return int(raw, 0) != 0
34+
except ValueError:
35+
return True

‎cuda_bindings/cuda/bindings/utils/_version_check.py‎

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,18 @@
11
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
22
# SPDX-License-Identifier: Apache-2.0
33

4-
import os
54
import threading
65
import warnings
76

7+
from ._envvar import envvar_bool
8+
89
# Track whether we've already checked major version compatibility
910
_major_version_compatibility_checked = False
1011
_lock = threading.Lock()
1112

1213
_DISABLE_WARNING_ENV_VAR = "CUDA_PYTHON_DISABLE_MAJOR_VERSION_WARNING"
1314

1415

15-
def _warning_disabled() -> bool:
16-
"""Whether the user asked to suppress the major-version warning.
17-
18-
``=0`` means "do not suppress". A bare truthiness test on the raw string
19-
made ``CUDA_PYTHON_DISABLE_MAJOR_VERSION_WARNING=0`` suppress the warning
20-
-- the exact opposite of what the warning itself tells the user to type,
21-
and the opposite of the other boolean knobs in this repository
22-
(``CUDA_PYTHON_CUDA_PER_THREAD_DEFAULT_STREAM`` and
23-
``CUDA_CORE_DONT_FIX_TAB_COMPLETION``), which both parse their value with
24-
``int()``.
25-
26-
Unset and empty still mean "not disabled". A value that is not an integer
27-
keeps the old set-means-disabled behaviour, so anyone currently relying on
28-
a spelling like ``=true`` does not silently start seeing the warning again.
29-
"""
30-
raw = os.environ.get(_DISABLE_WARNING_ENV_VAR, "").strip()
31-
if not raw:
32-
return False
33-
try:
34-
return int(raw) != 0
35-
except ValueError:
36-
return True
37-
38-
3916
def warn_if_cuda_major_version_mismatch():
4017
"""Warn if the CUDA driver major version is older than cuda-bindings compile-time version.
4118
@@ -59,7 +36,7 @@ def warn_if_cuda_major_version_mismatch():
5936
_major_version_compatibility_checked = True
6037

6138
# Allow users to suppress the warning
62-
if _warning_disabled():
39+
if envvar_bool(_DISABLE_WARNING_ENV_VAR):
6340
return
6441

6542
# Import here to avoid circular imports and allow lazy loading

‎cuda_bindings/tests/test_envvar.py‎

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
import pytest
5+
6+
from cuda.bindings.utils import envvar_bool
7+
8+
_VAR = "CUDA_PYTHON_TEST_ENVVAR_BOOL"
9+
10+
11+
@pytest.mark.agent_authored(model="claude-opus-5")
12+
@pytest.mark.parametrize(
13+
("raw", "expected"),
14+
[
15+
pytest.param("0", False, id="zero"),
16+
pytest.param(" 0 ", False, id="zero-padded"),
17+
pytest.param("", False, id="empty"),
18+
pytest.param(" ", False, id="blank"),
19+
pytest.param("1", True, id="one"),
20+
pytest.param("2", True, id="two"),
21+
pytest.param("-0", False, id="negative-zero"),
22+
pytest.param("false", False, id="false"),
23+
pytest.param("FALSE", False, id="false-upper"),
24+
pytest.param("no", False, id="no"),
25+
pytest.param("off", False, id="off"),
26+
pytest.param("true", True, id="true"),
27+
pytest.param("True", True, id="true-capitalised"),
28+
pytest.param("yes", True, id="yes"),
29+
pytest.param("on", True, id="on"),
30+
# Anything unrecognised keeps the historical set-means-true behaviour.
31+
pytest.param("banana", True, id="unrecognised"),
32+
],
33+
)
34+
def test_envvar_bool_parsing(monkeypatch, raw, expected):
35+
monkeypatch.setenv(_VAR, raw)
36+
assert envvar_bool(_VAR) is expected
37+
38+
39+
@pytest.mark.agent_authored(model="claude-opus-5")
40+
@pytest.mark.parametrize("default", [False, True])
41+
def test_envvar_bool_unset_returns_default(monkeypatch, default):
42+
monkeypatch.delenv(_VAR, raising=False)
43+
assert envvar_bool(_VAR, default) is default
44+
45+
46+
@pytest.mark.agent_authored(model="claude-opus-5")
47+
@pytest.mark.parametrize("raw", ["", " "])
48+
def test_envvar_bool_blank_returns_default(monkeypatch, raw):
49+
"""Blank is "not set", so it must not override a True default."""
50+
monkeypatch.setenv(_VAR, raw)
51+
assert envvar_bool(_VAR, True) is True

‎cuda_bindings/tests/test_version_check.py‎

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -84,32 +84,6 @@ def test_warning_suppressed_by_env_var(self):
8484
warn_if_cuda_major_version_mismatch()
8585
assert len(w) == 0
8686

87-
@pytest.mark.agent_authored(model="claude-opus-5")
88-
@pytest.mark.parametrize(
89-
("raw", "expected"),
90-
[
91-
pytest.param("0", False, id="zero"),
92-
pytest.param(" 0 ", False, id="zero-padded"),
93-
pytest.param("", False, id="empty"),
94-
pytest.param(" ", False, id="blank"),
95-
pytest.param("1", True, id="one"),
96-
pytest.param("2", True, id="two"),
97-
# Not an integer: keep the old set-means-disabled behaviour so no
98-
# one relying on a spelling like `=true` starts seeing the warning
99-
# again.
100-
pytest.param("true", True, id="true"),
101-
pytest.param("yes", True, id="yes"),
102-
],
103-
)
104-
def test_disable_flag_parsing(self, monkeypatch, raw, expected):
105-
monkeypatch.setenv("CUDA_PYTHON_DISABLE_MAJOR_VERSION_WARNING", raw)
106-
assert _version_check._warning_disabled() is expected
107-
108-
@pytest.mark.agent_authored(model="claude-opus-5")
109-
def test_disable_flag_unset(self, monkeypatch):
110-
monkeypatch.delenv("CUDA_PYTHON_DISABLE_MAJOR_VERSION_WARNING", raising=False)
111-
assert _version_check._warning_disabled() is False
112-
11387
@pytest.mark.agent_authored(model="claude-opus-5")
11488
def test_warning_not_suppressed_when_env_var_is_zero(self):
11589
"""``=0`` is how a user says "no, keep warning me".

0 commit comments

Comments
 (0)