-
-
Notifications
You must be signed in to change notification settings - Fork 30.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
3.12.0b1 includes backwards incompatible change to operation of super()
#105035
Comments
Reduced test case class MyInstance(type):
pass
def test(name):
self = MyInstance(name, (MyInstance,), {})
super(MyInstance, type(self)).__setattr__(self, name, 1)
test("call1")
test("call2") # <-- only at the second call |
Also, note the following passes. So it's definitely related to the interpreter core. class MyInstance(type):
pass
def test(name):
self = MyInstance(name, (MyInstance,), {})
m = super(MyInstance, type(self)).__setattr__
m(self, name, id(name))
test("call1")
test("call2") |
The C call frame when the Details
From the C side, it seems that |
The comment of
And confirmed that in the latter case, the stack is
But it should be NULL? We can dis this function, and we get
must have something to do with this. |
Thanks @freakboy3742, and @sunmy2019 for the simplified repro! I've identified the issue and working on a PR to fix. Just for the record (and only because it confused me a bit until I double-checked), my testing shows that this wasn't broken by #104270, it was broken by the original introduction of |
…pythonGH-105094) (cherry picked from commit 68c75c3) Co-authored-by: Carl Meyer <carl@oddbird.net>
This should be fixed now, in both 3.12 and main. Thanks for the report! |
Confirming this is now working for me. Thanks for the fast turnaround, @carljm! |
Bug report
The optimisation to LOAD_SUPER_ATTR introduced by #104270 appears to have introduced a backwards incompatibility.
The following code will reproduce the problem:
Under 3.12.0a7 (and previous stable Python versions going back to at least 3.7), this will succeed, outputting:
Under 3.12.0b1, it raises an error:
That is - the first
MyClass
instance can be instantiated; however, the second instance fails in mid-construction when invoking__setattr__
. The state of the objects prior to the__setattr__
invocation appear to be identical, but the__setattr__
method behaves differently on the second invocation.Git bisect has narrowed the cause down to #104270 (CC @carljm, @markshannon).
The reproduction case also fails if the call to
super
:is replaced with the simpler:
Background
This test case has been extracted from rubicon-objc, causing beeware/rubicon-objc#313. Rubicon is a wrapper around the Objective C runtime used by macOS and iOS;
MyInstance
is an analog ofObjCInstance
, andMyClass
is a an analog ofObjCClass
.ObjCInstance
has an implementation of__setattr__
to redirect attribute access to the underlying ObjC calls. However, during construction,ObjCInstance
needs to store aptr
of the underlying ObjC instance. This isn't a valid ObjC attribute, sosuper()
is used to access the underlying__setattr__
implementation to set the attribute.Your environment
Linked PRs
The text was updated successfully, but these errors were encountered: