mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
added findmethodinchain and methodchain data types
This commit is contained in:
parent
5279ec683a
commit
6978503235
3 changed files with 60 additions and 23 deletions
|
@ -57,6 +57,14 @@ extern PyObject *PyCFunction_New
|
||||||
/* Flag passed to newmethodobject */
|
/* Flag passed to newmethodobject */
|
||||||
#define METH_VARARGS 0x0001
|
#define METH_VARARGS 0x0001
|
||||||
|
|
||||||
|
typedef struct PyMethodChain {
|
||||||
|
PyMethodDef *methods; /* Methods of this type */
|
||||||
|
struct PyMethodChain *link; /* NULL or base type */
|
||||||
|
} PyMethodChain;
|
||||||
|
|
||||||
|
extern PyObject *Py_FindMethodInChain
|
||||||
|
Py_PROTO((PyMethodChain *, PyObject *, char *));
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -38,6 +38,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
/* typedef ANY *PyUnivPtr; */
|
/* typedef ANY *PyUnivPtr; */
|
||||||
#define methodlist PyMethodDef
|
#define methodlist PyMethodDef
|
||||||
|
#define methodchain PyMethodChain
|
||||||
|
|
||||||
#define None Py_None
|
#define None Py_None
|
||||||
#define False Py_False
|
#define False Py_False
|
||||||
|
@ -290,6 +291,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#define newrangeobject PyRange_New
|
#define newrangeobject PyRange_New
|
||||||
#define method PyCFunction
|
#define method PyCFunction
|
||||||
#define findmethod Py_FindMethod
|
#define findmethod Py_FindMethod
|
||||||
|
#define findmethodinchain Py_FindMethodInChain
|
||||||
#define getmethod PyCFunction_GetFunction
|
#define getmethod PyCFunction_GetFunction
|
||||||
#define getself PyCFunction_GetSelf
|
#define getself PyCFunction_GetSelf
|
||||||
#define getvarargs PyCFunction_IsVarArgs
|
#define getvarargs PyCFunction_IsVarArgs
|
||||||
|
|
|
@ -188,46 +188,73 @@ typeobject Methodtype = {
|
||||||
(hashfunc)meth_hash, /*tp_hash*/
|
(hashfunc)meth_hash, /*tp_hash*/
|
||||||
};
|
};
|
||||||
|
|
||||||
static object *listmethods PROTO((struct methodlist *)); /* Forward */
|
/* List all methods in a chain -- helper for findmethodinchain */
|
||||||
|
|
||||||
static object *
|
static object *
|
||||||
listmethods(ml)
|
listmethodchain(chain)
|
||||||
struct methodlist *ml;
|
struct methodchain *chain;
|
||||||
{
|
{
|
||||||
|
struct methodchain *c;
|
||||||
|
struct methodlist *ml;
|
||||||
int i, n;
|
int i, n;
|
||||||
object *v;
|
object *v;
|
||||||
for (n = 0; ml[n].ml_name != NULL; n++)
|
|
||||||
;
|
n = 0;
|
||||||
|
for (c = chain; c != NULL; c = c->link) {
|
||||||
|
for (ml = c->methods; ml->ml_name != NULL; ml++)
|
||||||
|
n++;
|
||||||
|
}
|
||||||
v = newlistobject(n);
|
v = newlistobject(n);
|
||||||
if (v != NULL) {
|
if (v == NULL)
|
||||||
for (i = 0; i < n; i++)
|
return NULL;
|
||||||
setlistitem(v, i, newstringobject(ml[i].ml_name));
|
i = 0;
|
||||||
if (err_occurred()) {
|
for (c = chain; c != NULL; c = c->link) {
|
||||||
DECREF(v);
|
for (ml = c->methods; ml->ml_name != NULL; ml++) {
|
||||||
v = NULL;
|
setlistitem(v, i, newstringobject(ml->ml_name));
|
||||||
}
|
i++;
|
||||||
else {
|
|
||||||
sortlist(v);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (err_occurred()) {
|
||||||
|
DECREF(v);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
sortlist(v);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find a method in a module's method table.
|
/* Find a method in a method chain */
|
||||||
Usually called from an object's getattr method. */
|
|
||||||
|
|
||||||
object *
|
object *
|
||||||
findmethod(ml, op, name)
|
findmethodinchain(chain, self, name)
|
||||||
struct methodlist *ml;
|
struct methodchain *chain;
|
||||||
object *op;
|
object *self;
|
||||||
char *name;
|
char *name;
|
||||||
{
|
{
|
||||||
if (strcmp(name, "__methods__") == 0)
|
if (strcmp(name, "__methods__") == 0)
|
||||||
return listmethods(ml);
|
return listmethodchain(chain);
|
||||||
for (; ml->ml_name != NULL; ml++) {
|
while (chain != NULL) {
|
||||||
if (strcmp(name, ml->ml_name) == 0)
|
struct methodlist *ml = chain->methods;
|
||||||
return newmethodobject(ml, op);
|
for (; ml->ml_name != NULL; ml++) {
|
||||||
|
if (name[0] == ml->ml_name[0] &&
|
||||||
|
strcmp(name+1, ml->ml_name+1) == 0)
|
||||||
|
return newmethodobject(ml, self);
|
||||||
|
}
|
||||||
|
chain = chain->link;
|
||||||
}
|
}
|
||||||
err_setstr(AttributeError, name);
|
err_setstr(AttributeError, name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find a method in a single method list */
|
||||||
|
|
||||||
|
object *
|
||||||
|
findmethod(methods, self, name)
|
||||||
|
struct methodlist *methods;
|
||||||
|
object *self;
|
||||||
|
char *name;
|
||||||
|
{
|
||||||
|
struct methodchain chain;
|
||||||
|
chain.methods = methods;
|
||||||
|
chain.link = NULL;
|
||||||
|
return findmethodinchain(&chain, self, name);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue