Skip to content

Commit 81cfdee

Browse files
authored
feat(cython): Hide C++ stacktrace by default (#70)
This PR introduces an environment variable `MLC_SHOW_CPP_STACKTRACES`, which controls if CXX-side stacktrace is included when an exception is thrown. It's turned on only if it's value is `1`. It means C++ stacktrace is hidden by default. Should fix #68.
1 parent 04be216 commit 81cfdee

File tree

4 files changed

+37
-3
lines changed

4 files changed

+37
-3
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ env:
55
CIBW_BUILD_VERBOSITY: 3
66
CIBW_TEST_REQUIRES: "pytest torch"
77
CIBW_TEST_COMMAND: "pytest -svv --durations=20 {project}/tests/python/"
8+
CIBW_ENVIRONMENT: "MLC_SHOW_CPP_STACKTRACES=1"
89
MLC_CIBW_VERSION: "2.22.0"
910
MLC_PYTHON_VERSION: "3.9"
1011
MLC_CIBW_WIN_BUILD: "cp39-win_amd64"

python/mlc/_cython/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
)
2828
from .core import ( # type: ignore[import-not-found]
2929
container_to_py,
30+
cxx_stacktrace_enabled,
3031
device_as_pair,
3132
dtype_as_triple,
3233
dtype_from_triple,
@@ -50,6 +51,7 @@
5051
tensor_shape,
5152
tensor_strides,
5253
tensor_to_dlpack,
54+
toggle_cxx_stacktrace,
5355
type_add_method,
5456
type_cast,
5557
type_create,

python/mlc/_cython/core.pyx

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# cython: language_level=3
22
import ctypes
33
import itertools
4+
import os
45
from libcpp.vector cimport vector
56
from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, uint8_t, uint16_t, uint32_t, uint64_t
67
from libc.stdlib cimport malloc, free
@@ -407,7 +408,13 @@ cdef class PyAny:
407408
func = _vtable_get_func_ptr(vtable, type_index, True)
408409
except Exception as e: # no-cython-lint
409410
raise TypeError(f"Cannot find method `{name}` for type: {cls}") from e
410-
_func_call_impl(func, args, &c_ret)
411+
if CXX_STACKTRACE_ENABLED:
412+
_func_call_impl(func, args, &c_ret)
413+
else:
414+
try:
415+
_func_call_impl(func, args, &c_ret)
416+
except Exception as e: # no-cython-lint
417+
raise e.with_traceback(None)
411418
return _any_c2py_no_inc_ref(c_ret)
412419

413420
cdef class Str(str):
@@ -1699,6 +1706,16 @@ cpdef list type_table():
16991706
return list(TYPE_INDEX_TO_INFO)
17001707

17011708

1709+
cpdef void toggle_cxx_stacktrace(bint enable):
1710+
global CXX_STACKTRACE_ENABLED
1711+
CXX_STACKTRACE_ENABLED = enable
1712+
1713+
1714+
cpdef bint cxx_stacktrace_enabled():
1715+
global CXX_STACKTRACE_ENABLED
1716+
return CXX_STACKTRACE_ENABLED
1717+
1718+
17021719
cdef const char* _DLPACK_CAPSULE_NAME = "dltensor"
17031720
cdef const char* _DLPACK_CAPSULE_NAME_USED = "used_dltensor"
17041721
cdef const char* _DLPACK_CAPSULE_NAME_VER = "dltensor_versioned"
@@ -1735,3 +1752,4 @@ cdef MLCFunc* _OPAQUE_INIT = _vtable_get_func_ptr(_VTABLE_INIT, kMLCOpaque, Fals
17351752
cdef MLCFunc* _TENSOR_INIT = _vtable_get_func_ptr(_vtable_get_global(b"__init_DLManagedTensor"), kMLCTensor, False)
17361753
cdef MLCFunc* _TENSOR_INIT_VER = _vtable_get_func_ptr(_vtable_get_global(b"__init_DLManagedTensorVersioned"), kMLCTensor, False) # no-cython-lint
17371754
cdef tuple _OPAQUE_TYPES = ()
1755+
cdef bint CXX_STACKTRACE_ENABLED = os.environ.get("MLC_SHOW_CPP_STACKTRACES", "0") == "1"

python/mlc/core/func.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,14 @@
33
from collections.abc import Callable
44
from typing import Any, TypeVar
55

6-
from mlc._cython import c_class_core, func_call, func_get, func_init, func_register
6+
from mlc._cython import (
7+
c_class_core,
8+
cxx_stacktrace_enabled,
9+
func_call,
10+
func_get,
11+
func_init,
12+
func_register,
13+
)
714

815
from .object import Object
916

@@ -17,7 +24,13 @@ def __init__(self, func: Callable) -> None:
1724
func_init(self, func)
1825

1926
def __call__(self, *args: Any) -> Any:
20-
return func_call(self, args)
27+
if cxx_stacktrace_enabled():
28+
return func_call(self, args)
29+
else:
30+
try:
31+
return func_call(self, args)
32+
except Exception as e:
33+
raise e.with_traceback(None)
2134

2235
@staticmethod
2336
def get(name: str, allow_missing: bool = False) -> Func:

0 commit comments

Comments
 (0)