Coverage for cuda/core/_utils/enum_explanations_helpers.py: 67.57%
37 statements
« prev ^ index » next coverage.py v7.17.2, created at 2026-11-05 01:11 +0000
« prev ^ index » next coverage.py v7.17.2, created at 2026-11-05 01:11 +0000
1# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2# SPDX-License-Identifier: Apache-2.0
4"""Internal support for error-enum explanations.
6Driver and runtime error enums in ``cuda-bindings`` carry per-member
7``__doc__`` text. ``cuda-bindings`` added the text in 12.9.6 on the 12.x line
8and in 13.2.0 on the 13.x line. Every ``cuda-bindings`` that ``cuda.core``
9accepts has it. This module normalizes those generated docstrings so that
10user-facing ``CUDAError`` messages stay presentable.
12The cleanup rules here were derived while validating generated enum docstrings
13in PR #1805. Keep them narrow. When the codegen quirks are gone, remove them.
14"""
16from __future__ import annotations
18import re
19from typing import Any
21_RST_INLINE_ROLE_RE = re.compile(r":(?:[a-z]+:)?[a-z]+:`([^`]+)`")
22_WORDWRAP_HYPHEN_AFTER_RE = re.compile(r"(?<=[0-9A-Za-z_])- (?=[0-9A-Za-z_])")
23_WORDWRAP_HYPHEN_BEFORE_RE = re.compile(r"(?<=[0-9A-Za-z_]) -(?=[0-9A-Za-z_])")
26def _fix_hyphenation_wordwrap_spacing(s: str) -> str:
27 """Remove spaces around hyphens introduced by line wrapping in generated ``__doc__`` text.
29 This targets asymmetric wrap artifacts such as ``non- linear`` or
30 ``GPU- Direct`` while leaving intentional ``a - b`` separators alone.
31 """
32 prev = None 1cdefghijklmnopqrstuvwxyzABCaDEFGbHIJKLMNOPQRSTUVWXYZ012345678
33 while prev != s: 1cdefghijklmnopqrstuvwxyzABCaDEFGbHIJKLMNOPQRSTUVWXYZ012345678
34 prev = s 1cdefghijklmnopqrstuvwxyzABCaDEFGbHIJKLMNOPQRSTUVWXYZ012345678
35 s = _WORDWRAP_HYPHEN_AFTER_RE.sub("-", s) 1cdefghijklmnopqrstuvwxyzABCaDEFGbHIJKLMNOPQRSTUVWXYZ012345678
36 s = _WORDWRAP_HYPHEN_BEFORE_RE.sub("-", s) 1cdefghijklmnopqrstuvwxyzABCaDEFGbHIJKLMNOPQRSTUVWXYZ012345678
37 return s 1cdefghijklmnopqrstuvwxyzABCaDEFGbHIJKLMNOPQRSTUVWXYZ012345678
40def clean_enum_member_docstring(doc: str | None) -> str | None:
41 """Turn an enum member ``__doc__`` into plain text.
43 The generated enum docstrings are already close to user-facing prose, but
44 they may contain Sphinx inline roles, line wrapping, or a small known
45 codegen defect. Normalize only those differences so the text is suitable
46 for error messages.
47 """
48 if doc is None: 1cdefghijklmnopqrstuvwxyzABCaDEFGbHIJKLMNOPQRSTUVWXYZ012345678#
49 return None 1#
50 s = doc 1cdefghijklmnopqrstuvwxyzABCaDEFGbHIJKLMNOPQRSTUVWXYZ012345678
51 # Known codegen bug on cudaErrorIncompatibleDriverContext. Remove once fixed
52 # in cuda-bindings code generation.
53 s = s.replace("\n:py:obj:`~.Interactions`", ' "Interactions ') 1cdefghijklmnopqrstuvwxyzABCaDEFGbHIJKLMNOPQRSTUVWXYZ012345678
54 # Drop a leading "~." or "." after removing the surrounding RST inline role.
55 s = _RST_INLINE_ROLE_RE.sub(lambda m: re.sub(r"^~?\.", "", m.group(1)), s) 1cdefghijklmnopqrstuvwxyzABCaDEFGbHIJKLMNOPQRSTUVWXYZ012345678
56 # Strip simple bold emphasis markers.
57 s = re.sub(r"\*\*([^*]+)\*\*", r"\1", s) 1cdefghijklmnopqrstuvwxyzABCaDEFGbHIJKLMNOPQRSTUVWXYZ012345678
58 # Strip simple italic emphasis markers.
59 s = re.sub(r"\*([^*]+)\*", r"\1", s) 1cdefghijklmnopqrstuvwxyzABCaDEFGbHIJKLMNOPQRSTUVWXYZ012345678
60 # Collapse wrapped lines and repeated spaces.
61 s = re.sub(r"\s+", " ", s).strip() 1cdefghijklmnopqrstuvwxyzABCaDEFGbHIJKLMNOPQRSTUVWXYZ012345678
62 s = _fix_hyphenation_wordwrap_spacing(s) 1cdefghijklmnopqrstuvwxyzABCaDEFGbHIJKLMNOPQRSTUVWXYZ012345678
63 return s 1cdefghijklmnopqrstuvwxyzABCaDEFGbHIJKLMNOPQRSTUVWXYZ012345678
66class DocstringBackedExplanations:
67 """Expose enum-member ``__doc__`` text via ``dict.get``.
69 Keeps the ``.get(int(error))`` lookup shape used by ``cuda_utils.pyx``.
70 """
72 __slots__ = ("_enum_type",)
74 def __init__(self, enum_type: Any) -> None:
75 self._enum_type = enum_type 19!
77 def get(self, code: int, default: str | None = None) -> str | None:
78 try: 1cdefghijklmnopqrstuvwxyzABCaDEFGbHIJKLMNOPQRS9!
79 member = self._enum_type(code) 1cdefghijklmnopqrstuvwxyzABCaDEFGbHIJKLMNOPQRS9!
80 except ValueError: 1!
81 return default 1!
83 raw_doc = member.__doc__ 1cdefghijklmnopqrstuvwxyzABCaDEFGbHIJKLMNOPQRS9
84 if raw_doc is None: 1cdefghijklmnopqrstuvwxyzABCaDEFGbHIJKLMNOPQRS9
85 return default 1ab9
87 return clean_enum_member_docstring(raw_doc) 1cdefghijklmnopqrstuvwxyzABCaDEFGbHIJKLMNOPQRS