summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--py/objexcept.c27
-rw-r--r--tests/basics/subclass_native3.py20
2 files changed, 33 insertions, 14 deletions
diff --git a/py/objexcept.c b/py/objexcept.c
index a10bd2c187..b4f5018c06 100644
--- a/py/objexcept.c
+++ b/py/objexcept.c
@@ -111,6 +111,15 @@ mp_obj_t mp_alloc_emergency_exception_buf(mp_obj_t size_in) {
#endif
#endif // MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF
+STATIC mp_obj_exception_t *get_native_exception(mp_obj_t self_in) {
+ assert(mp_obj_is_exception_instance(self_in));
+ if (mp_obj_is_native_exception_instance(self_in)) {
+ return MP_OBJ_TO_PTR(self_in);
+ } else {
+ return MP_OBJ_TO_PTR(((mp_obj_instance_t *)MP_OBJ_TO_PTR(self_in))->subobj[0]);
+ }
+}
+
STATIC void decompress_error_text_maybe(mp_obj_exception_t *o) {
#if MICROPY_ROM_TEXT_COMPRESSION
if (o->args->len == 1 && mp_obj_is_type(o->args->items[0], &mp_type_str)) {
@@ -240,7 +249,7 @@ mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type, size_t n_args, siz
// Get exception "value" - that is, first argument, or None
mp_obj_t mp_obj_exception_get_value(mp_obj_t self_in) {
- mp_obj_exception_t *self = MP_OBJ_TO_PTR(self_in);
+ mp_obj_exception_t *self = get_native_exception(self_in);
if (self->args->len == 0) {
return mp_const_none;
} else {
@@ -559,25 +568,15 @@ bool mp_obj_exception_match(mp_obj_t exc, mp_const_obj_t exc_type) {
// traceback handling functions
-#define GET_NATIVE_EXCEPTION(self, self_in) \
- /* make sure self_in is an exception instance */ \
- assert(mp_obj_is_exception_instance(self_in)); \
- mp_obj_exception_t *self; \
- if (mp_obj_is_native_exception_instance(self_in)) { \
- self = MP_OBJ_TO_PTR(self_in); \
- } else { \
- self = MP_OBJ_TO_PTR(((mp_obj_instance_t *)MP_OBJ_TO_PTR(self_in))->subobj[0]); \
- }
-
void mp_obj_exception_clear_traceback(mp_obj_t self_in) {
- GET_NATIVE_EXCEPTION(self, self_in);
+ mp_obj_exception_t *self = get_native_exception(self_in);
// just set the traceback to the null object
// we don't want to call any memory management functions here
self->traceback_data = NULL;
}
void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, size_t line, qstr block) {
- GET_NATIVE_EXCEPTION(self, self_in);
+ mp_obj_exception_t *self = get_native_exception(self_in);
// append this traceback info to traceback data
// if memory allocation fails (eg because gc is locked), just return
@@ -630,7 +629,7 @@ void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, size_t line, qs
}
void mp_obj_exception_get_traceback(mp_obj_t self_in, size_t *n, size_t **values) {
- GET_NATIVE_EXCEPTION(self, self_in);
+ mp_obj_exception_t *self = get_native_exception(self_in);
if (self->traceback_data == NULL) {
*n = 0;
diff --git a/tests/basics/subclass_native3.py b/tests/basics/subclass_native3.py
index ac5aabfed7..0c45c4924f 100644
--- a/tests/basics/subclass_native3.py
+++ b/tests/basics/subclass_native3.py
@@ -34,6 +34,26 @@ print(MyStopIteration().value)
print(MyStopIteration(1).value)
+class Iter:
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ # This exception will stop the "yield from", with a value of 3
+ raise MyStopIteration(3)
+
+
+def gen():
+ print((yield from Iter()))
+ return 4
+
+
+try:
+ next(gen())
+except StopIteration as er:
+ print(er.args)
+
+
class MyOSError(OSError):
pass