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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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
Et attention, quand je dis 1 fois sur 2, c'est avec la régularité d'un métronome !

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 !