Several built-in exceptions store their attributes in the instance dict instead of as fields · Issue #8345 · RustPython/RustPython · GitHub
Skip to content

Several built-in exceptions store their attributes in the instance dict instead of as fields #8345

Description

@kangdora

Feature

Several built-in exceptions store their attributes in the instance __dict__ instead of as struct fields, so Exc().__dict__ is non-empty (unlike CPython) and the attributes are not backed by descriptors. SystemExit.code (#8230 / #8282) and StopIteration.value (#8290 / #8301) have been converted already; this issue tracks the rest.

Measured against CPython 3.14.6 (print(exc.__dict__)):

exception leaked into __dict__ CPython
NameError('m', name='x') {'name': 'x'} {}
AttributeError('m') {'name': None, 'obj': None} {}
ImportError('m') {'name': None, 'path': None, 'name_from': None} {}
SyntaxError('m') {'print_file_and_line': None} {}
SyntaxError('m', (...)) + filename, lineno, offset, text {}
UnicodeDecodeError(...) {'encoding', 'object', 'start', 'end', 'reason'} {}
UnicodeEncodeError(...) same five fields {}
UnicodeTranslateError(...) {'object', 'start', 'end', 'reason'} {}

Their subclasses inherit the same problem (ModuleNotFoundError from ImportError; IndentationError / TabError / _IncompleteInputError from SyntaxError) and should be fixed automatically once the base is converted.

These are the remaining cases of the issue addressed in #8282 and #8301.
SyntaxError already carries a // TODO: members note for this.

Plan

Convert each to a struct field (#[repr(C)] + base field, exposed via #[pygetset]), following the approach established in #8282 and #8301, in separate PRs:

  1. NameError and AttributeError
    • Both are small and use a similar keyword-argument pattern.
  2. ImportError
    • ModuleNotFoundError will inherit the converted fields.
  3. UnicodeDecodeError, UnicodeEncodeError, and UnicodeTranslateError
    • These exceptions share most of their fields, similar to CPython's implementation.
  4. SyntaxError
    • This will also cover IndentationError, TabError, and _IncompleteInputError.
    • It is the largest conversion and will require checking the code paths that read these attributes.

Python Documentation or reference to CPython source code

https://docs.python.org/3/library/exceptions.html

These attributes are defined via PyMemberDef (struct members, not instance-dict entries) in CPython's Objects/exceptions.c.


Verified locally against CPython 3.14.6 and RustPython. AI was used to help organize the initial draft; the technical details and final wording were reviewed by me.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

C-compatA discrepancy between RustPython and CPython

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions