Summary
SystemExit.code is read-only in RustPython, but it is a writable member in CPython:
class MyExit(SystemExit):
pass
m = MyExit(1)
m.code = 42
# AttributeError: attribute 'code' of 'MyExit' objects is not writable
CPython 3.14.2 accepts the assignment (code is a PyMemberDef on SystemExit, i.e. a writable data descriptor; same as assigning on SystemExit itself). Verified on main @ 7044fdc.
Note the neighboring exception members are already correct — e.g. OSError().errno = 5 works — it's specifically SystemExit.code that was made read-only.
Cause
crates/vm/src/exceptions.rs:965:
"code" => ctx.new_readonly_getset("code", excs.system_exit, system_exit_code),
Should be a getset with a setter (or member-style storage) writing through to the instance, like the errno/filename/etc. attributes on OSError. sys.exit()/SystemExit.__init__ derive code from args, and CPython keeps code as an independent writable slot after construction.
Found while running synthetic benchmark/compat suites; researched and reported by Claude on behalf of @youknowone.
Summary
SystemExit.codeis read-only in RustPython, but it is a writable member in CPython:CPython 3.14.2 accepts the assignment (
codeis aPyMemberDefonSystemExit, i.e. a writable data descriptor; same as assigning onSystemExititself). Verified onmain@ 7044fdc.Note the neighboring exception members are already correct — e.g.
OSError().errno = 5works — it's specificallySystemExit.codethat was made read-only.Cause
crates/vm/src/exceptions.rs:965:Should be a getset with a setter (or member-style storage) writing through to the instance, like the
errno/filename/etc. attributes onOSError.sys.exit()/SystemExit.__init__derivecodefromargs, and CPython keepscodeas an independent writable slot after construction.Found while running synthetic benchmark/compat suites; researched and reported by Claude on behalf of @youknowone.