[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}