[Python-checkins] CVS: python/dist/src/Objects funcobject.c,2.37.4.6,2.37.4.7 typeobject.c,2.16.8.55,2.16.8.56
Guido van Rossum
gvanrossum@users.sourceforge.net
Mon, 02 Jul 2001 11:06:09 -0700
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv18444/Objects
Modified Files:
Tag: descr-branch
funcobject.c typeobject.c
Log Message:
Add a new type: 'classmethod'. This needs to be fleshed out a bit
more with docstrings and maybe attribute, but it works:
>>> class C(object):
... def f(*a): return a
... f = classmethod(f)
...
>>> C.f(1, 2)
(<type 'C'>, 1, 2)
>>> C().f(1, 2)
(<type 'C'>, 1, 2)
>>> class D(C):
... pass
...
>>> D.f(1, 2)
(<type 'D'>, 1, 2)
>>> D().f(1, 2)
(<type 'D'>, 1, 2)
>>>
It doesn't work in classic classes yet (the method binding there needs
to be updated).
Index: funcobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/funcobject.c,v
retrieving revision 2.37.4.6
retrieving revision 2.37.4.7
diff -C2 -r2.37.4.6 -r2.37.4.7
*** funcobject.c 2001/07/02 17:08:33 2.37.4.6
--- funcobject.c 2001/07/02 18:06:06 2.37.4.7
***************
*** 374,375 ****
--- 374,459 ----
offsetof(PyFunctionObject, func_dict), /* tp_dictoffset */
};
+
+
+ /* Class method object */
+
+ typedef struct {
+ PyObject_HEAD;
+ PyObject *cm_callable;
+ } classmethod;
+
+ static void
+ cm_dealloc(classmethod *cm)
+ {
+ Py_XDECREF(cm->cm_callable);
+ PyObject_DEL(cm);
+ }
+
+ static PyObject *
+ cm_descr_get(PyObject *self, PyObject *obj, PyTypeObject *type)
+ {
+ classmethod *cm = (classmethod *)self;
+
+ if (cm->cm_callable == NULL) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "uninitialized classmethod object");
+ return NULL;
+ }
+ return PyMethod_New(cm->cm_callable,
+ (PyObject *)type, (PyObject *)(type->ob_type));
+ }
+
+ static int
+ cm_init(PyObject *self, PyObject *args, PyObject *kwds)
+ {
+ classmethod *cm = (classmethod *)self;
+ PyObject *callable;
+
+ if (!PyArg_ParseTuple(args, "O:callable", &callable))
+ return -1;
+ Py_INCREF(callable);
+ cm->cm_callable = callable;
+ return 0;
+ }
+
+ PyTypeObject PyClassMethod_Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "classmethod",
+ sizeof(classmethod),
+ 0,
+ (destructor)cm_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ cm_descr_get, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ cm_init, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ PyType_GenericNew, /* tp_new */
+ };
Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.16.8.55
retrieving revision 2.16.8.56
diff -C2 -r2.16.8.55 -r2.16.8.56
*** typeobject.c 2001/07/02 17:08:33 2.16.8.55
--- typeobject.c 2001/07/02 18:06:06 2.16.8.56
***************
*** 639,642 ****
--- 639,645 ----
res = _PyType_Lookup(type, name);
if (res != NULL) {
+ f = res->ob_type->tp_descr_get;
+ if (f != NULL)
+ return f(res, (PyObject *)NULL, type);
Py_INCREF(res);
return res;
***************
*** 1635,1640 ****
};
static struct wrapperbase tab_descr_get[] = {
! {"__get__", (wrapperfunc)wrap_ternaryfunc,
"descr.__get__(obj, type) -> value"},
{0}
--- 1638,1657 ----
};
+ static PyObject *
+ wrap_descr_get(PyObject *self, PyObject *args, void *wrapped)
+ {
+ descrgetfunc func = (descrgetfunc)wrapped;
+ PyObject *obj;
+ PyTypeObject *type = NULL;
+
+ if (!PyArg_ParseTuple(args, "O|O!", &obj, &PyType_Type, &type))
+ return NULL;
+ if (type == NULL)
+ type = obj->ob_type;
+ return (*func)(self, obj, type);
+ }
+
static struct wrapperbase tab_descr_get[] = {
! {"__get__", (wrapperfunc)wrap_descr_get,
"descr.__get__(obj, type) -> value"},
{0}