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.

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