Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/RELEASE-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,13 @@ This must happen *before* the release tag is cut. Removals are breaking
changes, so they are only permitted at a major-version boundary per the
[support policy](https://nvidia.github.io/cuda-python/cuda-core/latest/support.html).

There may also be deprecations in `cuda-bindings` tied to a particular `cuda-core` release.
Find those this way:

```console
$ grep -rn 'deprecated:: cuda-core' cuda_bindings/cuda
```

---

## Finalize the doc update, including release notes
Expand Down
84 changes: 84 additions & 0 deletions cuda_bindings/cuda/bindings/_test_helpers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

"""Deprecated shim package.

These helpers moved to ``cuda_python_test_helpers`` in #2384 (2026-08-04).
This package is kept for one cuda-core release cycle so that already-released
cuda-core test trees (<=1.1.x), which still import from here, keep working
against newer cuda-bindings wheels. See #2725.

The idea here is to import the current cuda_python_test_helpers that cuda_bindings
expects, even if the real cuda_python_test_helpers name is already claimed by an older,
incompatible copy.

.. deprecated:: cuda-core-1.2
Remove this entire subpackage once cuda-core >= 1.2 is the oldest supported
release.
"""

import importlib
import importlib.util
import pathlib
import sys

# Private alias under which a modern (post-#2384) cuda_python_test_helpers
# source checkout is loaded, when the real `cuda_python_test_helpers` name is
# already claimed by an older, incompatible copy. See _import_current below.
_CURRENT_ALIAS = "_cuda_bindings_test_helpers_current"


def _find_current_test_helpers_package():
"""Locate and load cuda_python_test_helpers source checkout under a private
alias name, bypassing sys.modules entirely.
"""
if _CURRENT_ALIAS in sys.modules:
return sys.modules[_CURRENT_ALIAS]

candidates = [*pathlib.Path(__file__).parents, pathlib.Path.cwd(), *pathlib.Path.cwd().parents]
seen: set[pathlib.Path] = set()
for candidate in candidates:
if candidate in seen:
continue
seen.add(candidate)
pkg_dir = candidate / "cuda_python_test_helpers" / "cuda_python_test_helpers"
init_file = pkg_dir / "__init__.py"
if init_file.is_file() and (pkg_dir / "arch_check.py").is_file():
spec = importlib.util.spec_from_file_location(
_CURRENT_ALIAS, init_file, submodule_search_locations=[str(pkg_dir)]
)
if spec is None or spec.loader is None:
continue
module = importlib.util.module_from_spec(spec)
sys.modules[_CURRENT_ALIAS] = module
spec.loader.exec_module(module)
return module

return None


def _import_current(submodule_name: str):
"""Import cuda_python_test_helpers.<submodule_name>.

Prefers whatever is already importable under the real
``cuda_python_test_helpers`` name. Falls back to a modern copy loaded under
a private alias if the real name resolves to an older, incompatible copy --
e.g. released cuda-core <= 1.1.1 (tagged 2026-07-29, six days before #2384
landed) ships its own ``tests/conftest.py`` that puts a pre-#2384
``cuda_python_test_helpers`` (predating arch_check.py / mempool.py /
pep723.py living there at all) on sys.path and caches it in sys.modules
under the real name before this shim ever runs.
"""
try:
return importlib.import_module(f"cuda_python_test_helpers.{submodule_name}")
except ImportError:
pass

module = _find_current_test_helpers_package()
if module is None:
raise ModuleNotFoundError(
f"cuda_python_test_helpers.{submodule_name} is required by cuda.bindings._test_helpers "
"but is not installed, and no source checkout containing it was found near this file "
"or the current working directory."
)
return importlib.import_module(f"{module.__name__}.{submodule_name}")
15 changes: 15 additions & 0 deletions cuda_bindings/cuda/bindings/_test_helpers/arch_check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

"""Deprecated shim. Moved to cuda_python_test_helpers.arch_check in #2384 (2026-08-04).
Kept for one release cycle so released cuda-core test trees keep importing.
Remove after cuda-core >= 1.2 is the oldest supported release.
"""

from cuda.bindings._test_helpers import _import_current

_arch_check = _import_current("arch_check")
hardware_supports_nvml = _arch_check.hardware_supports_nvml
unsupported_before = _arch_check.unsupported_before

__all__ = ["hardware_supports_nvml", "unsupported_before"]
15 changes: 15 additions & 0 deletions cuda_bindings/cuda/bindings/_test_helpers/mempool.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

"""Deprecated shim. Moved to cuda_python_test_helpers.mempool in #2384 (2026-08-04).
Kept for one release cycle so released cuda-core test trees keep importing.
Remove after cuda-core >= 1.2 is the oldest supported release.
"""

from cuda.bindings._test_helpers import _import_current

_mempool = _import_current("mempool")
is_windows_mcdm_device = _mempool.is_windows_mcdm_device
xfail_if_mempool_oom = _mempool.xfail_if_mempool_oom

__all__ = ["is_windows_mcdm_device", "xfail_if_mempool_oom"]
14 changes: 14 additions & 0 deletions cuda_bindings/cuda/bindings/_test_helpers/pep723.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

"""Deprecated shim. Moved to cuda_python_test_helpers.pep723 in #2384 (2026-08-04).
Kept for one release cycle so released cuda-core test trees keep importing.
Remove after cuda-core >= 1.2 is the oldest supported release.
"""

from cuda.bindings._test_helpers import _import_current

_pep723 = _import_current("pep723")
has_package_requirements_or_skip = _pep723.has_package_requirements_or_skip

__all__ = ["has_package_requirements_or_skip"]
39 changes: 39 additions & 0 deletions cuda_core/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,30 @@

pytest_plugins = ["cuda_python_test_helpers._pytest_plugin"]


class _BanBindingsTestHelpersShimFinder:
"""Hard-fails any import of the deprecated ``cuda.bindings._test_helpers``
shim (added by #2731).

That shim exists solely so already-released cuda-core <=1.1.1 test trees
keep working against newer cuda-bindings wheels (see #2725); it is
scheduled for removal once cuda-core >= 1.2 is the oldest supported
release. This (current, in-repo) cuda-core test suite must always use
cuda_python_test_helpers directly and should never exercise that shim.
"""

def find_spec(self, fullname, path, target=None):
if fullname == "cuda.bindings._test_helpers" or fullname.startswith("cuda.bindings._test_helpers."):
raise ImportError(
f"Refusing to import {fullname!r}: this is a deprecated compatibility shim "
"(see #2731/#2725) meant only for already-released cuda-core <=1.1.1 test "
"trees. This test suite must import from cuda_python_test_helpers directly."
)
return None


sys.meta_path.insert(0, _BanBindingsTestHelpersShimFinder())

from helpers.constants import POOL_SIZE
from helpers.memory import skip_if_pinned_memory_unsupported

Expand Down Expand Up @@ -184,6 +208,21 @@ def session_setup():
multiprocessing.set_start_method("spawn", force=True)


@pytest.fixture(scope="session", autouse=True)
def _forbid_bindings_test_helpers_shim():
# Belt-and-suspenders alongside _BanBindingsTestHelpersShimFinder above:
# independently re-check at session end that nothing slipped the
# deprecated cuda.bindings._test_helpers shim into sys.modules, in case
# the meta path finder is ever bypassed, disabled, or removed by mistake.
yield
banned = [
name
for name in sys.modules
if name == "cuda.bindings._test_helpers" or name.startswith("cuda.bindings._test_helpers.")
]
assert not banned, f"deprecated cuda.bindings._test_helpers shim was imported (see #2731): {banned}"


@pytest.fixture
def init_cuda():
with _init_cuda_context() as device:
Expand Down
Loading