You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Zero argument super is broken in 3.6 for methods with a hacked __class__ cell #76357
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=<Date2017-12-03.13:36:10.122>created_at=<Date2017-11-30.07:39:34.993>labels= ['interpreter-core', 'type-bug', '3.7']
title='Zero argument super is broken in 3.6 for methods with a hacked __class__ cell'updated_at=<Date2017-12-03.13:36:10.120>user='https://github.com/mr-nfamous'
The hacked cell object using this method appears to be changed to NULL when accessed by frame.f_localsplus. I don't know C well enough to find out what's happening because nothing looks different to me in PyFrame_FastToLocalsWithError.
Also creating a closure with:
from ctypes import pythonapi, py_object
So while CO_NOFREE is set in all versions with the example code, it appears only python 3.6 recognizes that flag and disallows the accessing of the __class__ cell. In this case the error message is bad because it implies that the __class__ cell is the wrong type. Disabling the flag when creating the code objects allows the above code to work.
Given that, I'd say the way to cleanest way to fix this would be to remove these lines from "compute_code_flags" in compile.c:
if (!PyDict_GET_SIZE(c->u->u_freevars) &&
!PyDict_GET_SIZE(c->u->u_cellvars)) {
flags |= CO_NOFREE;
}
and replace them with a check like the following in PyCode_New just after we ensure the Unicode string for the filename is ready:
if (!PyTuple_GET_SIZE(freevars) &&
!PyTuple_GET_SIZE(cellvars)) {
flags |= CO_NOFREE;
}
That way CO_NOFREE will be set only when appropriate regardless of how the code object is created, rather than relying on the caller to set it correctly.
Activity
mr-nfamous commentedon Nov 30, 2017
The following code works in 3.3, 3.4, and 3.5, but in 3.6 it throws RuntimeError: super(): bad __class__ cell.
mr-nfamous commentedon Nov 30, 2017
The hacked cell object using this method appears to be changed to NULL when accessed by frame.f_localsplus. I don't know C well enough to find out what's happening because nothing looks different to me in PyFrame_FastToLocalsWithError.
Also creating a closure with:
from ctypes import pythonapi, py_object
doesn't solve this either.
mr-nfamous commentedon Dec 1, 2017
So while CO_NOFREE is set in all versions with the example code, it appears only python 3.6 recognizes that flag and disallows the accessing of the __class__ cell. In this case the error message is bad because it implies that the __class__ cell is the wrong type. Disabling the flag when creating the code objects allows the above code to work.
ncoghlan commentedon Dec 2, 2017
Given that, I'd say the way to cleanest way to fix this would be to remove these lines from "compute_code_flags" in compile.c:
and replace them with a check like the following in PyCode_New just after we ensure the Unicode string for the filename is ready:
That way CO_NOFREE will be set only when appropriate regardless of how the code object is created, rather than relying on the caller to set it correctly.
ncoghlan commentedon Dec 3, 2017
New changeset 078f181 by Nick Coghlan in branch 'master':
bpo-32176: Set CO_NOFREE in the code object constructor (GH-4675)
078f181
ncoghlan commentedon Dec 3, 2017
New changeset c8f32aa by Nick Coghlan in branch '3.6':
[3.6] bpo-32176: Set CO_NOFREE in the code object constructor (GH-4684)
c8f32aa
ncoghlan commentedon Dec 3, 2017
Thanks for the issue report! The fix will be released in 3.6.4 and 3.7.0a3 (both of which are expected to be later this month).