Commit 3a592876 authored by Jim Fulton's avatar Jim Fulton

Added support for function and method attributes.

parent 84741cb6
/* /*
$Id: ExtensionClass.c,v 1.15 1997/09/26 14:35:11 jim Exp $ $Id: ExtensionClass.c,v 1.16 1997/10/22 15:09:43 jim Exp $
Extension Class Extension Class
...@@ -65,7 +65,7 @@ static char ExtensionClass_module_documentation[] = ...@@ -65,7 +65,7 @@ static char ExtensionClass_module_documentation[] =
" - They provide access to unbound methods,\n" " - They provide access to unbound methods,\n"
" - They can be called to create instances.\n" " - They can be called to create instances.\n"
"\n" "\n"
"$Id: ExtensionClass.c,v 1.15 1997/09/26 14:35:11 jim Exp $\n" "$Id: ExtensionClass.c,v 1.16 1997/10/22 15:09:43 jim Exp $\n"
; ;
#include <stdio.h> #include <stdio.h>
...@@ -196,6 +196,7 @@ typedef struct { ...@@ -196,6 +196,7 @@ typedef struct {
PyCFunction meth; PyCFunction meth;
int flags; int flags;
char *doc; char *doc;
PyObject *dict;
} CMethod; } CMethod;
staticforward PyTypeObject CMethodType; staticforward PyTypeObject CMethodType;
...@@ -360,6 +361,7 @@ newCMethod(PyExtensionClass *type, PyObject *inst, ...@@ -360,6 +361,7 @@ newCMethod(PyExtensionClass *type, PyObject *inst,
self->meth=meth; self->meth=meth;
self->flags=flags; self->flags=flags;
self->doc=doc; self->doc=doc;
self->dict=NULL;
return (PyObject*)self; return (PyObject*)self;
} }
...@@ -387,6 +389,8 @@ bindCMethod(CMethod *m, PyObject *inst) ...@@ -387,6 +389,8 @@ bindCMethod(CMethod *m, PyObject *inst)
self->meth=m->meth; self->meth=m->meth;
self->flags=m->flags; self->flags=m->flags;
self->doc=m->doc; self->doc=m->doc;
self->dict=m->dict;
Py_XINCREF(self->dict);
return self; return self;
} }
...@@ -398,6 +402,7 @@ CMethod_dealloc(CMethod *self) ...@@ -398,6 +402,7 @@ CMethod_dealloc(CMethod *self)
#endif #endif
Py_XDECREF(self->type); Py_XDECREF(self->type);
Py_XDECREF(self->self); Py_XDECREF(self->self);
Py_XDECREF(self->dict);
PyMem_DEL(self); PyMem_DEL(self);
} }
...@@ -503,10 +508,15 @@ CMethod_call(CMethod *self, PyObject *args, PyObject *kw) ...@@ -503,10 +508,15 @@ CMethod_call(CMethod *self, PyObject *args, PyObject *kw)
} }
static PyObject * static PyObject *
CMethod_getattr(CMethod *self, char *name) CMethod_getattro(CMethod *self, PyObject *oname)
{ {
PyObject *r; PyObject *r;
if(PyString_Check(oname))
{
char *name;
UNLESS(name=PyString_AsString(oname)) return NULL;
if(strcmp(name,"__name__")==0 || strcmp(name,"func_name")==0 ) if(strcmp(name,"__name__")==0 || strcmp(name,"func_name")==0 )
return PyString_FromString(self->name); return PyString_FromString(self->name);
if(strcmp(name,"func_code")==0 || if(strcmp(name,"func_code")==0 ||
...@@ -516,7 +526,6 @@ CMethod_getattr(CMethod *self, char *name) ...@@ -516,7 +526,6 @@ CMethod_getattr(CMethod *self, char *name)
return (PyObject *)self; return (PyObject *)self;
} }
if(strcmp(name,"__doc__")==0 || if(strcmp(name,"__doc__")==0 ||
strcmp(name,"func_doc")==0 ||
strcmp(name,"func_doc")==0) strcmp(name,"func_doc")==0)
{ {
if(self->doc) if(self->doc)
...@@ -536,10 +545,22 @@ CMethod_getattr(CMethod *self, char *name) ...@@ -536,10 +545,22 @@ CMethod_getattr(CMethod *self, char *name)
Py_INCREF(r); Py_INCREF(r);
return r; return r;
} }
PyErr_SetString(PyExc_AttributeError, name); }
if(self->dict && (r=PyObject_GetItem(self->dict, oname))) return r;
PyErr_SetObject(PyExc_AttributeError, oname);
return NULL; return NULL;
} }
static int
CMethod_setattro(CMethod *self, PyObject *oname, PyObject *v)
{
if(! self->dict && ! (self->dict=PyDict_New())) return -1;
return PyDict_SetItem(self->dict, oname, v);
}
static PyTypeObject CMethodType = { static PyTypeObject CMethodType = {
PyObject_HEAD_INIT(NULL) PyObject_HEAD_INIT(NULL)
0, /*ob_size*/ 0, /*ob_size*/
...@@ -549,7 +570,7 @@ static PyTypeObject CMethodType = { ...@@ -549,7 +570,7 @@ static PyTypeObject CMethodType = {
/* methods */ /* methods */
(destructor)CMethod_dealloc, /*tp_dealloc*/ (destructor)CMethod_dealloc, /*tp_dealloc*/
(printfunc)0, /*tp_print*/ (printfunc)0, /*tp_print*/
(getattrfunc)CMethod_getattr, /*tp_getattr*/ 0, /*tp_getattr*/
(setattrfunc)0, /*tp_setattr*/ (setattrfunc)0, /*tp_setattr*/
(cmpfunc)0, /*tp_compare*/ (cmpfunc)0, /*tp_compare*/
(reprfunc)0, /*tp_repr*/ (reprfunc)0, /*tp_repr*/
...@@ -559,9 +580,11 @@ static PyTypeObject CMethodType = { ...@@ -559,9 +580,11 @@ static PyTypeObject CMethodType = {
(hashfunc)0, /*tp_hash*/ (hashfunc)0, /*tp_hash*/
(ternaryfunc)CMethod_call, /*tp_call*/ (ternaryfunc)CMethod_call, /*tp_call*/
(reprfunc)0, /*tp_str*/ (reprfunc)0, /*tp_str*/
(getattrofunc)CMethod_getattro, /* tp_getattro */
(setattrofunc)CMethod_setattro, /* tp_setattro */
/* Space for future expansion */ /* Space for future expansion */
0L,0L,0L,0L, 0L,0L,
"Storage manager for unbound C function PyObject data" "Storage manager for unbound C function PyObject data"
/* Documentation string */ /* Documentation string */
}; };
...@@ -736,35 +759,39 @@ PMethod_call(PMethod *self, PyObject *args, PyObject *kw) ...@@ -736,35 +759,39 @@ PMethod_call(PMethod *self, PyObject *args, PyObject *kw)
} }
static PyObject * static PyObject *
PMethod_getattr(PMethod *self, char *name) PMethod_getattro(PMethod *self, PyObject *oname)
{ {
PyObject *r; PyObject *r;
if(strcmp(name,"__name__")==0 || strcmp(name,"func_name")==0 ) if(PyString_Check(oname))
return PyObject_GetAttrString(self->meth,"__name__"); {
if(strcmp(name,"im_func")==0) char *name;
UNLESS(name=PyString_AsString(oname)) return NULL;
if(*name++=='i' && *name++=='m' && *name++=='_')
{
if(strcmp(name,"func")==0)
{ {
Py_INCREF(self->meth); Py_INCREF(self->meth);
return self->meth; return self->meth;
} }
if(strcmp(name,"__doc__")==0 || if(strcmp(name,"class")==0)
strcmp(name,"func_doc")==0 ||
strcmp(name,"func_doc")==0)
return PyObject_GetAttrString(self->meth,"__doc__");
if(strcmp(name,"im_class")==0)
{ {
Py_INCREF(self->type); Py_INCREF(self->type);
return (PyObject *)self->type; return (PyObject *)self->type;
} }
if(strcmp(name,"im_self")==0) if(strcmp(name,"self")==0)
{ {
if(self->self) r=self->self; if(self->self) r=self->self;
else r=Py_None; else r=Py_None;
Py_INCREF(r); Py_INCREF(r);
return r; return r;
} }
PyErr_SetString(PyExc_AttributeError, name); }
return NULL; }
return PyObject_GetAttr(self->meth, oname);
} }
static PyTypeObject PMethodType = { static PyTypeObject PMethodType = {
...@@ -776,7 +803,7 @@ static PyTypeObject PMethodType = { ...@@ -776,7 +803,7 @@ static PyTypeObject PMethodType = {
/* methods */ /* methods */
(destructor)PMethod_dealloc, /*tp_dealloc*/ (destructor)PMethod_dealloc, /*tp_dealloc*/
(printfunc)0, /*tp_print*/ (printfunc)0, /*tp_print*/
(getattrfunc)PMethod_getattr, /*tp_getattr*/ 0, /*tp_getattr*/
(setattrfunc)0, /*tp_setattr*/ (setattrfunc)0, /*tp_setattr*/
(cmpfunc)0, /*tp_compare*/ (cmpfunc)0, /*tp_compare*/
(reprfunc)0, /*tp_repr*/ (reprfunc)0, /*tp_repr*/
...@@ -786,9 +813,10 @@ static PyTypeObject PMethodType = { ...@@ -786,9 +813,10 @@ static PyTypeObject PMethodType = {
(hashfunc)0, /*tp_hash*/ (hashfunc)0, /*tp_hash*/
(ternaryfunc)PMethod_call, /*tp_call*/ (ternaryfunc)PMethod_call, /*tp_call*/
(reprfunc)0, /*tp_str*/ (reprfunc)0, /*tp_str*/
(getattrofunc)PMethod_getattro, /*tp_getattro*/
/* Space for future expansion */ /* Space for future expansion */
0L,0L,0L,0L, 0L,0L,0L,
"Storage manager for unbound C function PyObject data" "Storage manager for unbound C function PyObject data"
/* Documentation string */ /* Documentation string */
}; };
...@@ -3043,7 +3071,7 @@ void ...@@ -3043,7 +3071,7 @@ void
initExtensionClass() initExtensionClass()
{ {
PyObject *m, *d; PyObject *m, *d;
char *rev="$Revision: 1.15 $"; char *rev="$Revision: 1.16 $";
PURE_MIXIN_CLASS(Base, "Minimalbase class for Extension Classes", NULL); PURE_MIXIN_CLASS(Base, "Minimalbase class for Extension Classes", NULL);
PMethodType.ob_type=&PyType_Type; PMethodType.ob_type=&PyType_Type;
...@@ -3082,6 +3110,9 @@ initExtensionClass() ...@@ -3082,6 +3110,9 @@ initExtensionClass()
/**************************************************************************** /****************************************************************************
$Log: ExtensionClass.c,v $ $Log: ExtensionClass.c,v $
Revision 1.16 1997/10/22 15:09:43 jim
Added support for function and method attributes.
Revision 1.15 1997/09/26 14:35:11 jim Revision 1.15 1997/09/26 14:35:11 jim
Fixed awful bug in handling of sequence subclasses. Fixed awful bug in handling of sequence subclasses.
......
/* /*
$Id: ExtensionClass.c,v 1.15 1997/09/26 14:35:11 jim Exp $ $Id: ExtensionClass.c,v 1.16 1997/10/22 15:09:43 jim Exp $
Extension Class Extension Class
...@@ -65,7 +65,7 @@ static char ExtensionClass_module_documentation[] = ...@@ -65,7 +65,7 @@ static char ExtensionClass_module_documentation[] =
" - They provide access to unbound methods,\n" " - They provide access to unbound methods,\n"
" - They can be called to create instances.\n" " - They can be called to create instances.\n"
"\n" "\n"
"$Id: ExtensionClass.c,v 1.15 1997/09/26 14:35:11 jim Exp $\n" "$Id: ExtensionClass.c,v 1.16 1997/10/22 15:09:43 jim Exp $\n"
; ;
#include <stdio.h> #include <stdio.h>
...@@ -196,6 +196,7 @@ typedef struct { ...@@ -196,6 +196,7 @@ typedef struct {
PyCFunction meth; PyCFunction meth;
int flags; int flags;
char *doc; char *doc;
PyObject *dict;
} CMethod; } CMethod;
staticforward PyTypeObject CMethodType; staticforward PyTypeObject CMethodType;
...@@ -360,6 +361,7 @@ newCMethod(PyExtensionClass *type, PyObject *inst, ...@@ -360,6 +361,7 @@ newCMethod(PyExtensionClass *type, PyObject *inst,
self->meth=meth; self->meth=meth;
self->flags=flags; self->flags=flags;
self->doc=doc; self->doc=doc;
self->dict=NULL;
return (PyObject*)self; return (PyObject*)self;
} }
...@@ -387,6 +389,8 @@ bindCMethod(CMethod *m, PyObject *inst) ...@@ -387,6 +389,8 @@ bindCMethod(CMethod *m, PyObject *inst)
self->meth=m->meth; self->meth=m->meth;
self->flags=m->flags; self->flags=m->flags;
self->doc=m->doc; self->doc=m->doc;
self->dict=m->dict;
Py_XINCREF(self->dict);
return self; return self;
} }
...@@ -398,6 +402,7 @@ CMethod_dealloc(CMethod *self) ...@@ -398,6 +402,7 @@ CMethod_dealloc(CMethod *self)
#endif #endif
Py_XDECREF(self->type); Py_XDECREF(self->type);
Py_XDECREF(self->self); Py_XDECREF(self->self);
Py_XDECREF(self->dict);
PyMem_DEL(self); PyMem_DEL(self);
} }
...@@ -503,10 +508,15 @@ CMethod_call(CMethod *self, PyObject *args, PyObject *kw) ...@@ -503,10 +508,15 @@ CMethod_call(CMethod *self, PyObject *args, PyObject *kw)
} }
static PyObject * static PyObject *
CMethod_getattr(CMethod *self, char *name) CMethod_getattro(CMethod *self, PyObject *oname)
{ {
PyObject *r; PyObject *r;
if(PyString_Check(oname))
{
char *name;
UNLESS(name=PyString_AsString(oname)) return NULL;
if(strcmp(name,"__name__")==0 || strcmp(name,"func_name")==0 ) if(strcmp(name,"__name__")==0 || strcmp(name,"func_name")==0 )
return PyString_FromString(self->name); return PyString_FromString(self->name);
if(strcmp(name,"func_code")==0 || if(strcmp(name,"func_code")==0 ||
...@@ -516,7 +526,6 @@ CMethod_getattr(CMethod *self, char *name) ...@@ -516,7 +526,6 @@ CMethod_getattr(CMethod *self, char *name)
return (PyObject *)self; return (PyObject *)self;
} }
if(strcmp(name,"__doc__")==0 || if(strcmp(name,"__doc__")==0 ||
strcmp(name,"func_doc")==0 ||
strcmp(name,"func_doc")==0) strcmp(name,"func_doc")==0)
{ {
if(self->doc) if(self->doc)
...@@ -536,10 +545,22 @@ CMethod_getattr(CMethod *self, char *name) ...@@ -536,10 +545,22 @@ CMethod_getattr(CMethod *self, char *name)
Py_INCREF(r); Py_INCREF(r);
return r; return r;
} }
PyErr_SetString(PyExc_AttributeError, name); }
if(self->dict && (r=PyObject_GetItem(self->dict, oname))) return r;
PyErr_SetObject(PyExc_AttributeError, oname);
return NULL; return NULL;
} }
static int
CMethod_setattro(CMethod *self, PyObject *oname, PyObject *v)
{
if(! self->dict && ! (self->dict=PyDict_New())) return -1;
return PyDict_SetItem(self->dict, oname, v);
}
static PyTypeObject CMethodType = { static PyTypeObject CMethodType = {
PyObject_HEAD_INIT(NULL) PyObject_HEAD_INIT(NULL)
0, /*ob_size*/ 0, /*ob_size*/
...@@ -549,7 +570,7 @@ static PyTypeObject CMethodType = { ...@@ -549,7 +570,7 @@ static PyTypeObject CMethodType = {
/* methods */ /* methods */
(destructor)CMethod_dealloc, /*tp_dealloc*/ (destructor)CMethod_dealloc, /*tp_dealloc*/
(printfunc)0, /*tp_print*/ (printfunc)0, /*tp_print*/
(getattrfunc)CMethod_getattr, /*tp_getattr*/ 0, /*tp_getattr*/
(setattrfunc)0, /*tp_setattr*/ (setattrfunc)0, /*tp_setattr*/
(cmpfunc)0, /*tp_compare*/ (cmpfunc)0, /*tp_compare*/
(reprfunc)0, /*tp_repr*/ (reprfunc)0, /*tp_repr*/
...@@ -559,9 +580,11 @@ static PyTypeObject CMethodType = { ...@@ -559,9 +580,11 @@ static PyTypeObject CMethodType = {
(hashfunc)0, /*tp_hash*/ (hashfunc)0, /*tp_hash*/
(ternaryfunc)CMethod_call, /*tp_call*/ (ternaryfunc)CMethod_call, /*tp_call*/
(reprfunc)0, /*tp_str*/ (reprfunc)0, /*tp_str*/
(getattrofunc)CMethod_getattro, /* tp_getattro */
(setattrofunc)CMethod_setattro, /* tp_setattro */
/* Space for future expansion */ /* Space for future expansion */
0L,0L,0L,0L, 0L,0L,
"Storage manager for unbound C function PyObject data" "Storage manager for unbound C function PyObject data"
/* Documentation string */ /* Documentation string */
}; };
...@@ -736,35 +759,39 @@ PMethod_call(PMethod *self, PyObject *args, PyObject *kw) ...@@ -736,35 +759,39 @@ PMethod_call(PMethod *self, PyObject *args, PyObject *kw)
} }
static PyObject * static PyObject *
PMethod_getattr(PMethod *self, char *name) PMethod_getattro(PMethod *self, PyObject *oname)
{ {
PyObject *r; PyObject *r;
if(strcmp(name,"__name__")==0 || strcmp(name,"func_name")==0 ) if(PyString_Check(oname))
return PyObject_GetAttrString(self->meth,"__name__"); {
if(strcmp(name,"im_func")==0) char *name;
UNLESS(name=PyString_AsString(oname)) return NULL;
if(*name++=='i' && *name++=='m' && *name++=='_')
{
if(strcmp(name,"func")==0)
{ {
Py_INCREF(self->meth); Py_INCREF(self->meth);
return self->meth; return self->meth;
} }
if(strcmp(name,"__doc__")==0 || if(strcmp(name,"class")==0)
strcmp(name,"func_doc")==0 ||
strcmp(name,"func_doc")==0)
return PyObject_GetAttrString(self->meth,"__doc__");
if(strcmp(name,"im_class")==0)
{ {
Py_INCREF(self->type); Py_INCREF(self->type);
return (PyObject *)self->type; return (PyObject *)self->type;
} }
if(strcmp(name,"im_self")==0) if(strcmp(name,"self")==0)
{ {
if(self->self) r=self->self; if(self->self) r=self->self;
else r=Py_None; else r=Py_None;
Py_INCREF(r); Py_INCREF(r);
return r; return r;
} }
PyErr_SetString(PyExc_AttributeError, name); }
return NULL; }
return PyObject_GetAttr(self->meth, oname);
} }
static PyTypeObject PMethodType = { static PyTypeObject PMethodType = {
...@@ -776,7 +803,7 @@ static PyTypeObject PMethodType = { ...@@ -776,7 +803,7 @@ static PyTypeObject PMethodType = {
/* methods */ /* methods */
(destructor)PMethod_dealloc, /*tp_dealloc*/ (destructor)PMethod_dealloc, /*tp_dealloc*/
(printfunc)0, /*tp_print*/ (printfunc)0, /*tp_print*/
(getattrfunc)PMethod_getattr, /*tp_getattr*/ 0, /*tp_getattr*/
(setattrfunc)0, /*tp_setattr*/ (setattrfunc)0, /*tp_setattr*/
(cmpfunc)0, /*tp_compare*/ (cmpfunc)0, /*tp_compare*/
(reprfunc)0, /*tp_repr*/ (reprfunc)0, /*tp_repr*/
...@@ -786,9 +813,10 @@ static PyTypeObject PMethodType = { ...@@ -786,9 +813,10 @@ static PyTypeObject PMethodType = {
(hashfunc)0, /*tp_hash*/ (hashfunc)0, /*tp_hash*/
(ternaryfunc)PMethod_call, /*tp_call*/ (ternaryfunc)PMethod_call, /*tp_call*/
(reprfunc)0, /*tp_str*/ (reprfunc)0, /*tp_str*/
(getattrofunc)PMethod_getattro, /*tp_getattro*/
/* Space for future expansion */ /* Space for future expansion */
0L,0L,0L,0L, 0L,0L,0L,
"Storage manager for unbound C function PyObject data" "Storage manager for unbound C function PyObject data"
/* Documentation string */ /* Documentation string */
}; };
...@@ -3043,7 +3071,7 @@ void ...@@ -3043,7 +3071,7 @@ void
initExtensionClass() initExtensionClass()
{ {
PyObject *m, *d; PyObject *m, *d;
char *rev="$Revision: 1.15 $"; char *rev="$Revision: 1.16 $";
PURE_MIXIN_CLASS(Base, "Minimalbase class for Extension Classes", NULL); PURE_MIXIN_CLASS(Base, "Minimalbase class for Extension Classes", NULL);
PMethodType.ob_type=&PyType_Type; PMethodType.ob_type=&PyType_Type;
...@@ -3082,6 +3110,9 @@ initExtensionClass() ...@@ -3082,6 +3110,9 @@ initExtensionClass()
/**************************************************************************** /****************************************************************************
$Log: ExtensionClass.c,v $ $Log: ExtensionClass.c,v $
Revision 1.16 1997/10/22 15:09:43 jim
Added support for function and method attributes.
Revision 1.15 1997/09/26 14:35:11 jim Revision 1.15 1997/09/26 14:35:11 jim
Fixed awful bug in handling of sequence subclasses. Fixed awful bug in handling of sequence subclasses.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment