[Python-checkins] CVS: python/dist/src/Objects complexobject.c,2.35.4.1,2.35.4.2 descrobject.c,1.1.2.2,1.1.2.3 dictobject.c,2.80.2.1,2.80.2.2 fileobject.c,2.112.2.1,2.112.2.2 frameobject.c,2.49.4.1,2.49.4.2 listobject.c,2.92.6.1,2.92.6.2 methodobject.c,2.33.8.2,2.33.8.3 object.c,2.124.4.1,2.124.4.2 rangeobject.c,2.24.6.1,2.24.6.2 sliceobject.c,2.7.4.1,2.7.4.2 stringobject.c,2.103.2.1,2.103.2.2 typeobject.c,2.16.8.1,2.16.8.2 unicodeobject.c,2.87.2.1,2.87.2.2

Guido van Rossum gvanrossum@users.sourceforge.net
Fri, 27 Apr 2001 11:04:54 -0700


Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv25251/Objects

Modified Files:
      Tag: descr-branch
	complexobject.c descrobject.c dictobject.c fileobject.c 
	frameobject.c listobject.c methodobject.c object.c 
	rangeobject.c sliceobject.c stringobject.c typeobject.c 
	unicodeobject.c 
Log Message:
Make the descriptor operations (formerly PyDescr_Get() and
PyDescr_Set()) slots in the type object.

Also, the choice to use tp_dict is made by placing a standard function
on the tp_[gs]etattro slot, not by default in PyObject_[GS]etAttr().



Index: complexobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/complexobject.c,v
retrieving revision 2.35.4.1
retrieving revision 2.35.4.2
diff -C2 -r2.35.4.1 -r2.35.4.2
*** complexobject.c	2001/04/24 00:43:30	2.35.4.1
--- complexobject.c	2001/04/27 18:04:50	2.35.4.2
***************
*** 611,615 ****
  	0,					/* tp_call */
  	(reprfunc)complex_str,			/* tp_str */
! 	0,					/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
--- 611,615 ----
  	0,					/* tp_call */
  	(reprfunc)complex_str,			/* tp_str */
! 	PyGeneric_GetAttr,			/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */

Index: descrobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/Attic/descrobject.c,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -C2 -r1.1.2.2 -r1.1.2.3
*** descrobject.c	2001/04/24 01:43:06	1.1.2.2
--- descrobject.c	2001/04/27 18:04:50	1.1.2.3
***************
*** 83,86 ****
--- 83,186 ----
  
  static PyObject *
+ descr_get(PyObject *d, PyObject *obj)
+ {
+ 	PyDescrObject *descr;
+ 
+ 	if (obj == NULL || !PyDescr_Check(d)) {
+ 		Py_INCREF(d);
+ 		return d;
+ 	}
+ 
+ 	descr = (PyDescrObject *)d;
+  
+ 	if (!PyObject_IsInstance(obj, (PyObject *)(descr->d_type))) {
+ 		PyErr_Format(PyExc_TypeError,
+ 			     "descriptor for '%.100s' objects "
+ 			     "doesn't apply to '%.100s' object",
+ 			     descr->d_type->tp_name,
+ 			     obj->ob_type->tp_name);
+ 		return NULL;
+ 	}
+ 
+ 	switch (descr->d_flavor) {
+ 
+ 	case DF_METHOD:
+ 		return PyCFunction_New(descr->d_union.d_method, obj);
+ 
+ 	case DF_MEMBER:
+ 		return PyMember_Get((char *)obj,
+ 				    descr->d_union.d_member,
+ 				    descr->d_union.d_member->name);
+ 
+ 	case DF_GETSET:
+ 		if (descr->d_union.d_getset->get != NULL)
+ 			return descr->d_union.d_getset->get(
+ 				obj, descr->d_union.d_getset->closure);
+ 
+ 	}
+ 
+ 	PyErr_Format(PyExc_NotImplementedError,
+ 		     "PyDescr_Get() not implemented for descriptor type %d "
+ 		     "of '%.50s' object",
+ 		     descr->d_flavor, obj->ob_type->tp_name);
+ 	return NULL;
+ }
+ 
+ int
+ descr_set(PyObject *d, PyObject *obj, PyObject *value)
+ {
+ 	PyDescrObject *descr = (PyDescrObject *)d;
+ 
+ 	assert(PyDescr_Check(d));
+ 
+ 	if (!PyObject_IsInstance(obj, (PyObject *)(descr->d_type))) {
+ 		PyErr_Format(PyExc_TypeError,
+ 			     "descriptor for '%.100s' objects "
+ 			     "doesn't apply to '%.100s' object",
+ 			     descr->d_type->tp_name,
+ 			     obj->ob_type->tp_name);
+ 		return -1;
+ 	}
+ 
+ 	switch (descr->d_flavor) {
+ 
+ 	case DF_METHOD:
+ 		PyErr_Format(PyExc_TypeError,
+ 			     "can't %s method attribute '%.400s' "
+ 			     "of '%.50s' object",
+ 			     value==NULL ? "delete" : "assign to",
+ 			     descr->d_union.d_method->ml_name,
+ 			     obj->ob_type->tp_name);
+ 		return -1;
+ 
+ 	case DF_MEMBER:
+ 		return PyMember_Set((char *)obj,
+ 				    descr->d_union.d_member,
+ 				    descr->d_union.d_member->name,
+ 				    value);
+ 
+ 	case DF_GETSET:
+ 		if (descr->d_union.d_getset->set == NULL) {
+ 			PyErr_Format(PyExc_TypeError,
+ 				     "can't %s read-only attribute "
+ 				     "'%.400s' of '%.50s' object",
+ 				     value==NULL ? "delete" : "assign to",
+ 				     descr->d_union.d_getset->name,
+ 				     obj->ob_type->tp_name);
+ 			return -1;
+ 		}
+ 		return descr->d_union.d_getset->set(
+ 			obj, value, descr->d_union.d_getset->closure);
+ 
+ 	}
+ 
+ 	PyErr_Format(PyExc_NotImplementedError,
+ 		     "PyDescr_Set() not implemented for descriptor type %d "
+ 		     "of '%.50s' object",
+ 		     descr->d_flavor, obj->ob_type->tp_name);
+ 	return -1;
+ }
+ 
+ static PyObject *
  descr_call(PyDescrObject *descr, PyObject *args, PyObject *kwds)
  {
***************
*** 131,138 ****
  
  	if (argc == 1)
! 		return PyDescr_Get((PyObject *)descr, self);
  	if (argc == 2) {
  		PyObject *value = PyTuple_GET_ITEM(args, 1);
! 		if (PyDescr_Set((PyObject *)descr, self, value) < 0)
  			return NULL;
  		Py_INCREF(Py_None);
--- 231,238 ----
  
  	if (argc == 1)
! 		return descr_get((PyObject *)descr, self);
  	if (argc == 2) {
  		PyObject *value = PyTuple_GET_ITEM(args, 1);
! 		if (descr_set((PyObject *)descr, self, value) < 0)
  			return NULL;
  		Py_INCREF(Py_None);
***************
*** 145,149 ****
  
  static PyObject *
! descr_get(PyObject *descr, PyObject *args)
  {
  	PyObject *obj;
--- 245,249 ----
  
  static PyObject *
! descr_get_api(PyObject *descr, PyObject *args)
  {
  	PyObject *obj;
***************
*** 151,159 ****
  	if (!PyArg_ParseTuple(args, "O:get", &obj))
  		return NULL;
! 	return PyDescr_Get(descr, obj);
  }
  
  static PyObject *
! descr_set(PyObject *descr, PyObject *args)
  {
  	PyObject *obj, *val;
--- 251,259 ----
  	if (!PyArg_ParseTuple(args, "O:get", &obj))
  		return NULL;
! 	return descr_get(descr, obj);
  }
  
  static PyObject *
! descr_set_api(PyObject *descr, PyObject *args)
  {
  	PyObject *obj, *val;
***************
*** 161,165 ****
  	if (!PyArg_ParseTuple(args, "OO:set", &obj, &val))
  		return NULL;
! 	if (PyDescr_Set(descr, obj, val) < 0)
  		return NULL;
  	Py_INCREF(Py_None);
--- 261,265 ----
  	if (!PyArg_ParseTuple(args, "OO:set", &obj, &val))
  		return NULL;
! 	if (descr_set(descr, obj, val) < 0)
  		return NULL;
  	Py_INCREF(Py_None);
***************
*** 168,175 ****
  
  static PyMethodDef descr_methods[] = {
! 	{"get",		descr_get,	METH_VARARGS},
! 	{"set",		descr_set,	METH_VARARGS},
! 	{"call",	descr_call,	METH_VARARGS|METH_KEYWORDS},
! 	{"bind",	descr_get,	METH_VARARGS},
  	{0}
  };
--- 268,276 ----
  
  static PyMethodDef descr_methods[] = {
! 	{"get",		(PyCFunction)descr_get_api,	METH_VARARGS},
! 	{"set",		(PyCFunction)descr_set_api,	METH_VARARGS},
! 	{"call",	(PyCFunction)descr_call,
! 	                                  METH_KEYWORDS|METH_VARARGS},
! 	{"bind",	(PyCFunction)descr_get_api,	METH_VARARGS},
  	{0}
  };
***************
*** 225,234 ****
  
  static struct getsetlist descr_getsets[] = {
! 	{"name",	descr_get_name},
! 	{"__name__",	descr_get_name},
! 	{"doc",		descr_get_doc},
! 	{"__doc__",	descr_get_doc},
! 	{"kind",	descr_get_kind},
! 	{"readonly",	descr_get_readonly},
  	{0}
  };
--- 326,335 ----
  
  static struct getsetlist descr_getsets[] = {
! 	{"name",	(getter)descr_get_name},
! 	{"__name__",	(getter)descr_get_name},
! 	{"doc",		(getter)descr_get_doc},
! 	{"__doc__",	(getter)descr_get_doc},
! 	{"kind",	(getter)descr_get_kind},
! 	{"readonly",	(getter)descr_get_readonly},
  	{0}
  };
***************
*** 260,264 ****
  	(ternaryfunc)descr_call,		/* tp_call */
  	0,					/* tp_str */
! 	0,					/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
--- 361,365 ----
  	(ternaryfunc)descr_call,		/* tp_call */
  	0,					/* tp_str */
! 	PyGeneric_GetAttr,			/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
***************
*** 276,279 ****
--- 377,382 ----
  	0,					/* tp_base */
  	0,					/* tp_dict */
+ 	(descrgetfunc)descr_get,		/* tp_descr_get */
+ 	(descrsetfunc)descr_set,		/* tp_descr_set */
  };
  
***************
*** 324,427 ****
  	descr->d_flavor = DF_GETSET;
  	return (PyObject *)descr;
- }
- 
- PyObject *
- PyDescr_Get(PyObject *d, PyObject *obj)
- {
- 	PyDescrObject *descr;
- 
- 	if (obj == NULL || !PyDescr_Check(d)) {
- 		Py_INCREF(d);
- 		return d;
- 	}
- 
- 	descr = (PyDescrObject *)d;
-  
- 	if (!PyObject_IsInstance(obj, (PyObject *)(descr->d_type))) {
- 		PyErr_Format(PyExc_TypeError,
- 			     "descriptor for '%.100s' objects "
- 			     "doesn't apply to '%.100s' object",
- 			     descr->d_type->tp_name,
- 			     obj->ob_type->tp_name);
- 		return NULL;
- 	}
- 
- 	switch (descr->d_flavor) {
- 
- 	case DF_METHOD:
- 		return PyCFunction_New(descr->d_union.d_method, obj);
- 
- 	case DF_MEMBER:
- 		return PyMember_Get((char *)obj,
- 				    descr->d_union.d_member,
- 				    descr->d_union.d_member->name);
- 
- 	case DF_GETSET:
- 		if (descr->d_union.d_getset->get != NULL)
- 			return descr->d_union.d_getset->get(
- 				obj, descr->d_union.d_getset->closure);
- 
- 	}
- 
- 	PyErr_Format(PyExc_NotImplementedError,
- 		     "PyDescr_Get() not implemented for descriptor type %d "
- 		     "of '%.50s' object",
- 		     descr->d_flavor, obj->ob_type->tp_name);
- 	return NULL;
- }
- 
- int
- PyDescr_Set(PyObject *d, PyObject *obj, PyObject *value)
- {
- 	PyDescrObject *descr = (PyDescrObject *)d;
- 
- 	assert(PyDescr_Check(d));
- 
- 	if (!PyObject_IsInstance(obj, (PyObject *)(descr->d_type))) {
- 		PyErr_Format(PyExc_TypeError,
- 			     "descriptor for '%.100s' objects "
- 			     "doesn't apply to '%.100s' object",
- 			     descr->d_type->tp_name,
- 			     obj->ob_type->tp_name);
- 		return -1;
- 	}
- 
- 	switch (descr->d_flavor) {
- 
- 	case DF_METHOD:
- 		PyErr_Format(PyExc_TypeError,
- 			     "can't %s method attribute '%.400s' "
- 			     "of '%.50s' object",
- 			     value==NULL ? "delete" : "assign to",
- 			     descr->d_union.d_method->ml_name,
- 			     obj->ob_type->tp_name);
- 		return -1;
- 
- 	case DF_MEMBER:
- 		return PyMember_Set((char *)obj,
- 				    descr->d_union.d_member,
- 				    descr->d_union.d_member->name,
- 				    value);
- 
- 	case DF_GETSET:
- 		if (descr->d_union.d_getset->set == NULL) {
- 			PyErr_Format(PyExc_TypeError,
- 				     "can't %s read-only attribute "
- 				     "'%.400s' of '%.50s' object",
- 				     value==NULL ? "delete" : "assign to",
- 				     descr->d_union.d_getset->name,
- 				     obj->ob_type->tp_name);
- 			return -1;
- 		}
- 		return descr->d_union.d_getset->set(
- 			obj, value, descr->d_union.d_getset->closure);
- 
- 	}
- 
- 	PyErr_Format(PyExc_NotImplementedError,
- 		     "PyDescr_Set() not implemented for descriptor type %d "
- 		     "of '%.50s' object",
- 		     descr->d_flavor, obj->ob_type->tp_name);
- 	return -1;
  }
  
--- 427,430 ----

Index: dictobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v
retrieving revision 2.80.2.1
retrieving revision 2.80.2.2
diff -C2 -r2.80.2.1 -r2.80.2.2
*** dictobject.c	2001/04/24 00:43:30	2.80.2.1
--- dictobject.c	2001/04/27 18:04:50	2.80.2.2
***************
*** 1263,1267 ****
  "D.copy() -> a shallow copy of D";
  
! static PyMethodDef mapp_methods[] = {
  	{"has_key",	(PyCFunction)dict_has_key,      METH_VARARGS,
  	 has_key__doc__},
--- 1263,1267 ----
  "D.copy() -> a shallow copy of D";
  
! static PyMethodDef dict_methods[] = {
  	{"has_key",	(PyCFunction)dict_has_key,      METH_VARARGS,
  	 has_key__doc__},
***************
*** 1339,1343 ****
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	0,					/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
--- 1339,1343 ----
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	PyGeneric_GetAttr,			/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
***************
*** 1350,1354 ****
  	(getiterfunc)dictiter_new,		/* tp_iter */
  	0,					/* tp_iternext */
! 	mapp_methods,				/* tp_methods */
  	0,					/* tp_members */
  	0,					/* tp_getset */
--- 1350,1354 ----
  	(getiterfunc)dictiter_new,		/* tp_iter */
  	0,					/* tp_iternext */
! 	dict_methods,				/* tp_methods */
  	0,					/* tp_members */
  	0,					/* tp_getset */

Index: fileobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v
retrieving revision 2.112.2.1
retrieving revision 2.112.2.2
diff -C2 -r2.112.2.1 -r2.112.2.2
*** fileobject.c	2001/04/24 00:43:30	2.112.2.1
--- fileobject.c	2001/04/27 18:04:50	2.112.2.2
***************
*** 1317,1321 ****
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	0,					/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
--- 1317,1321 ----
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	PyGeneric_GetAttr,			/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */

Index: frameobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/frameobject.c,v
retrieving revision 2.49.4.1
retrieving revision 2.49.4.2
diff -C2 -r2.49.4.1 -r2.49.4.2
*** frameobject.c	2001/04/24 00:43:30	2.49.4.1
--- frameobject.c	2001/04/27 18:04:51	2.49.4.2
***************
*** 108,113 ****
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	0,					/* tp_getattro */
! 	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
  	Py_TPFLAGS_DEFAULT,			/* tp_flags */
--- 108,113 ----
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	PyGeneric_GetAttr,			/* tp_getattro */
! 	PyGeneric_SetAttr,			/* tp_setattro */
  	0,					/* tp_as_buffer */
  	Py_TPFLAGS_DEFAULT,			/* tp_flags */

Index: listobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v
retrieving revision 2.92.6.1
retrieving revision 2.92.6.2
diff -C2 -r2.92.6.1 -r2.92.6.2
*** listobject.c	2001/04/24 00:43:30	2.92.6.1
--- listobject.c	2001/04/27 18:04:51	2.92.6.2
***************
*** 1554,1558 ****
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	0,					/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
--- 1554,1558 ----
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	PyGeneric_GetAttr,			/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
***************
*** 1634,1638 ****
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	0,					/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
--- 1634,1638 ----
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	PyGeneric_GetAttr,			/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */

Index: methodobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/methodobject.c,v
retrieving revision 2.33.8.2
retrieving revision 2.33.8.3
diff -C2 -r2.33.8.2 -r2.33.8.3
*** methodobject.c	2001/04/24 01:36:12	2.33.8.2
--- methodobject.c	2001/04/27 18:04:51	2.33.8.3
***************
*** 171,175 ****
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	0,					/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
--- 171,175 ----
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	PyGeneric_GetAttr,			/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */

Index: object.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v
retrieving revision 2.124.4.1
retrieving revision 2.124.4.2
diff -C2 -r2.124.4.1 -r2.124.4.2
*** object.c	2001/04/24 00:43:30	2.124.4.1
--- object.c	2001/04/27 18:04:51	2.124.4.2
***************
*** 1022,1040 ****
  }
  
- /*
- 	if (v->ob_type->tp_setattr == NULL) {
- 		if (v->ob_type->tp_getattr == NULL)
- 			PyErr_SetString(PyExc_TypeError,
- 				   "attribute-less object (assign or del)");
- 		else
- 			PyErr_SetString(PyExc_TypeError,
- 				   "object has read-only attributes");
- 		return -1;
- 	}
- 	else {
- 		return (*v->ob_type->tp_setattr)(v, name, w);
- 	}
- */
- 
  /* Internal API needed by PyObject_GetAttr(): */
  extern 
--- 1022,1025 ----
***************
*** 1064,1077 ****
  	if (tp->tp_getattr != NULL)
  		return (*tp->tp_getattr)(v, PyString_AS_STRING(name));
- 	if (tp->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
- 		PyObject *descr;
- 		if (tp->tp_dict == NULL) {
- 			if (PyType_InitDict(tp) < 0)
- 				return NULL;
- 		}
- 		descr = PyDict_GetItem(tp->tp_dict, name);
- 		if (descr != NULL)
- 			return PyDescr_Get(descr, v);
- 	}
  	PyErr_Format(PyExc_AttributeError,
  		     "'%.50s' object has no attribute '%.400s'",
--- 1049,1052 ----
***************
*** 1125,1142 ****
  		return err;
  	}
- 	if (tp->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
- 		PyObject *descr;
- 		if (tp->tp_dict == NULL) {
- 			if (PyType_InitDict(tp) < 0)
- 				return -1;
- 		}
- 		descr = PyDict_GetItem(tp->tp_dict, name);
- 		if (descr != NULL) {
- 			err = PyDescr_Set(descr, v, value);
- 			Py_DECREF(name);
- 			return err;
- 		}
- 	}
  	Py_DECREF(name);
  	PyErr_Format(PyExc_AttributeError,
  		     "'%.50s' object has no attribute '%.400s'",
--- 1100,1146 ----
  		return err;
  	}
  	Py_DECREF(name);
+ 	PyErr_Format(PyExc_AttributeError,
+ 		     "'%.50s' object has no attribute '%.400s'",
+ 		     tp->tp_name, PyString_AS_STRING(name));
+ 	return -1;
+ }
+ 
+ /* Generic GetAttr functions - put these in your tp_[gs]etattro slot */
+ 
+ PyObject *
+ PyGeneric_GetAttr(PyObject *obj, PyObject *name)
+ {
+ 	PyTypeObject *tp = obj->ob_type;
+ 	PyObject *descr;
+ 	descrgetfunc f;
+ 
+ 	if (tp->tp_dict == NULL) {
+ 		if (PyType_InitDict(tp) < 0)
+ 			return NULL;
+ 	}
+ 	descr = PyDict_GetItem(tp->tp_dict, name);
+ 	if (descr != NULL && (f = descr->ob_type->tp_descr_get) != NULL)
+ 		return (*f)(descr, obj);
+ 	PyErr_Format(PyExc_AttributeError,
+ 		     "'%.50s' object has no attribute '%.400s'",
+ 		     tp->tp_name, PyString_AS_STRING(name));
+ 	return NULL;
+ }
+ 
+ int
+ PyGeneric_SetAttr(PyObject *obj, PyObject *name, PyObject *value)
+ {
+ 	PyTypeObject *tp = obj->ob_type;
+ 	PyObject *descr;
+ 	descrsetfunc f;
+ 
+ 	if (tp->tp_dict == NULL) {
+ 		if (PyType_InitDict(tp) < 0)
+ 			return -1;
+ 	}
+ 	descr = PyDict_GetItem(tp->tp_dict, name);
+ 	if (descr != NULL && (f = descr->ob_type->tp_descr_set) != NULL)
+ 		return (*f)(descr, obj, value);
  	PyErr_Format(PyExc_AttributeError,
  		     "'%.50s' object has no attribute '%.400s'",

Index: rangeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/rangeobject.c,v
retrieving revision 2.24.6.1
retrieving revision 2.24.6.2
diff -C2 -r2.24.6.1 -r2.24.6.2
*** rangeobject.c	2001/04/24 00:43:30	2.24.6.1
--- rangeobject.c	2001/04/27 18:04:51	2.24.6.2
***************
*** 311,330 ****
  	sizeof(rangeobject),	/* Basic object size */
  	0,			/* Item size for varobject */
! 	(destructor)range_dealloc, /*tp_dealloc*/
! 	0,			/*tp_print*/
! 	0, 			/*tp_getattr*/
! 	0,			/*tp_setattr*/
! 	(cmpfunc)range_compare, /*tp_compare*/
! 	(reprfunc)range_repr,	/*tp_repr*/
! 	0,			/*tp_as_number*/
! 	&range_as_sequence,	/*tp_as_sequence*/
! 	0,			/*tp_as_mapping*/
! 	0,			/*tp_hash*/
! 	0,			/*tp_call*/
! 	0,			/*tp_str*/
! 	0,			/*tp_getattro*/
! 	0,			/*tp_setattro*/
! 	0,			/*tp_as_buffer*/
! 	Py_TPFLAGS_DEFAULT,	/*tp_flags*/
  	0,					/* tp_doc */
  	0,					/* tp_traverse */
--- 311,330 ----
  	sizeof(rangeobject),	/* Basic object size */
  	0,			/* Item size for varobject */
! 	(destructor)range_dealloc,		/* tp_dealloc */
! 	0,					/* tp_print */
! 	0, 					/* tp_getattr */
! 	0,					/* tp_setattr */
! 	(cmpfunc)range_compare,			/* tp_compare */
! 	(reprfunc)range_repr,			/* tp_repr */
! 	0,					/* tp_as_number */
! 	&range_as_sequence,			/* tp_as_sequence */
! 	0,					/* tp_as_mapping */
! 	0,					/* tp_hash */
! 	0,					/* tp_call */
! 	0,					/* tp_str */
! 	PyGeneric_GetAttr,			/* tp_getattro */
! 	0,					/* tp_setattro */
! 	0,					/* tp_as_buffer */
! 	Py_TPFLAGS_DEFAULT,			/* tp_flags */
  	0,					/* tp_doc */
  	0,					/* tp_traverse */

Index: sliceobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/sliceobject.c,v
retrieving revision 2.7.4.1
retrieving revision 2.7.4.2
diff -C2 -r2.7.4.1 -r2.7.4.2
*** sliceobject.c	2001/04/24 00:43:30	2.7.4.1
--- sliceobject.c	2001/04/27 18:04:51	2.7.4.2
***************
*** 176,180 ****
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	0,					/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
--- 176,180 ----
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	PyGeneric_GetAttr,			/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */

Index: stringobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v
retrieving revision 2.103.2.1
retrieving revision 2.103.2.2
diff -C2 -r2.103.2.1 -r2.103.2.2
*** stringobject.c	2001/04/24 00:43:30	2.103.2.1
--- stringobject.c	2001/04/27 18:04:51	2.103.2.2
***************
*** 2358,2378 ****
  	sizeof(PyStringObject),
  	sizeof(char),
! 	(destructor)string_dealloc, /*tp_dealloc*/
! 	(printfunc)string_print, /*tp_print*/
! 	0,		/*tp_getattr*/
! 	0,		/*tp_setattr*/
! 	(cmpfunc)string_compare, /*tp_compare*/
! 	(reprfunc)string_repr, /*tp_repr*/
! 	0,		/*tp_as_number*/
! 	&string_as_sequence,	/*tp_as_sequence*/
! 	0,		/*tp_as_mapping*/
! 	(hashfunc)string_hash, /*tp_hash*/
! 	0,		/*tp_call*/
! 	0,		/*tp_str*/
! 	0,		/*tp_getattro*/
! 	0,		/*tp_setattro*/
! 	&string_as_buffer,	/*tp_as_buffer*/
! 	Py_TPFLAGS_DEFAULT,	/*tp_flags*/
! 	0,		/*tp_doc*/
  	0,					/* tp_traverse */
  	0,					/* tp_clear */
--- 2358,2378 ----
  	sizeof(PyStringObject),
  	sizeof(char),
! 	(destructor)string_dealloc, 		/* tp_dealloc */
! 	(printfunc)string_print, 		/* tp_print */
! 	0,					/* tp_getattr */
! 	0,					/* tp_setattr */
! 	(cmpfunc)string_compare, 		/* tp_compare */
! 	(reprfunc)string_repr, 			/* tp_repr */
! 	0,					/* tp_as_number */
! 	&string_as_sequence,			/* tp_as_sequence */
! 	0,					/* tp_as_mapping */
! 	(hashfunc)string_hash, 			/* tp_hash */
! 	0,					/* tp_call */
! 	0,					/* tp_str */
! 	PyGeneric_GetAttr,			/* tp_getattro */
! 	0,					/* tp_setattro */
! 	&string_as_buffer,			/* tp_as_buffer */
! 	Py_TPFLAGS_DEFAULT,			/* tp_flags */
! 	0,					/* tp_doc */
  	0,					/* tp_traverse */
  	0,					/* tp_clear */

Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.16.8.1
retrieving revision 2.16.8.2
diff -C2 -r2.16.8.1 -r2.16.8.2
*** typeobject.c	2001/04/24 00:43:30	2.16.8.1
--- typeobject.c	2001/04/27 18:04:51	2.16.8.2
***************
*** 36,39 ****
--- 36,40 ----
  	PyTypeObject *tp = type->ob_type; /* Usually == &PyType_Type below */
  	PyObject *descr;
+ 	descrgetfunc f;
  
  	assert(PyString_Check(name));
***************
*** 52,63 ****
  		}
  		descr = PyDict_GetItem(tp->tp_dict, name);
! 		if (descr != NULL)
! 			return PyDescr_Get(descr, (PyObject *)type);
  	}
  
  	if (type->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
  		descr = PyDict_GetItem(type->tp_dict, name);
! 		if (descr != NULL)
! 			return PyDescr_Get(descr, NULL);
  	}
  
--- 53,66 ----
  		}
  		descr = PyDict_GetItem(tp->tp_dict, name);
! 		if (descr != NULL &&
! 		    (f = descr->ob_type->tp_descr_get) != NULL)
! 			return (*f)(descr, (PyObject *)type);
  	}
  
  	if (type->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
  		descr = PyDict_GetItem(type->tp_dict, name);
! 		if (descr != NULL &&
! 		    (f = descr->ob_type->tp_descr_get) != NULL)
! 			return (*f)(descr, NULL);
  	}
  

Index: unicodeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v
retrieving revision 2.87.2.1
retrieving revision 2.87.2.2
diff -C2 -r2.87.2.1 -r2.87.2.2
*** unicodeobject.c	2001/04/24 00:43:30	2.87.2.1
--- unicodeobject.c	2001/04/27 18:04:51	2.87.2.2
***************
*** 5239,5243 ****
      0, 					/* tp_call*/
      (reprfunc) unicode_str,	 	/* tp_str */
!     0,			 		/* tp_getattro */
      0,			 		/* tp_setattro */
      &unicode_as_buffer,			/* tp_as_buffer */
--- 5239,5243 ----
      0, 					/* tp_call*/
      (reprfunc) unicode_str,	 	/* tp_str */
!     PyGeneric_GetAttr,	 		/* tp_getattro */
      0,			 		/* tp_setattro */
      &unicode_as_buffer,			/* tp_as_buffer */