Coverage for cuda/core/_utils/enum_explanations_helpers.py: 67.57%

37 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-10-16 01:23 +0000

1# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 

2# SPDX-License-Identifier: Apache-2.0 

3 

4"""Internal support for error-enum explanations. 

5 

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. 

11 

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""" 

15 

16from __future__ import annotations 

17 

18import re 

19from typing import Any 

20 

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_])") 

24 

25 

26def _fix_hyphenation_wordwrap_spacing(s: str) -> str: 

27 """Remove spaces around hyphens introduced by line wrapping in generated ``__doc__`` text. 

28 

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 1bcdefghijklmnopqrstuvwxyzABaCDEFGHIJKLMNOPQRSTUVWXYZ0123

33 while prev != s: 1bcdefghijklmnopqrstuvwxyzABaCDEFGHIJKLMNOPQRSTUVWXYZ0123

34 prev = s 1bcdefghijklmnopqrstuvwxyzABaCDEFGHIJKLMNOPQRSTUVWXYZ0123

35 s = _WORDWRAP_HYPHEN_AFTER_RE.sub("-", s) 1bcdefghijklmnopqrstuvwxyzABaCDEFGHIJKLMNOPQRSTUVWXYZ0123

36 s = _WORDWRAP_HYPHEN_BEFORE_RE.sub("-", s) 1bcdefghijklmnopqrstuvwxyzABaCDEFGHIJKLMNOPQRSTUVWXYZ0123

37 return s 1bcdefghijklmnopqrstuvwxyzABaCDEFGHIJKLMNOPQRSTUVWXYZ0123

38 

39 

40def clean_enum_member_docstring(doc: str | None) -> str | None: 

41 """Turn an enum member ``__doc__`` into plain text. 

42 

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: 1bcdefghijklmnopqrstuvwxyzABaCDEFGHIJKLMNOPQRSTUVWXYZ01236

49 return None 16

50 s = doc 1bcdefghijklmnopqrstuvwxyzABaCDEFGHIJKLMNOPQRSTUVWXYZ0123

51 # Known codegen bug on cudaErrorIncompatibleDriverContext. Remove once fixed 

52 # in cuda-bindings code generation. 

53 s = s.replace("\n:py:obj:`~.Interactions`", ' "Interactions ') 1bcdefghijklmnopqrstuvwxyzABaCDEFGHIJKLMNOPQRSTUVWXYZ0123

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) 1bcdefghijklmnopqrstuvwxyzABaCDEFGHIJKLMNOPQRSTUVWXYZ0123

56 # Strip simple bold emphasis markers. 

57 s = re.sub(r"\*\*([^*]+)\*\*", r"\1", s) 1bcdefghijklmnopqrstuvwxyzABaCDEFGHIJKLMNOPQRSTUVWXYZ0123

58 # Strip simple italic emphasis markers. 

59 s = re.sub(r"\*([^*]+)\*", r"\1", s) 1bcdefghijklmnopqrstuvwxyzABaCDEFGHIJKLMNOPQRSTUVWXYZ0123

60 # Collapse wrapped lines and repeated spaces. 

61 s = re.sub(r"\s+", " ", s).strip() 1bcdefghijklmnopqrstuvwxyzABaCDEFGHIJKLMNOPQRSTUVWXYZ0123

62 s = _fix_hyphenation_wordwrap_spacing(s) 1bcdefghijklmnopqrstuvwxyzABaCDEFGHIJKLMNOPQRSTUVWXYZ0123

63 return s 1bcdefghijklmnopqrstuvwxyzABaCDEFGHIJKLMNOPQRSTUVWXYZ0123

64 

65 

66class DocstringBackedExplanations: 

67 """Expose enum-member ``__doc__`` text via ``dict.get``. 

68 

69 Keeps the ``.get(int(error))`` lookup shape used by ``cuda_utils.pyx``. 

70 """ 

71 

72 __slots__ = ("_enum_type",) 

73 

74 def __init__(self, enum_type: Any) -> None: 

75 self._enum_type = enum_type 145

76 

77 def get(self, code: int, default: str | None = None) -> str | None: 

78 try: 1bcdefghijklmnopqrstuvwxyzABaCDEFGHIJKLMN45

79 member = self._enum_type(code) 1bcdefghijklmnopqrstuvwxyzABaCDEFGHIJKLMN45

80 except ValueError: 15

81 return default 15

82 

83 raw_doc = member.__doc__ 1bcdefghijklmnopqrstuvwxyzABaCDEFGHIJKLMN4

84 if raw_doc is None: 1bcdefghijklmnopqrstuvwxyzABaCDEFGHIJKLMN4

85 return default 1a4

86 

87 return clean_enum_member_docstring(raw_doc) 1bcdefghijklmnopqrstuvwxyzABaCDEFGHIJKLMN