Summary
Program.__dealloc__ (cuda_core/cuda/core/_program.pyx:103) always calls _cleanup_debug_source(), which unconditionally reads self._options._name (line 111). self._options is only assigned inside _init at line 867. If a Program object is garbage-collected after __cinit__/__new__ but before that assignment runs — for example an exception raised during construction — self._options is still None, and _cleanup_debug_source raises AttributeError: 'NoneType' object has no attribute '_name' from inside __dealloc__. Since __dealloc__ cannot propagate an exception, this surfaces as an unraisable exception via sys.unraisablehook.
Evidence
Seen in CI as a PytestUnraisableExceptionWarning from test_program_compile_cache.py:
Exception ignored in: Program.__dealloc__
AttributeError: 'NoneType' object has no attribute '_name'
First noticed while reviewing warnings surfaced by #2759's new reporting channel; the bug predates that PR.
Suggested fix
Guard the access: if self._nvrtc_name is not None and self._options is not None and self._nvrtc_name != self._options._name:. Worth checking whether other fields __dealloc__/_cleanup_debug_source touch have the same partial-construction gap.
Refs: found during review of #2759.
Summary
Program.__dealloc__(cuda_core/cuda/core/_program.pyx:103) always calls_cleanup_debug_source(), which unconditionally readsself._options._name(line 111).self._optionsis only assigned inside_initat line 867. If aProgramobject is garbage-collected after__cinit__/__new__but before that assignment runs — for example an exception raised during construction —self._optionsis stillNone, and_cleanup_debug_sourceraisesAttributeError: 'NoneType' object has no attribute '_name'from inside__dealloc__. Since__dealloc__cannot propagate an exception, this surfaces as an unraisable exception viasys.unraisablehook.Evidence
Seen in CI as a
PytestUnraisableExceptionWarningfromtest_program_compile_cache.py:First noticed while reviewing warnings surfaced by #2759's new reporting channel; the bug predates that PR.
Suggested fix
Guard the access:
if self._nvrtc_name is not None and self._options is not None and self._nvrtc_name != self._options._name:. Worth checking whether other fields__dealloc__/_cleanup_debug_sourcetouch have the same partial-construction gap.Refs: found during review of #2759.