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
Here is info about the tp_dictoffset issue, and a solution at the end.
Test case.
frompygame.eventimportEvente=Event(1, asdf=22)
print(e)
asserte.dict.get('asdf') ==22, 'Getting a dict attribute works.'asserte.__dict__ise.dict, 'the __dict__ is the same as this e.dict'asserte.asdf==22, 'Fails... events use the e.dict to make the attributes available.'
>>>>e=Event(1, asdf=22)
>>>>print(e)
<Event(1-ActiveEvent {'asdf': 22})>>>>>asserte.dict.get('asdf') ==22, 'Getting a dict attribute works.'>>>>asserte.__dict__ise.dict, 'the __dict__ is the same as this e.dict'>>>>asserte.asdf==22, 'Fails... events use the e.dict to make the attributes available.'Traceback (mostrecentcalllast):
File"<stdin>", line1, in<module>AttributeError: 'Event'objecthasnoattribute'asdf'
where is the problem likely?
It overwrites the __dict__ variable of the object using tp_dictoffset(which pypy doesn't support at time of writing). See below.
It seems that tp_dictoffset is not used in pypy/module/cpyext/parse/cpyext_object.h
PyObject_GenericGetAttr is defined in pypy/pypy/module/cpyext/object.py in there is a comment saying that it looks at __dict__.
There are a few places where tp_members is used.
How we fix it
[17:48:59] <mattip> illume: I doubt we can support overriding __dict__, but what is the exact error message and who is generating it?
Make our own getter and setter which tries the dict first.
pg_EventGetAttr, /* tp_getattro /
pg_EventSetAttr, / tp_setattro */
Here is the getter and setter used to set the __dict__ as appropriate. From the #420 PR...
#ifdefPYPY_VERSION/* Because pypy does not work with the __dict__ tp_dictoffset. */PyObject*pg_EventGetAttr(PyObject*o, PyObject*attr_name) {
/* Try e->dict first, if not try the generic attribute. */PyObject*result=PyDict_GetItem(((PyEventObject*)o)->dict, attr_name);
if (!result) {
returnPyObject_GenericGetAttr(o, attr_name);
}
returnresult;
}
intpg_EventSetAttr(PyObject*o, PyObject*name, PyObject*value) {
/* if the variable is in the dict, deal with it there. else if it's a normal attribute set it there. else if it's not an attribute, or in the dict, set it in the dict. */intdictResult;
intsetInDict=0;
PyObject*result=PyDict_GetItem(((PyEventObject*)o)->dict, name);
if (result) {
setInDict=1;
} else {
result=PyObject_GenericGetAttr(o, name);
if (!result) {
setInDict=1;
}
}
if (setInDict) {
dictResult=PyDict_SetItem(((PyEventObject*)o)->dict, name, value);
if (dictResult) {
return-1;
}
return0;
} else {
returnPyObject_GenericSetAttr(o, name, value);
}
}
#endif
The text was updated successfully, but these errors were encountered:
Here is info about the tp_dictoffset issue, and a solution at the end.
Test case.
where is the problem likely?
It overwrites the
__dict__
variable of the object usingtp_dictoffset
(which pypy doesn't support at time of writing). See below.Relevant documentation and code
src/event.c
Python docs.
tp_dict
tp_dictoffset
PyObject_GenericGetAttr
From src/event.c the type definition. We see that the object uses the tp_dictoffset
Then we see that the event_members structure uses the same dict for
__dict__
.Here is the type definition: src/_pygame.h
pypy info
It seems that
tp_dictoffset
is not used in pypy/module/cpyext/parse/cpyext_object.hPyObject_GenericGetAttr is defined in pypy/pypy/module/cpyext/object.py in there is a comment saying that it looks at
__dict__
.There are a few places where tp_members is used.
How we fix it
Make our own getter and setter which tries the dict first.
pg_EventGetAttr, /* tp_getattro /
pg_EventSetAttr, / tp_setattro */
Here is the getter and setter used to set the
__dict__
as appropriate. From the #420 PR...The text was updated successfully, but these errors were encountered: