Comportements erratiques avec tp_attr : Effets de bord de Py_FindMethod ?
Bonjour,
J'ai un petit problème avec l'API C de python 2.4 : j'observe un comportement bizarre que je pense être du à Py_FindMethod. Je m'explique en simplifiant volontairement tout ce qui est inutile :
J'ai un objet typé (Type Object) monObjet qui possède un PyMethodDef qui référence une méthode summary.
Si je ne met aucun getAttr (tp_getattr = 0), tout marche normalement en python :
Code:
1 2 3 4 5
|
>>> import monModule
>>> m = monModule.monObjet(...)
>>> m.summary()
Bonjour monde ! |
Je décide de complexifier les choses en ajoutant une méthode getAttr :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
static PyObject* monObjet_getAttr(PyObject* self, char *attr_name) {
// quelques casts importants
monObjet_Object* selfc = (monObjet_Object*) self;
std::string str_attr_name = std::string(attr_name);
if(str_attr_name=="type") {
PyObject* result = PyInt_FromLong(12);
Py_XINCREF(result);
return result;
}
PyErr_SetString(PyExc_AttributeError,(char*)"Attribut inconnu");
return NULL;
} |
Problème : ma méthode "summary" est cachée :
Code:
1 2 3 4 5 6
|
>>> m = monModule.monObjet(...)
>>> m.summary()
AttributeError: Attribut inconnu
>>> m.type
12 |
Il faut donc définir un Py_FindMethod dans le getAttr pour dire au module d'explorer aussi ma liste de méthode :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
static PyObject* monObjet_getAttr(PyObject* self, char *attr_name) {
// quelques casts importants
monObjet_Object* selfc = (monObjet_Object*) self;
std::string str_attr_name = std::string(attr_name);
// On cherche dans les méthodes existantes
PyObject* func = Py_FindMethod(monObjet_methods,self,attr_name);
if (func!=NULL) {
return func;
}
// Sinon...
if(str_attr_name=="type") {
PyObject* result = PyInt_FromLong(12);
Py_XINCREF(result);
return result;
}
PyErr_SetString(PyExc_AttributeError,(char*)"Attribut inconnu");
return NULL;
} |
A ce moment, ma méthode passe mais type ne passe.... q'une fois sur deux 8O 8O
Et attention, quand je dis 1 fois sur 2, c'est avec la régularité d'un métronome !
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
>>> P.type
12
>>> P.type
AttributeError: type
>>> P.type
12
>>> P.type
AttributeError: type
>>> P.type
12
>>> P.type
AttributeError: type |
Je tente donc de commenter le bloc if (func!=NULL)... , le problème subsiste. Il existe donc un effet de bord créé par Py_FindMethod que je suis incapable de comprendre (ou alors j'ai fait une grave faute conceptuelle quelque part).
Merci d'avance pour toute aide !