From 3c4bfd1dec28ffbefc6379dedeaa24feaa2ef373 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 20 Apr 2021 17:11:13 +1000 Subject: py/objexcept: Support errno attribute on OSError exceptions. This commit adds the errno attribute to exceptions, so code can retrieve errno codes from an OSError using exc.errno. The implementation here simply lets `errno` (and the existing `value`) attributes work on any exception instance (they both alias args[0]). This is for efficiency and to keep code size down. The pros and cons of this are: Pros: - more compatible with CPython, less difference to document and learn - OSError().errno will correctly return None, whereas the current way of doing it via OSError().args[0] will raise an IndexError - it reduces code size on most bare-metal ports (because they already have the errno qstr) - for Python code that uses exc.errno the generated bytecode is 2 bytes smaller and more efficient to execute (compared with exc.args[0]); so bytecode loaded to RAM saves 2 bytes RAM for each use of this attribute, and bytecode that is frozen saves 2 bytes flash/ROM for each use - it's easier/shorter to type, and saves 2 bytes of space in .py files that use it (for each use) Cons: - increases code size by 4-8 bytes on minimal ports that don't already have the `errno` qstr - all exceptions now have .errno and .value attributes (a cpydiff test is added to address this) See also #2407. Signed-off-by: Damien George --- py/objexcept.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'py/objexcept.c') diff --git a/py/objexcept.c b/py/objexcept.c index 885032c3e..f6bffec38 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -261,7 +261,9 @@ void mp_obj_exception_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { if (attr == MP_QSTR_args) { decompress_error_text_maybe(self); dest[0] = MP_OBJ_FROM_PTR(self->args); - } else if (self->base.type == &mp_type_StopIteration && attr == MP_QSTR_value) { + } else if (attr == MP_QSTR_value || attr == MP_QSTR_errno) { + // These are aliases for args[0]: .value for StopIteration and .errno for OSError. + // For efficiency let these attributes apply to all exception instances. dest[0] = mp_obj_exception_get_value(self_in); } } -- cgit v1.2.3