[Python-checkins] CVS: python/dist/src/Objects descrobject.c,1.1,2.1 abstract.c,2.69,2.70 bufferobject.c,2.13,2.14 cellobject.c,1.2,1.3 classobject.c,2.132,2.133 complexobject.c,2.35,2.36 dictobject.c,2.106,2.107 fileobject.c,2.114,2.115 floatobject.c,2.83,2.84 frameobject.c,2.53,2.54 funcobject.c,2.38,2.39 intobject.c,2.59,2.60 iterobject.c,1.5,1.6 listobject.c,2.97,2.98 longobject.c,1.89,1.90 methodobject.c,2.34,2.35 moduleobject.c,2.33,2.34 object.c,2.134,2.135 rangeobject.c,2.26,2.27 sliceobject.c,2.7,2.8 stringobject.c,2.121,2.122 tupleobject.c,2.53,2.54 typeobject.c,2.18,2.19 unicodeobject.c,2.105,2.106

Tim Peters tim_one@users.sourceforge.net
Wed, 01 Aug 2001 21:15:03 -0700


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

Modified Files:
	abstract.c bufferobject.c cellobject.c classobject.c 
	complexobject.c dictobject.c fileobject.c floatobject.c 
	frameobject.c funcobject.c intobject.c iterobject.c 
	listobject.c longobject.c methodobject.c moduleobject.c 
	object.c rangeobject.c sliceobject.c stringobject.c 
	tupleobject.c typeobject.c unicodeobject.c 
Added Files:
	descrobject.c 
Log Message:
Merge of descr-branch back into trunk.



Index: abstract.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v
retrieving revision 2.69
retrieving revision 2.70
diff -C2 -d -r2.69 -r2.70
*** abstract.c	2001/05/28 22:30:08	2.69
--- abstract.c	2001/08/02 04:15:00	2.70
***************
*** 1590,1593 ****
--- 1590,1611 ----
  
  PyObject *
+ PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw)
+ {
+         ternaryfunc call;
+ 
+ 	if ((call = func->ob_type->tp_call) != NULL) {
+ 		PyObject *result = (*call)(func, arg, kw);
+ 		if (result == NULL && !PyErr_Occurred())
+ 			PyErr_SetString(
+ 				PyExc_SystemError,
+ 				"NULL result without error in PyObject_Call");
+ 		return result;
+ 	}
+ 	PyErr_Format(PyExc_TypeError, "object is not callable: %s",
+ 		     PyString_AS_STRING(PyObject_Repr(func)));
+ 	return NULL;
+ }
+ 
+ PyObject *
  PyObject_CallFunction(PyObject *callable, char *format, ...)
  {
***************
*** 1747,1751 ****
  	}
  	else if (PyType_Check(cls)) {
! 		retval = ((PyObject *)(inst->ob_type) == cls);
  	}
  	else if (!PyInstance_Check(inst)) {
--- 1765,1769 ----
  	}
  	else if (PyType_Check(cls)) {
! 		retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls);
  	}
  	else if (!PyInstance_Check(inst)) {

Index: bufferobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/bufferobject.c,v
retrieving revision 2.13
retrieving revision 2.14
diff -C2 -d -r2.13 -r2.14
*** bufferobject.c	2000/09/01 23:29:27	2.13
--- bufferobject.c	2001/08/02 04:15:00	2.14
***************
*** 538,557 ****
  	sizeof(PyBufferObject),
  	0,
! 	(destructor)buffer_dealloc, /*tp_dealloc*/
! 	0,		/*tp_print*/
! 	0,		/*tp_getattr*/
! 	0,		/*tp_setattr*/
! 	(cmpfunc)buffer_compare, /*tp_compare*/
! 	(reprfunc)buffer_repr, /*tp_repr*/
! 	0,		/*tp_as_number*/
! 	&buffer_as_sequence,	/*tp_as_sequence*/
! 	0,		/*tp_as_mapping*/
! 	(hashfunc)buffer_hash,	/*tp_hash*/
! 	0,		/*tp_call*/
! 	(reprfunc)buffer_str,		/*tp_str*/
! 	0,		/*tp_getattro*/
! 	0,		/*tp_setattro*/
! 	&buffer_as_buffer,	/*tp_as_buffer*/
! 	Py_TPFLAGS_DEFAULT,	/*tp_flags*/
! 	0,		/*tp_doc*/
  };
--- 538,557 ----
  	sizeof(PyBufferObject),
  	0,
! 	(destructor)buffer_dealloc, 		/* tp_dealloc */
! 	0,					/* tp_print */
! 	0,					/* tp_getattr */
! 	0,					/* tp_setattr */
! 	(cmpfunc)buffer_compare,		/* tp_compare */
! 	(reprfunc)buffer_repr,			/* tp_repr */
! 	0,					/* tp_as_number */
! 	&buffer_as_sequence,			/* tp_as_sequence */
! 	0,					/* tp_as_mapping */
! 	(hashfunc)buffer_hash,			/* tp_hash */
! 	0,					/* tp_call */
! 	(reprfunc)buffer_str,			/* tp_str */
! 	PyObject_GenericGetAttr,		/* tp_getattro */
! 	0,					/* tp_setattro */
! 	&buffer_as_buffer,			/* tp_as_buffer */
! 	Py_TPFLAGS_DEFAULT,			/* tp_flags */
! 	0,					/* tp_doc */
  };

Index: cellobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/cellobject.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** cellobject.c	2001/03/13 01:58:21	1.2
--- cellobject.c	2001/08/02 04:15:00	1.3
***************
*** 107,111 ****
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	0,					/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
--- 107,111 ----
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	PyObject_GenericGetAttr,		/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */

Index: classobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v
retrieving revision 2.132
retrieving revision 2.133
diff -C2 -d -r2.132 -r2.133
*** classobject.c	2001/05/22 02:33:08	2.132
--- classobject.c	2001/08/02 04:15:00	2.133
***************
*** 37,46 ****
  	}
  	if (name == NULL || !PyString_Check(name)) {
! 		PyErr_SetString(PyExc_SystemError,
  				"PyClass_New: name must be a string");
  		return NULL;
  	}
  	if (dict == NULL || !PyDict_Check(dict)) {
! 		PyErr_SetString(PyExc_SystemError,
  				"PyClass_New: dict must be a dictionary");
  		return NULL;
--- 37,46 ----
  	}
  	if (name == NULL || !PyString_Check(name)) {
! 		PyErr_SetString(PyExc_TypeError,
  				"PyClass_New: name must be a string");
  		return NULL;
  	}
  	if (dict == NULL || !PyDict_Check(dict)) {
! 		PyErr_SetString(PyExc_TypeError,
  				"PyClass_New: dict must be a dictionary");
  		return NULL;
***************
*** 68,72 ****
  		int i;
  		if (!PyTuple_Check(bases)) {
! 			PyErr_SetString(PyExc_SystemError,
  					"PyClass_New: bases must be a tuple");
  			return NULL;
--- 68,72 ----
  		int i;
  		if (!PyTuple_Check(bases)) {
! 			PyErr_SetString(PyExc_TypeError,
  					"PyClass_New: bases must be a tuple");
  			return NULL;
***************
*** 75,79 ****
  		while (--i >= 0) {
  			if (!PyClass_Check(PyTuple_GetItem(bases, i))) {
! 				PyErr_SetString(PyExc_SystemError,
  					"PyClass_New: base must be a class");
  				return NULL;
--- 75,79 ----
  		while (--i >= 0) {
  			if (!PyClass_Check(PyTuple_GetItem(bases, i))) {
! 				PyErr_SetString(PyExc_TypeError,
  					"PyClass_New: base must be a class");
  				return NULL;
***************
*** 107,110 ****
--- 107,122 ----
  }
  
+ static PyObject *
+ class_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+ {
+ 	PyObject *name, *bases, *dict;
+ 	static char *kwlist[] = {"name", "bases", "dict", 0};
+ 
+ 	if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO", kwlist,
+ 					 &name, &bases, &dict))
+ 		return NULL;
+ 	return PyClass_New(bases, dict, name);
+ }
+ 
  /* Class methods */
  
***************
*** 150,153 ****
--- 162,167 ----
  	register char *sname = PyString_AsString(name);
  	PyClassObject *class;
+ 	descrgetfunc f;
+ 
  	if (sname[0] == '_' && sname[1] == '_') {
  		if (strcmp(sname, "__dict__") == 0) {
***************
*** 187,190 ****
--- 201,209 ----
  		v = w;
  	}
+ 	f = v->ob_type->tp_descr_get;
+ 	if (f == NULL)
+ 		Py_INCREF(v);
+ 	else
+ 		v = f(v, (PyObject *)NULL, (PyObject *)op);
  	return v;
  }
***************
*** 397,401 ****
  	0,					/* tp_as_mapping */
  	0,					/* tp_hash */
! 	0,					/* tp_call */
  	(reprfunc)class_str,			/* tp_str */
  	(getattrofunc)class_getattr,		/* tp_getattro */
--- 416,420 ----
  	0,					/* tp_as_mapping */
  	0,					/* tp_hash */
! 	PyInstance_New,				/* tp_call */
  	(reprfunc)class_str,			/* tp_str */
  	(getattrofunc)class_getattr,		/* tp_getattro */
***************
*** 405,408 ****
--- 424,443 ----
  	0,					/* tp_doc */
  	(traverseproc)class_traverse,		/* 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 */
+ 	0,					/* tp_descr_get */
+ 	0,					/* tp_descr_set */
+ 	0,					/* tp_dictoffset */
+ 	0,					/* tp_init */
+ 	0,					/* tp_alloc */
+ 	class_new,				/* tp_new */
  };
  
***************
*** 532,536 ****
  	 * _Py_RefTotal was also boosted; we'll knock that down later.
  	 */
! 	inst->ob_type->tp_alloc--;
  #endif
  #else /* !Py_TRACE_REFS */
--- 567,571 ----
  	 * _Py_RefTotal was also boosted; we'll knock that down later.
  	 */
! 	inst->ob_type->tp_allocs--;
  #endif
  #else /* !Py_TRACE_REFS */
***************
*** 565,569 ****
  	if (--inst->ob_refcnt > 0) {
  #ifdef COUNT_ALLOCS
! 		inst->ob_type->tp_free--;
  #endif
  		return; /* __del__ added a reference; don't delete now */
--- 600,604 ----
  	if (--inst->ob_refcnt > 0) {
  #ifdef COUNT_ALLOCS
! 		inst->ob_type->tp_frees--;
  #endif
  		return; /* __del__ added a reference; don't delete now */
***************
*** 573,577 ****
  #ifdef COUNT_ALLOCS
  	/* compensate for increment in _Py_ForgetReference */
! 	inst->ob_type->tp_free--;
  #endif
  #ifndef WITH_CYCLE_GC
--- 608,612 ----
  #ifdef COUNT_ALLOCS
  	/* compensate for increment in _Py_ForgetReference */
! 	inst->ob_type->tp_frees--;
  #endif
  #ifndef WITH_CYCLE_GC
***************
*** 620,623 ****
--- 655,660 ----
  	register PyObject *v;
  	PyClassObject *class;
+ 	descrgetfunc f;
+ 
  	class = NULL;
  	v = PyDict_GetItem(inst->in_dict, name);
***************
*** 629,643 ****
  	Py_INCREF(v);
  	if (class != NULL) {
! 		if (PyFunction_Check(v)) {
! 			PyObject *w = PyMethod_New(v, (PyObject *)inst,
! 						   (PyObject *)class);
  			Py_DECREF(v);
  			v = w;
  		}
  		else if (PyMethod_Check(v)) {
! 			PyObject *im_class = PyMethod_Class(v);
  			/* Only if classes are compatible */
  			if (PyClass_IsSubclass((PyObject *)class, im_class)) {
! 				PyObject *im_func = PyMethod_Function(v);
  				PyObject *w = PyMethod_New(im_func,
  						(PyObject *)inst, im_class);
--- 666,683 ----
  	Py_INCREF(v);
  	if (class != NULL) {
! 		f = v->ob_type->tp_descr_get;
! 		if (f != NULL) {
! 			PyObject *w = f(v, (PyObject *)inst,
! 					(PyObject *)(inst->in_class));
  			Py_DECREF(v);
  			v = w;
  		}
  		else if (PyMethod_Check(v)) {
! 			/* XXX This should be a tp_descr_get slot of
! 			   PyMethodObjects */
! 			PyObject *im_class = PyMethod_GET_CLASS(v);
  			/* Only if classes are compatible */
  			if (PyClass_IsSubclass((PyObject *)class, im_class)) {
! 				PyObject *im_func = PyMethod_GET_FUNCTION(v);
  				PyObject *w = PyMethod_New(im_func,
  						(PyObject *)inst, im_class);
***************
*** 1815,1818 ****
--- 1855,1875 ----
  }
  
+ static PyObject *
+ instance_call(PyObject *func, PyObject *arg, PyObject *kw)
+ {
+ 	PyObject *res, *call = PyObject_GetAttrString(func, "__call__");
+ 	if (call == NULL) {
+ 		PyInstanceObject *inst = (PyInstanceObject*) func;
+ 		PyErr_Clear();
+ 		PyErr_Format(PyExc_AttributeError,
+ 			     "%.200s instance has no __call__ method",
+ 			     PyString_AsString(inst->in_class->cl_name));
+ 		return NULL;
+ 	}
+ 	res = PyObject_Call(call, arg, kw);
+ 	Py_DECREF(call);
+ 	return res;
+ }
+ 
  
  static PyNumberMethods instance_as_number = {
***************
*** 1869,1873 ****
  	&instance_as_mapping,			/* tp_as_mapping */
  	(hashfunc)instance_hash,		/* tp_hash */
! 	0,					/* tp_call */
  	(reprfunc)instance_str,			/* tp_str */
  	(getattrofunc)instance_getattr,		/* tp_getattro */
--- 1926,1930 ----
  	&instance_as_mapping,			/* tp_as_mapping */
  	(hashfunc)instance_hash,		/* tp_hash */
! 	instance_call,				/* tp_call */
  	(reprfunc)instance_str,			/* tp_str */
  	(getattrofunc)instance_getattr,		/* tp_getattro */
***************
*** 1922,1955 ****
  }
  
- PyObject *
- PyMethod_Function(register PyObject *im)
- {
- 	if (!PyMethod_Check(im)) {
- 		PyErr_BadInternalCall();
- 		return NULL;
- 	}
- 	return ((PyMethodObject *)im)->im_func;
- }
- 
- PyObject *
- PyMethod_Self(register PyObject *im)
- {
- 	if (!PyMethod_Check(im)) {
- 		PyErr_BadInternalCall();
- 		return NULL;
- 	}
- 	return ((PyMethodObject *)im)->im_self;
- }
- 
- PyObject *
- PyMethod_Class(register PyObject *im)
- {
- 	if (!PyMethod_Check(im)) {
- 		PyErr_BadInternalCall();
- 		return NULL;
- 	}
- 	return ((PyMethodObject *)im)->im_class;
- }
- 
  /* Class method methods */
  
--- 1979,1982 ----
***************
*** 2029,2069 ****
  instancemethod_repr(PyMethodObject *a)
  {
! 	char buf[240];
! 	PyInstanceObject *self = (PyInstanceObject *)(a->im_self);
  	PyObject *func = a->im_func;
! 	PyClassObject *class = (PyClassObject *)(a->im_class);
! 	PyObject *fclassname, *iclassname, *funcname;
! 	char *fcname, *icname, *fname;
! 	fclassname = class->cl_name;
! 	if (PyFunction_Check(func)) {
! 		funcname = ((PyFunctionObject *)func)->func_name;
! 		Py_INCREF(funcname);
! 	}
! 	else {
! 		funcname = PyObject_GetAttrString(func,"__name__");
! 		if (funcname == NULL)
! 			PyErr_Clear();
  	}
- 	if (funcname != NULL && PyString_Check(funcname))
- 		fname = PyString_AS_STRING(funcname);
  	else
! 		fname = "?";
! 	if (fclassname != NULL && PyString_Check(fclassname))
! 		fcname = PyString_AsString(fclassname);
  	else
! 		fcname = "?";
  	if (self == NULL)
! 		sprintf(buf, "<unbound method %.100s.%.100s>", fcname, fname);
  	else {
! 		iclassname = self->in_class->cl_name;
! 		if (iclassname != NULL && PyString_Check(iclassname))
! 			icname = PyString_AsString(iclassname);
! 		else
! 			icname = "?";
! 		sprintf(buf, "<method %.60s.%.60s of %.60s instance at %p>",
! 			fcname, fname, icname, self);
  	}
  	Py_XDECREF(funcname);
! 	return PyString_FromString(buf);
  }
  
--- 2056,2105 ----
  instancemethod_repr(PyMethodObject *a)
  {
! 	char buffer[240];
! 	PyObject *self = a->im_self;
  	PyObject *func = a->im_func;
! 	PyObject *klass = a->im_class;
! 	PyObject *funcname = NULL, *klassname = NULL, *result = NULL;
! 	char *sfuncname = "?", *sklassname = "?";
! 
! 	funcname = PyObject_GetAttrString(func, "__name__");
! 	if (funcname == NULL)
! 		PyErr_Clear();
! 	else if (!PyString_Check(funcname)) {
! 		Py_DECREF(funcname);
! 		funcname = NULL;
  	}
  	else
! 		sfuncname = PyString_AS_STRING(funcname);
! 	klassname = PyObject_GetAttrString(klass, "__name__");
! 	if (klassname == NULL)
! 		PyErr_Clear();
! 	else if (!PyString_Check(klassname)) {
! 		Py_DECREF(klassname);
! 		klassname = NULL;
! 	}
  	else
! 		sklassname = PyString_AS_STRING(klassname);
  	if (self == NULL)
! 		sprintf(buffer, "<unbound method %.100s.%.100s>",
! 			sklassname, sfuncname);
  	else {
! 		/* XXX Shouldn't use repr() here! */
! 		PyObject *selfrepr = PyObject_Repr(self);
! 		if (selfrepr == NULL)
! 			goto fail;
! 		if (!PyString_Check(selfrepr)) {
! 			Py_DECREF(selfrepr);
! 			goto fail;
! 		}
! 		sprintf(buffer, "<bound method %.60s.%.60s of %.60s>",
! 			sklassname, sfuncname, PyString_AS_STRING(selfrepr));
! 		Py_DECREF(selfrepr);
  	}
+ 	result = PyString_FromString(buffer);
+   fail:
  	Py_XDECREF(funcname);
! 	Py_XDECREF(klassname);
! 	return result;
  }
  
***************
*** 2106,2109 ****
--- 2142,2196 ----
  }
  
+ static PyObject *
+ instancemethod_call(PyObject *func, PyObject *arg, PyObject *kw)
+ {
+ 	PyObject *self = PyMethod_GET_SELF(func);
+ 	PyObject *class = PyMethod_GET_CLASS(func);
+ 	PyObject *result;
+ 
+ 	func = PyMethod_GET_FUNCTION(func);
+ 	if (self == NULL) {
+ 		/* Unbound methods must be called with an instance of
+ 		   the class (or a derived class) as first argument */
+ 		int ok;
+ 		if (PyTuple_Size(arg) >= 1)
+ 			self = PyTuple_GET_ITEM(arg, 0);
+ 		if (self == NULL)
+ 			ok = 0;
+ 		else {
+ 			ok = PyObject_IsInstance(self, class);
+ 			if (ok < 0)
+ 				return NULL;
+ 		}
+ 		if (!ok) {
+ 			PyErr_Format(PyExc_TypeError,
+ 				     "unbound method %s%s must be "
+ 				     "called with instance as first argument",
+ 				     PyEval_GetFuncName(func),
+ 				     PyEval_GetFuncDesc(func));
+ 			return NULL;
+ 		}
+ 		Py_INCREF(arg);
+ 	}
+ 	else {
+ 		int argcount = PyTuple_Size(arg);
+ 		PyObject *newarg = PyTuple_New(argcount + 1);
+ 		int i;
+ 		if (newarg == NULL)
+ 			return NULL;
+ 		Py_INCREF(self);
+ 		PyTuple_SET_ITEM(newarg, 0, self);
+ 		for (i = 0; i < argcount; i++) {
+ 			PyObject *v = PyTuple_GET_ITEM(arg, i);
+ 			Py_XINCREF(v);
+ 			PyTuple_SET_ITEM(newarg, i+1, v);
+ 		}
+ 		arg = newarg;
+ 	}
+ 	result = PyObject_Call((PyObject *)func, arg, kw);
+ 	Py_DECREF(arg);
+ 	return result;
+ }
+ 
  PyTypeObject PyMethod_Type = {
  	PyObject_HEAD_INIT(&PyType_Type)
***************
*** 2122,2126 ****
  	0,					/* tp_as_mapping */
  	(hashfunc)instancemethod_hash,		/* tp_hash */
! 	0,					/* tp_call */
  	0,					/* tp_str */
  	(getattrofunc)instancemethod_getattro,	/* tp_getattro */
--- 2209,2213 ----
  	0,					/* tp_as_mapping */
  	(hashfunc)instancemethod_hash,		/* tp_hash */
! 	instancemethod_call,			/* tp_call */
  	0,					/* tp_str */
  	(getattrofunc)instancemethod_getattro,	/* tp_getattro */

Index: complexobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/complexobject.c,v
retrieving revision 2.35
retrieving revision 2.36
diff -C2 -d -r2.35 -r2.36
*** complexobject.c	2001/03/18 08:21:57	2.35
--- complexobject.c	2001/08/02 04:15:00	2.36
***************
*** 9,12 ****
--- 9,13 ----
  
  #include "Python.h"
+ #include "structmember.h"
  
  /* Precisions used by repr() and str(), respectively.
***************
*** 183,186 ****
--- 184,198 ----
  }
  
+ static PyObject *
+ complex_subtype_from_c_complex(PyTypeObject *type, Py_complex cval)
+ {
+ 	PyObject *op;
+ 
+ 	op = PyType_GenericAlloc(type, 0);
+ 	if (op != NULL)
+ 		((PyComplexObject *)op)->cval = cval;
+ 	return op;
+ }
+ 
  PyObject *
  PyComplex_FromCComplex(Py_complex cval)
***************
*** 197,200 ****
--- 209,221 ----
  }
  
+ static PyObject *
+ complex_subtype_from_doubles(PyTypeObject *type, double real, double imag)
+ {
+ 	Py_complex c;
+ 	c.real = real;
+ 	c.imag = imag;
+ 	return complex_subtype_from_c_complex(type, c);
+ }
+ 
  PyObject *
  PyComplex_FromDoubles(double real, double imag)
***************
*** 560,576 ****
  };
  
  
  static PyObject *
! complex_getattr(PyComplexObject *self, char *name)
  {
! 	if (strcmp(name, "real") == 0)
! 		return (PyObject *)PyFloat_FromDouble(self->cval.real);
! 	else if (strcmp(name, "imag") == 0)
! 		return (PyObject *)PyFloat_FromDouble(self->cval.imag);
! 	else if (strcmp(name, "__members__") == 0)
! 		return Py_BuildValue("[ss]", "imag", "real");
! 	return Py_FindMethod(complex_methods, (PyObject *)self, name);
  }
  
  static PyNumberMethods complex_as_number = {
  	(binaryfunc)complex_add, 		/* nb_add */
--- 581,839 ----
  };
  
+ static struct memberlist complex_members[] = {
+ 	{"real", T_DOUBLE, offsetof(PyComplexObject, cval.real), 0},
+ 	{"imag", T_DOUBLE, offsetof(PyComplexObject, cval.imag), 0},
+ 	{0},
+ };
  
  static PyObject *
! complex_subtype_from_string(PyTypeObject *type, PyObject *v)
  {
! 	extern double strtod(const char *, char **);
! 	const char *s, *start;
! 	char *end;
! 	double x=0.0, y=0.0, z;
! 	int got_re=0, got_im=0, done=0;
! 	int digit_or_dot;
! 	int sw_error=0;
! 	int sign;
! 	char buffer[256]; /* For errors */
! 	char s_buffer[256];
! 	int len;
! 
! 	if (PyString_Check(v)) {
! 		s = PyString_AS_STRING(v);
! 		len = PyString_GET_SIZE(v);
! 	}
! 	else if (PyUnicode_Check(v)) {
! 		if (PyUnicode_GET_SIZE(v) >= sizeof(s_buffer)) {
! 			PyErr_SetString(PyExc_ValueError,
! 				 "complex() literal too large to convert");
! 			return NULL;
! 		}
! 		if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
! 					    PyUnicode_GET_SIZE(v),
! 					    s_buffer,
! 					    NULL))
! 			return NULL;
! 		s = s_buffer;
! 		len = (int)strlen(s);
! 	}
! 	else if (PyObject_AsCharBuffer(v, &s, &len)) {
! 		PyErr_SetString(PyExc_TypeError,
! 				"complex() arg is not a string");
! 		return NULL;
! 	}
! 
! 	/* position on first nonblank */
! 	start = s;
! 	while (*s && isspace(Py_CHARMASK(*s)))
! 		s++;
! 	if (s[0] == '\0') {
! 		PyErr_SetString(PyExc_ValueError,
! 				"complex() arg is an empty string");
! 		return NULL;
! 	}
! 
! 	z = -1.0;
! 	sign = 1;
! 	do {
! 
! 		switch (*s) {
! 
! 		case '\0':
! 			if (s-start != len) {
! 				PyErr_SetString(
! 					PyExc_ValueError,
! 					"complex() arg contains a null byte");
! 				return NULL;
! 			}
! 			if(!done) sw_error=1;
! 			break;
! 
! 		case '-':
! 			sign = -1;
! 				/* Fallthrough */
! 		case '+':
! 			if (done)  sw_error=1;
! 			s++;
! 			if  (  *s=='\0'||*s=='+'||*s=='-'  ||
! 			       isspace(Py_CHARMASK(*s))  )  sw_error=1;
! 			break;
! 
! 		case 'J':
! 		case 'j':
! 			if (got_im || done) {
! 				sw_error = 1;
! 				break;
! 			}
! 			if  (z<0.0) {
! 				y=sign;
! 			}
! 			else{
! 				y=sign*z;
! 			}
! 			got_im=1;
! 			s++;
! 			if  (*s!='+' && *s!='-' )
! 				done=1;
! 			break;
! 
! 		default:
! 			if (isspace(Py_CHARMASK(*s))) {
! 				while (*s && isspace(Py_CHARMASK(*s)))
! 					s++;
! 				if (s[0] != '\0')
! 					sw_error=1;
! 				else
! 					done = 1;
! 				break;
! 			}
! 			digit_or_dot =
! 				(*s=='.' || isdigit(Py_CHARMASK(*s)));
! 			if  (done||!digit_or_dot) {
! 				sw_error=1;
! 				break;
! 			}
! 			errno = 0;
! 			PyFPE_START_PROTECT("strtod", return 0)
! 				z = strtod(s, &end) ;
! 			PyFPE_END_PROTECT(z)
! 				if (errno != 0) {
! 					sprintf(buffer,
! 					  "float() out of range: %.150s", s);
! 					PyErr_SetString(
! 						PyExc_ValueError,
! 						buffer);
! 					return NULL;
! 				}
! 			s=end;
! 			if  (*s=='J' || *s=='j') {
! 
! 				break;
! 			}
! 			if  (got_re) {
! 				sw_error=1;
! 				break;
! 			}
! 
! 				/* accept a real part */
! 			x=sign*z;
! 			got_re=1;
! 			if  (got_im)  done=1;
! 			z = -1.0;
! 			sign = 1;
! 			break;
! 
! 		}  /* end of switch  */
! 
! 	} while (*s!='\0' && !sw_error);
! 
! 	if (sw_error) {
! 		PyErr_SetString(PyExc_ValueError,
! 				"complex() arg is a malformed string");
! 		return NULL;
! 	}
! 
! 	return complex_subtype_from_doubles(type, x, y);
! }
! 
! static PyObject *
! complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
! {
! 	PyObject *r, *i, *tmp;
! 	PyNumberMethods *nbr, *nbi = NULL;
! 	Py_complex cr, ci;
! 	int own_r = 0;
! 	static char *kwlist[] = {"real", "imag", 0};
! 
! 	r = Py_False;
! 	i = NULL;
! 	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:complex", kwlist,
! 					 &r, &i))
! 		return NULL;
! 	if (PyString_Check(r) || PyUnicode_Check(r))
! 		return complex_subtype_from_string(type, r);
! 	if ((nbr = r->ob_type->tp_as_number) == NULL ||
! 	    nbr->nb_float == NULL ||
! 	    (i != NULL &&
! 	     ((nbi = i->ob_type->tp_as_number) == NULL ||
! 	      nbi->nb_float == NULL))) {
! 		PyErr_SetString(PyExc_TypeError,
! 			   "complex() arg can't be converted to complex");
! 		return NULL;
! 	}
! 	/* XXX Hack to support classes with __complex__ method */
! 	if (PyInstance_Check(r)) {
! 		static PyObject *complexstr;
! 		PyObject *f;
! 		if (complexstr == NULL) {
! 			complexstr = PyString_InternFromString("__complex__");
! 			if (complexstr == NULL)
! 				return NULL;
! 		}
! 		f = PyObject_GetAttr(r, complexstr);
! 		if (f == NULL)
! 			PyErr_Clear();
! 		else {
! 			PyObject *args = Py_BuildValue("()");
! 			if (args == NULL)
! 				return NULL;
! 			r = PyEval_CallObject(f, args);
! 			Py_DECREF(args);
! 			Py_DECREF(f);
! 			if (r == NULL)
! 				return NULL;
! 			own_r = 1;
! 		}
! 	}
! 	if (PyComplex_Check(r)) {
! 		cr = ((PyComplexObject*)r)->cval;
! 		if (own_r) {
! 			Py_DECREF(r);
! 		}
! 	}
! 	else {
! 		tmp = PyNumber_Float(r);
! 		if (own_r) {
! 			Py_DECREF(r);
! 		}
! 		if (tmp == NULL)
! 			return NULL;
! 		if (!PyFloat_Check(tmp)) {
! 			PyErr_SetString(PyExc_TypeError,
! 					"float(r) didn't return a float");
! 			Py_DECREF(tmp);
! 			return NULL;
! 		}
! 		cr.real = PyFloat_AsDouble(tmp);
! 		Py_DECREF(tmp);
! 		cr.imag = 0.0;
! 	}
! 	if (i == NULL) {
! 		ci.real = 0.0;
! 		ci.imag = 0.0;
! 	}
! 	else if (PyComplex_Check(i))
! 		ci = ((PyComplexObject*)i)->cval;
! 	else {
! 		tmp = (*nbi->nb_float)(i);
! 		if (tmp == NULL)
! 			return NULL;
! 		ci.real = PyFloat_AsDouble(tmp);
! 		Py_DECREF(tmp);
! 		ci.imag = 0.;
! 	}
! 	cr.real -= ci.imag;
! 	cr.imag += ci.real;
! 	return complex_subtype_from_c_complex(type, cr);
  }
  
+ static char complex_doc[] =
+ "complex(real[, imag]) -> complex number\n\
+ \n\
+ Create a complex number from a real part and an optional imaginary part.\n\
+ This is equivalent to (real + imag*1j) where imag defaults to 0.";
+ 
  static PyNumberMethods complex_as_number = {
  	(binaryfunc)complex_add, 		/* nb_add */
***************
*** 607,611 ****
  	(destructor)complex_dealloc,		/* tp_dealloc */
  	(printfunc)complex_print,		/* tp_print */
! 	(getattrfunc)complex_getattr,		/* tp_getattr */
  	0,					/* tp_setattr */
  	0,					/* tp_compare */
--- 870,874 ----
  	(destructor)complex_dealloc,		/* tp_dealloc */
  	(printfunc)complex_print,		/* tp_print */
! 	0,					/* tp_getattr */
  	0,					/* tp_setattr */
  	0,					/* tp_compare */
***************
*** 617,628 ****
  	0,					/* tp_call */
  	(reprfunc)complex_str,			/* tp_str */
! 	0,					/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
! 	Py_TPFLAGS_DEFAULT,			/* tp_flags */
! 	0,					/* tp_doc */
  	0,					/* tp_traverse */
  	0,					/* tp_clear */
  	complex_richcompare,			/* tp_richcompare */
  };
  
--- 880,905 ----
  	0,					/* tp_call */
  	(reprfunc)complex_str,			/* tp_str */
! 	PyObject_GenericGetAttr,		/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
! 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
! 	complex_doc,				/* tp_doc */
  	0,					/* tp_traverse */
  	0,					/* tp_clear */
  	complex_richcompare,			/* tp_richcompare */
+ 	0,					/* tp_weaklistoffset */
+ 	0,					/* tp_iter */
+ 	0,					/* tp_iternext */
+ 	complex_methods,			/* tp_methods */
+ 	complex_members,			/* tp_members */
+ 	0,					/* tp_getset */
+ 	0,					/* tp_base */
+ 	0,					/* tp_dict */
+ 	0,					/* tp_descr_get */
+ 	0,					/* tp_descr_set */
+ 	0,					/* tp_dictoffset */
+ 	0,					/* tp_init */
+ 	0,					/* tp_alloc */
+ 	complex_new,				/* tp_new */
  };
  

Index: dictobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v
retrieving revision 2.106
retrieving revision 2.107
diff -C2 -d -r2.106 -r2.107
*** dictobject.c	2001/06/26 20:08:32	2.106
--- dictobject.c	2001/08/02 04:15:00	2.107
***************
*** 4,16 ****
  #include "Python.h"
  
! /* MINSIZE is the minimum size of a dictionary.  This many slots are
!  * allocated directly in the dict object (in the ma_smalltable member).
!  * It must be a power of 2, and at least 4.  8 allows dicts with no more than
!  * 5 active entries to live in ma_smalltable (and so avoid an additional
!  * malloc); instrumentation suggested this suffices for the majority of
!  * dicts (consisting mostly of usually-small instance dicts and usually-small
!  * dicts created to pass keyword arguments).
!  */
! #define MINSIZE 8
  
  /* Define this out if you don't want conversion statistics on exit. */
--- 4,9 ----
  #include "Python.h"
  
! typedef PyDictEntry dictentry;
! typedef PyDictObject dictobject;
  
  /* Define this out if you don't want conversion statistics on exit. */
***************
*** 117,183 ****
  static PyObject *dummy; /* Initialized by first call to newdictobject() */
  
- /*
- There are three kinds of slots in the table:
- 
- 1. Unused.  me_key == me_value == NULL
-    Does not hold an active (key, value) pair now and never did.  Unused can
-    transition to Active upon key insertion.  This is the only case in which
-    me_key is NULL, and is each slot's initial state.
- 
- 2. Active.  me_key != NULL and me_key != dummy and me_value != NULL
-    Holds an active (key, value) pair.  Active can transition to Dummy upon
-    key deletion.  This is the only case in which me_value != NULL.
- 
- 3. Dummy.  me_key == dummy and me_value == NULL
-    Previously held an active (key, value) pair, but that was deleted and an
-    active pair has not yet overwritten the slot.  Dummy can transition to
-    Active upon key insertion.  Dummy slots cannot be made Unused again
-    (cannot have me_key set to NULL), else the probe sequence in case of
-    collision would have no way to know they were once active.
- 
- Note: .popitem() abuses the me_hash field of an Unused or Dummy slot to
- hold a search finger.  The me_hash field of Unused or Dummy slots has no
- meaning otherwise.
- */
- typedef struct {
- 	long me_hash;      /* cached hash code of me_key */
- 	PyObject *me_key;
- 	PyObject *me_value;
- #ifdef USE_CACHE_ALIGNED
- 	long	aligner;
- #endif
- } dictentry;
- 
- /*
- To ensure the lookup algorithm terminates, there must be at least one Unused
- slot (NULL key) in the table.
- The value ma_fill is the number of non-NULL keys (sum of Active and Dummy);
- ma_used is the number of non-NULL, non-dummy keys (== the number of non-NULL
- values == the number of Active items).
- To avoid slowing down lookups on a near-full table, we resize the table when
- it's two-thirds full.
- */
- typedef struct dictobject dictobject;
- struct dictobject {
- 	PyObject_HEAD
- 	int ma_fill;  /* # Active + # Dummy */
- 	int ma_used;  /* # Active */
- 
- 	/* The table contains ma_mask + 1 slots, and that's a power of 2.
- 	 * We store the mask instead of the size because the mask is more
- 	 * frequently needed.
- 	 */
- 	int ma_mask;
- 
- 	/* ma_table points to ma_smalltable for small tables, else to
- 	 * additional malloc'ed memory.  ma_table is never NULL!  This rule
- 	 * saves repeated runtime null-tests in the workhorse getitem and
- 	 * setitem calls.
- 	 */
- 	dictentry *ma_table;
- 	dictentry *(*ma_lookup)(dictobject *mp, PyObject *key, long hash);
- 	dictentry ma_smalltable[MINSIZE];
- };
- 
  /* forward declarations */
  static dictentry *
--- 110,113 ----
***************
*** 197,206 ****
  #endif
  
! /* Set dictobject* mp to empty but w/ MINSIZE slots, using ma_smalltable. */
! #define empty_to_minsize(mp) do { 					\
! 	memset((mp)->ma_smalltable, 0, sizeof((mp)->ma_smalltable));	\
  	(mp)->ma_table = (mp)->ma_smalltable;				\
! 	(mp)->ma_mask = MINSIZE - 1;					\
  	(mp)->ma_used = (mp)->ma_fill = 0;				\
      } while(0)
  
--- 127,148 ----
  #endif
  
! /* Initialization macros.
!    There are two ways to create a dict:  PyDict_New() is the main C API
!    function, and the tp_new slot maps to dict_new().  In the latter case we
!    can save a little time over what PyDict_New does because it's guaranteed
!    that the PyDictObject struct is already zeroed out.
!    Everyone except dict_new() should use EMPTY_TO_MINSIZE (unless they have
!    an excellent reason not to).
! */
! 
! #define INIT_NONZERO_DICT_SLOTS(mp) do {				\
  	(mp)->ma_table = (mp)->ma_smalltable;				\
! 	(mp)->ma_mask = PyDict_MINSIZE - 1;				\
!     } while(0)
! 
! #define EMPTY_TO_MINSIZE(mp) do {					\
! 	memset((mp)->ma_smalltable, 0, sizeof((mp)->ma_smalltable));	\
  	(mp)->ma_used = (mp)->ma_fill = 0;				\
+ 	INIT_NONZERO_DICT_SLOTS(mp);					\
      } while(0)
  
***************
*** 220,224 ****
  	if (mp == NULL)
  		return NULL;
! 	empty_to_minsize(mp);
  	mp->ma_lookup = lookdict_string;
  #ifdef SHOW_CONVERSION_COUNTS
--- 162,166 ----
  	if (mp == NULL)
  		return NULL;
! 	EMPTY_TO_MINSIZE(mp);
  	mp->ma_lookup = lookdict_string;
  #ifdef SHOW_CONVERSION_COUNTS
***************
*** 419,423 ****
  	PyObject *old_value;
  	register dictentry *ep;
! 	ep = (mp->ma_lookup)(mp, key, hash);
  	if (ep->me_value != NULL) {
  		old_value = ep->me_value;
--- 361,368 ----
  	PyObject *old_value;
  	register dictentry *ep;
! 	typedef PyDictEntry *(*lookupfunc)(PyDictObject *, PyObject *, long);
! 
! 	assert(mp->ma_lookup != NULL);
! 	ep = mp->ma_lookup(mp, key, hash);
  	if (ep->me_value != NULL) {
  		old_value = ep->me_value;
***************
*** 450,459 ****
  	int i;
  	int is_oldtable_malloced;
! 	dictentry small_copy[MINSIZE];
  
  	assert(minused >= 0);
  
  	/* Find the smallest table size > minused. */
! 	for (newsize = MINSIZE;
  	     newsize <= minused && newsize > 0;
  	     newsize <<= 1)
--- 395,404 ----
  	int i;
  	int is_oldtable_malloced;
! 	dictentry small_copy[PyDict_MINSIZE];
  
  	assert(minused >= 0);
  
  	/* Find the smallest table size > minused. */
! 	for (newsize = PyDict_MINSIZE;
  	     newsize <= minused && newsize > 0;
  	     newsize <<= 1)
***************
*** 469,473 ****
  	is_oldtable_malloced = oldtable != mp->ma_smalltable;
  
! 	if (newsize == MINSIZE) {
  		/* A large table is shrinking, or we can't get any smaller. */
  		newtable = mp->ma_smalltable;
--- 414,418 ----
  	is_oldtable_malloced = oldtable != mp->ma_smalltable;
  
! 	if (newsize == PyDict_MINSIZE) {
  		/* A large table is shrinking, or we can't get any smaller. */
  		newtable = mp->ma_smalltable;
***************
*** 650,654 ****
  	int table_is_malloced;
  	int fill;
! 	dictentry small_copy[MINSIZE];
  #ifdef Py_DEBUG
  	int i, n;
--- 595,599 ----
  	int table_is_malloced;
  	int fill;
! 	dictentry small_copy[PyDict_MINSIZE];
  #ifdef Py_DEBUG
  	int i, n;
***************
*** 675,679 ****
  	fill = mp->ma_fill;
  	if (table_is_malloced)
! 		empty_to_minsize(mp);
  
  	else if (fill > 0) {
--- 620,624 ----
  	fill = mp->ma_fill;
  	if (table_is_malloced)
! 		EMPTY_TO_MINSIZE(mp);
  
  	else if (fill > 0) {
***************
*** 684,688 ****
  		memcpy(small_copy, table, sizeof(small_copy));
  		table = small_copy;
! 		empty_to_minsize(mp);
  	}
  	/* else it's a small table that's already empty */
--- 629,633 ----
  		memcpy(small_copy, table, sizeof(small_copy));
  		table = small_copy;
! 		EMPTY_TO_MINSIZE(mp);
  	}
  	/* else it's a small table that's already empty */
***************
*** 1043,1052 ****
  
  static PyObject *
! dict_update(register dictobject *mp, PyObject *args)
  {
  	register int i;
- 	dictobject *other;
  	dictentry *entry;
! 	PyObject *param;
  	/* We accept for the argument either a concrete dictionary object,
  	 * or an abstract "mapping" object.  For the former, we can do
--- 988,1010 ----
  
  static PyObject *
! dict_update(PyObject *mp, PyObject *args)
  {
+ 	PyObject *other;
+ 
+ 	if (!PyArg_ParseTuple(args, "O:update", &other))
+ 		return NULL;
+ 	if (PyDict_Update(mp, other) < 0)
+ 		return NULL;
+ 	Py_INCREF(Py_None);
+ 	return Py_None;
+ }
+ 
+ int
+ PyDict_Update(PyObject *a, PyObject *b)
+ {
+ 	register PyDictObject *mp, *other;
  	register int i;
  	dictentry *entry;
! 
  	/* We accept for the argument either a concrete dictionary object,
  	 * or an abstract "mapping" object.  For the former, we can do
***************
*** 1054,1065 ****
  	 * PyMapping_Keys() and PyObject_GetItem() be supported.
  	 */
! 	if (!PyArg_ParseTuple(args, "O:update", &param))
! 		return NULL;
! 
! 	if (PyDict_Check(param)) {
! 		other = (dictobject*)param;
  		if (other == mp || other->ma_used == 0)
  			/* a.update(a) or a.update({}); nothing to do */
! 			goto done;
  		/* Do one big resize at the start, rather than
  		 * incrementally resizing as we insert new items.  Expect
--- 1012,1025 ----
  	 * PyMapping_Keys() and PyObject_GetItem() be supported.
  	 */
! 	if (a == NULL || !PyDict_Check(a) || b == NULL) {
! 		PyErr_BadInternalCall();
! 		return -1;
! 	}
! 	mp = (dictobject*)a;
! 	if (PyDict_Check(b)) {
! 		other = (dictobject*)b;
  		if (other == mp || other->ma_used == 0)
  			/* a.update(a) or a.update({}); nothing to do */
! 			return 0;
  		/* Do one big resize at the start, rather than
  		 * incrementally resizing as we insert new items.  Expect
***************
*** 1068,1072 ****
  		if ((mp->ma_fill + other->ma_used)*3 >= (mp->ma_mask+1)*2) {
  		   if (dictresize(mp, (mp->ma_used + other->ma_used)*3/2) != 0)
! 			   return NULL;
  		}
  		for (i = 0; i <= other->ma_mask; i++) {
--- 1028,1032 ----
  		if ((mp->ma_fill + other->ma_used)*3 >= (mp->ma_mask+1)*2) {
  		   if (dictresize(mp, (mp->ma_used + other->ma_used)*3/2) != 0)
! 			   return -1;
  		}
  		for (i = 0; i <= other->ma_mask; i++) {
***************
*** 1082,1086 ****
  	else {
  		/* Do it the generic, slower way */
! 		PyObject *keys = PyMapping_Keys(param);
  		PyObject *iter;
  		PyObject *key, *value;
--- 1042,1046 ----
  	else {
  		/* Do it the generic, slower way */
! 		PyObject *keys = PyMapping_Keys(b);
  		PyObject *iter;
  		PyObject *key, *value;
***************
*** 1093,1109 ****
  			 * do the same for any other error.
  			 */
! 			return NULL;
  
  		iter = PyObject_GetIter(keys);
  		Py_DECREF(keys);
  		if (iter == NULL)
! 			return NULL;
  
  		for (key = PyIter_Next(iter); key; key = PyIter_Next(iter)) {
! 			value = PyObject_GetItem(param, key);
  			if (value == NULL) {
  				Py_DECREF(iter);
  				Py_DECREF(key);
! 				return NULL;
  			}
  			status = PyDict_SetItem((PyObject*)mp, key, value);
--- 1053,1069 ----
  			 * do the same for any other error.
  			 */
! 			return -1;
  
  		iter = PyObject_GetIter(keys);
  		Py_DECREF(keys);
  		if (iter == NULL)
! 			return -1;
  
  		for (key = PyIter_Next(iter); key; key = PyIter_Next(iter)) {
! 			value = PyObject_GetItem(b, key);
  			if (value == NULL) {
  				Py_DECREF(iter);
  				Py_DECREF(key);
! 				return -1;
  			}
  			status = PyDict_SetItem((PyObject*)mp, key, value);
***************
*** 1112,1116 ****
  			if (status < 0) {
  				Py_DECREF(iter);
! 				return NULL;
  			}
  		}
--- 1072,1076 ----
  			if (status < 0) {
  				Py_DECREF(iter);
! 				return -1;
  			}
  		}
***************
*** 1118,1127 ****
  		if (PyErr_Occurred())
  			/* Iterator completed, via error */
! 			return NULL;
  	}
! 	
!   done:
! 	Py_INCREF(Py_None);
! 	return Py_None;
  }
  
--- 1078,1084 ----
  		if (PyErr_Occurred())
  			/* Iterator completed, via error */
! 			return -1;
  	}
! 	return 0;
  }
  
***************
*** 1695,1704 ****
  };
  
- static PyObject *
- dict_getattr(dictobject *mp, char *name)
- {
- 	return Py_FindMethod(mapp_methods, (PyObject *)mp, name);
- }
- 
  static int
  dict_contains(dictobject *mp, PyObject *key)
--- 1652,1655 ----
***************
*** 1733,1736 ****
--- 1684,1707 ----
  
  static PyObject *
+ dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+ {
+ 	PyObject *self;
+ 
+ 	assert(type != NULL && type->tp_alloc != NULL);
+ 	self = type->tp_alloc(type, 0);
+ 	if (self != NULL) {
+ 		PyDictObject *d = (PyDictObject *)self;
+ 		/* It's guaranteed that tp->alloc zeroed out the struct. */
+ 		assert(d->ma_table == NULL && d->ma_fill == 0 && d->ma_used == 0);
+ 		INIT_NONZERO_DICT_SLOTS(d);
+ 		d->ma_lookup = lookdict_string;
+ #ifdef SHOW_CONVERSION_COUNTS
+ 		++created;
+ #endif
+ 	}
+ 	return self;
+ }
+ 
+ static PyObject *
  dict_iter(dictobject *dict)
  {
***************
*** 1746,1750 ****
  	(destructor)dict_dealloc,		/* tp_dealloc */
  	(printfunc)dict_print,			/* tp_print */
! 	(getattrfunc)dict_getattr,		/* tp_getattr */
  	0,					/* tp_setattr */
  	(cmpfunc)dict_compare,			/* tp_compare */
--- 1717,1721 ----
  	(destructor)dict_dealloc,		/* tp_dealloc */
  	(printfunc)dict_print,			/* tp_print */
! 	0,					/* tp_getattr */
  	0,					/* tp_setattr */
  	(cmpfunc)dict_compare,			/* tp_compare */
***************
*** 1756,1764 ****
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	0,					/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
! 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
! 	0,					/* tp_doc */
  	(traverseproc)dict_traverse,		/* tp_traverse */
  	(inquiry)dict_tp_clear,			/* tp_clear */
--- 1727,1736 ----
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	PyObject_GenericGetAttr,		/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
! 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC |
! 		Py_TPFLAGS_BASETYPE,		/* tp_flags */
! 	"dictionary type",			/* tp_doc */
  	(traverseproc)dict_traverse,		/* tp_traverse */
  	(inquiry)dict_tp_clear,			/* tp_clear */
***************
*** 1767,1770 ****
--- 1739,1753 ----
  	(getiterfunc)dict_iter,			/* tp_iter */
  	0,					/* tp_iternext */
+ 	mapp_methods,				/* tp_methods */
+ 	0,					/* tp_members */
+ 	0,					/* tp_getset */
+ 	0,					/* tp_base */
+ 	0,					/* tp_dict */
+ 	0,					/* tp_descr_get */
+ 	0,					/* tp_descr_set */
+ 	0,					/* tp_dictoffset */
+ 	0,					/* tp_init */
+ 	PyType_GenericAlloc,			/* tp_alloc */
+ 	dict_new,				/* tp_new */
  };
  
***************
*** 1874,1883 ****
  };
  
- static PyObject *
- dictiter_getattr(dictiterobject *di, char *name)
- {
- 	return Py_FindMethod(dictiter_methods, (PyObject *)di, name);
- }
- 
  static PyObject *dictiter_iternext(dictiterobject *di)
  {
--- 1857,1860 ----
***************
*** 1904,1908 ****
  	(destructor)dictiter_dealloc, 		/* tp_dealloc */
  	0,					/* tp_print */
! 	(getattrfunc)dictiter_getattr,		/* tp_getattr */
  	0,					/* tp_setattr */
  	0,					/* tp_compare */
--- 1881,1885 ----
  	(destructor)dictiter_dealloc, 		/* tp_dealloc */
  	0,					/* tp_print */
! 	0,					/* tp_getattr */
  	0,					/* tp_setattr */
  	0,					/* tp_compare */
***************
*** 1914,1918 ****
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	0,					/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
--- 1891,1895 ----
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	PyObject_GenericGetAttr,		/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
***************
*** 1925,1927 ****
--- 1902,1911 ----
  	(getiterfunc)dictiter_getiter,		/* tp_iter */
  	(iternextfunc)dictiter_iternext,	/* tp_iternext */
+ 	dictiter_methods,			/* tp_methods */
+ 	0,					/* tp_members */
+ 	0,					/* tp_getset */
+ 	0,					/* tp_base */
+ 	0,					/* tp_dict */
+ 	0,					/* tp_descr_get */
+ 	0,					/* tp_descr_set */
  };

Index: fileobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v
retrieving revision 2.114
retrieving revision 2.115
diff -C2 -d -r2.114 -r2.115
*** fileobject.c	2001/07/19 21:49:38	2.114
--- fileobject.c	2001/08/02 04:15:00	2.115
***************
*** 1274,1300 ****
  
  static PyObject *
! file_getattr(PyFileObject *f, char *name)
  {
! 	PyObject *res;
! 
! 	res = Py_FindMethod(file_methods, (PyObject *)f, name);
! 	if (res != NULL)
! 		return res;
! 	PyErr_Clear();
! 	if (strcmp(name, "closed") == 0)
! 		return PyInt_FromLong((long)(f->f_fp == 0));
! 	return PyMember_Get((char *)f, file_memberlist, name);
  }
  
! static int
! file_setattr(PyFileObject *f, char *name, PyObject *v)
! {
! 	if (v == NULL) {
! 		PyErr_SetString(PyExc_AttributeError,
! 				"can't delete file attributes");
! 		return -1;
! 	}
! 	return PyMember_Set((char *)f, file_memberlist, name, v);
! }
  
  static PyObject *
--- 1274,1286 ----
  
  static PyObject *
! get_closed(PyFileObject *f, void *closure)
  {
! 	return PyInt_FromLong((long)(f->f_fp == 0));
  }
  
! static struct getsetlist file_getsetlist[] = {
! 	{"closed", (getter)get_closed, NULL, NULL},
! 	{0},
! };
  
  static PyObject *
***************
*** 1312,1319 ****
  	(destructor)file_dealloc,		/* tp_dealloc */
  	0,					/* tp_print */
! 	(getattrfunc)file_getattr,		/* tp_getattr */
! 	(setattrfunc)file_setattr,		/* tp_setattr */
  	0,					/* tp_compare */
! 	(reprfunc)file_repr,			/* tp_repr */
  	0,					/* tp_as_number */
  	0,					/* tp_as_sequence */
--- 1298,1305 ----
  	(destructor)file_dealloc,		/* tp_dealloc */
  	0,					/* tp_print */
! 	0,			 		/* tp_getattr */
! 	0,			 		/* tp_setattr */
  	0,					/* tp_compare */
! 	(reprfunc)file_repr, 			/* tp_repr */
  	0,					/* tp_as_number */
  	0,					/* tp_as_sequence */
***************
*** 1322,1336 ****
  	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 */
!  	0,					/* tp_clear */
  	0,					/* tp_richcompare */
  	0,					/* tp_weaklistoffset */
  	file_getiter,				/* tp_iter */
  	0,					/* tp_iternext */
  };
  
--- 1308,1327 ----
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	PyObject_GenericGetAttr,		/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
  	Py_TPFLAGS_DEFAULT,			/* tp_flags */
! 	0,					/* tp_doc */
! 	0,					/* tp_traverse */
! 	0,					/* tp_clear */
  	0,					/* tp_richcompare */
  	0,					/* tp_weaklistoffset */
  	file_getiter,				/* tp_iter */
  	0,					/* tp_iternext */
+ 	file_methods,				/* tp_methods */
+ 	file_memberlist,			/* tp_members */
+ 	file_getsetlist,			/* tp_getset */
+ 	0,					/* tp_base */
+ 	0,					/* tp_dict */
  };
  

Index: floatobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v
retrieving revision 2.83
retrieving revision 2.84
diff -C2 -d -r2.83 -r2.84
*** floatobject.c	2001/07/26 20:02:17	2.83
--- floatobject.c	2001/08/02 04:15:00	2.84
***************
*** 637,640 ****
--- 637,660 ----
  
  
+ static PyObject *
+ float_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+ {
+ 	PyObject *x = Py_False; /* Integer zero */
+ 	static char *kwlist[] = {"x", 0};
+ 
+ 	assert(type == &PyFloat_Type);
+ 	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:float", kwlist, &x))
+ 		return NULL;
+ 	if (PyString_Check(x))
+ 		return PyFloat_FromString(x, NULL);
+ 	return PyNumber_Float(x);
+ }
+ 
+ static char float_doc[] =
+ "float(x) -> floating point number\n\
+ \n\
+ Convert a string or number to a floating point number, if possible.";
+ 
+ 
  static PyNumberMethods float_as_number = {
  	(binaryfunc)float_add, /*nb_add*/
***************
*** 680,699 ****
  	sizeof(PyFloatObject),
  	0,
! 	(destructor)float_dealloc, /*tp_dealloc*/
! 	(printfunc)float_print, /*tp_print*/
! 	0,			/*tp_getattr*/
! 	0,			/*tp_setattr*/
! 	(cmpfunc)float_compare, /*tp_compare*/
! 	(reprfunc)float_repr,	/*tp_repr*/
! 	&float_as_number,	/*tp_as_number*/
! 	0,			/*tp_as_sequence*/
! 	0,			/*tp_as_mapping*/
! 	(hashfunc)float_hash,	/*tp_hash*/
!         0,			/*tp_call*/
!         (reprfunc)float_str,	/*tp_str*/
! 	0,			/*tp_getattro*/
! 	0,			/*tp_setattro*/
! 	0,			/*tp_as_buffer*/
! 	Py_TPFLAGS_CHECKTYPES	/*tp_flags*/
  };
  
--- 700,737 ----
  	sizeof(PyFloatObject),
  	0,
! 	(destructor)float_dealloc,		/* tp_dealloc */
! 	(printfunc)float_print, 		/* tp_print */
! 	0,					/* tp_getattr */
! 	0,					/* tp_setattr */
! 	(cmpfunc)float_compare, 		/* tp_compare */
! 	(reprfunc)float_repr,			/* tp_repr */
! 	&float_as_number,			/* tp_as_number */
! 	0,					/* tp_as_sequence */
! 	0,					/* tp_as_mapping */
! 	(hashfunc)float_hash,			/* tp_hash */
! 	0,					/* tp_call */
! 	(reprfunc)float_str,			/* tp_str */
! 	PyObject_GenericGetAttr,		/* tp_getattro */
! 	0,					/* tp_setattro */
! 	0,					/* tp_as_buffer */
! 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
! 	float_doc,				/* 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 */
! 	0,					/* tp_descr_get */
! 	0,					/* tp_descr_set */
! 	0,					/* tp_dictoffset */
! 	0,					/* tp_init */
! 	0,					/* tp_alloc */
! 	float_new,				/* tp_new */
  };
  

Index: frameobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/frameobject.c,v
retrieving revision 2.53
retrieving revision 2.54
diff -C2 -d -r2.53 -r2.54
*** frameobject.c	2001/07/12 13:27:11	2.53
--- frameobject.c	2001/08/02 04:15:00	2.54
***************
*** 16,20 ****
  	{"f_builtins",	T_OBJECT,	OFF(f_builtins),RO},
  	{"f_globals",	T_OBJECT,	OFF(f_globals),	RO},
- 	{"f_locals",	T_OBJECT,	OFF(f_locals),	RO},
  	{"f_lasti",	T_INT,		OFF(f_lasti),	RO},
  	{"f_lineno",	T_INT,		OFF(f_lineno),	RO},
--- 16,19 ----
***************
*** 28,43 ****
  
  static PyObject *
! frame_getattr(PyFrameObject *f, char *name)
  {
! 	if (strcmp(name, "f_locals") == 0)
! 		PyFrame_FastToLocals(f);
! 	return PyMember_Get((char *)f, frame_memberlist, name);
  }
  
! static int
! frame_setattr(PyFrameObject *f, char *name, PyObject *value)
! {
! 	return PyMember_Set((char *)f, frame_memberlist, name, value);
! }
  
  /* Stack frames are allocated and deallocated at a considerable rate.
--- 27,41 ----
  
  static PyObject *
! frame_getlocals(PyFrameObject *f, void *closure)
  {
! 	PyFrame_FastToLocals(f);
! 	Py_INCREF(f->f_locals);
! 	return f->f_locals;
  }
  
! static struct getsetlist frame_getsetlist[] = {
! 	{"f_locals",	(getter)frame_getlocals, NULL, NULL},
! 	{0}
! };
  
  /* Stack frames are allocated and deallocated at a considerable rate.
***************
*** 178,183 ****
  	(destructor)frame_dealloc, 		/* tp_dealloc */
  	0,					/* tp_print */
! 	(getattrfunc)frame_getattr, 		/* tp_getattr */
! 	(setattrfunc)frame_setattr, 		/* tp_setattr */
  	0,					/* tp_compare */
  	0,					/* tp_repr */
--- 176,181 ----
  	(destructor)frame_dealloc, 		/* tp_dealloc */
  	0,					/* tp_print */
! 	0, 					/* tp_getattr */
! 	0,			 		/* tp_setattr */
  	0,					/* tp_compare */
  	0,					/* tp_repr */
***************
*** 188,193 ****
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	0,					/* tp_getattro */
! 	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
  	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
--- 186,191 ----
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	PyObject_GenericGetAttr,		/* tp_getattro */
! 	PyObject_GenericSetAttr,		/* tp_setattro */
  	0,					/* tp_as_buffer */
  	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
***************
*** 195,198 ****
--- 193,205 ----
   	(traverseproc)frame_traverse,		/* tp_traverse */
  	(inquiry)frame_clear,			/* tp_clear */
+ 	0,					/* tp_richcompare */
+ 	0,					/* tp_weaklistoffset */
+ 	0,					/* tp_iter */
+ 	0,					/* tp_iternext */
+ 	0,					/* tp_methods */
+ 	frame_memberlist,			/* tp_members */
+ 	frame_getsetlist,			/* tp_getset */
+ 	0,					/* tp_base */
+ 	0,					/* tp_dict */
  };
  

Index: funcobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/funcobject.c,v
retrieving revision 2.38
retrieving revision 2.39
diff -C2 -d -r2.38 -r2.39
*** funcobject.c	2001/05/03 16:04:13	2.38
--- funcobject.c	2001/08/02 04:15:00	2.39
***************
*** 4,7 ****
--- 4,8 ----
  #include "Python.h"
  #include "compile.h"
+ #include "eval.h"
  #include "structmember.h"
  
***************
*** 142,148 ****
  
  static PyObject *
! func_getattro(PyFunctionObject *op, PyObject *name)
  {
- 	PyObject *rtn;
  	char *sname = PyString_AsString(name);
  	
--- 143,148 ----
  
  static PyObject *
! func_getattro(PyObject *op, PyObject *name)
  {
  	char *sname = PyString_AsString(name);
  	
***************
*** 152,175 ****
  		return NULL;
  	}
- 
- 	/* no API for PyMember_HasAttr() */
- 	rtn = PyMember_Get((char *)op, func_memberlist, sname);
  
! 	if (rtn == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
! 		PyErr_Clear();
! 		if (op->func_dict != NULL) {
! 			rtn = PyDict_GetItem(op->func_dict, name);
! 			Py_XINCREF(rtn);
! 		}
! 		if (rtn == NULL)
! 			PyErr_SetObject(PyExc_AttributeError, name);
! 	}
! 	return rtn;
  }
  
  static int
! func_setattro(PyFunctionObject *op, PyObject *name, PyObject *value)
  {
- 	int rtn;
  	char *sname = PyString_AsString(name);
  
--- 152,162 ----
  		return NULL;
  	}
  
! 	return PyObject_GenericGetAttr(op, name);
  }
  
  static int
! func_setattro(PyObject *op, PyObject *name, PyObject *value)
  {
  	char *sname = PyString_AsString(name);
  
***************
*** 217,245 ****
  	}
  
! 	rtn = PyMember_Set((char *)op, func_memberlist, sname, value);
! 	if (rtn < 0 && PyErr_ExceptionMatches(PyExc_AttributeError)) {
! 		PyErr_Clear();
! 		if (op->func_dict == NULL) {
! 			/* don't create the dict if we're deleting an
! 			 * attribute.  In that case, we know we'll get an
! 			 * AttributeError.
! 			 */
! 			if (value == NULL) {
! 				PyErr_SetString(PyExc_AttributeError, sname);
! 				return -1;
! 			}
! 			op->func_dict = PyDict_New();
! 			if (op->func_dict == NULL)
! 				return -1;
! 		}
!                 if (value == NULL)
! 			rtn = PyDict_DelItem(op->func_dict, name);
!                 else
! 			rtn = PyDict_SetItem(op->func_dict, name, value);
! 		/* transform KeyError into AttributeError */
! 		if (rtn < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
! 			PyErr_SetString(PyExc_AttributeError, sname);
! 	}
! 	return rtn;
  }
  
--- 204,208 ----
  	}
  
! 	return PyObject_GenericSetAttr(op, name, value);
  }
  
***************
*** 315,318 ****
--- 278,341 ----
  }
  
+ static PyObject *
+ function_call(PyObject *func, PyObject *arg, PyObject *kw)
+ {
+ 	PyObject *result;
+ 	PyObject *argdefs;
+ 	PyObject **d, **k;
+ 	int nk, nd;
+ 
+ 	argdefs = PyFunction_GET_DEFAULTS(func);
+ 	if (argdefs != NULL && PyTuple_Check(argdefs)) {
+ 		d = &PyTuple_GET_ITEM((PyTupleObject *)argdefs, 0);
+ 		nd = PyTuple_Size(argdefs);
+ 	}
+ 	else {
+ 		d = NULL;
+ 		nd = 0;
+ 	}
+ 
+ 	if (kw != NULL && PyDict_Check(kw)) {
+ 		int pos, i;
+ 		nk = PyDict_Size(kw);
+ 		k = PyMem_NEW(PyObject *, 2*nk);
+ 		if (k == NULL) {
+ 			PyErr_NoMemory();
+ 			Py_DECREF(arg);
+ 			return NULL;
+ 		}
+ 		pos = i = 0;
+ 		while (PyDict_Next(kw, &pos, &k[i], &k[i+1]))
+ 			i += 2;
+ 		nk = i/2;
+ 		/* XXX This is broken if the caller deletes dict items! */
+ 	}
+ 	else {
+ 		k = NULL;
+ 		nk = 0;
+ 	}
+ 
+ 	result = PyEval_EvalCodeEx(
+ 		(PyCodeObject *)PyFunction_GET_CODE(func),
+ 		PyFunction_GET_GLOBALS(func), (PyObject *)NULL,
+ 		&PyTuple_GET_ITEM(arg, 0), PyTuple_Size(arg),
+ 		k, nk, d, nd,
+ 		PyFunction_GET_CLOSURE(func));
+ 
+ 	if (k != NULL)
+ 		PyMem_DEL(k);
+ 
+ 	return result;
+ }
+ 
+ /* Bind a function to an object */
+ static PyObject *
+ func_descr_get(PyObject *func, PyObject *obj, PyObject *type)
+ {
+ 	if (obj == Py_None)
+ 		obj = NULL;
+ 	return PyMethod_New(func, obj, type);
+ }
+ 
  PyTypeObject PyFunction_Type = {
  	PyObject_HEAD_INIT(&PyType_Type)
***************
*** 321,344 ****
  	sizeof(PyFunctionObject) + PyGC_HEAD_SIZE,
  	0,
! 	(destructor)func_dealloc,            /* tp_dealloc */
! 	0,                                   /* tp_print */
! 	0,                                   /* tp_getattr */
! 	0,                                   /* tp_setattr */
! 	0,                                   /* tp_compare */
! 	(reprfunc)func_repr,                 /* tp_repr */
! 	0,                                   /* tp_as_number */
! 	0,                                   /* tp_as_sequence */
! 	0,                                   /* tp_as_mapping */
! 	0,                                   /* tp_hash */
! 	0,                                   /* tp_call */
! 	0,                                   /* tp_str */
! 	(getattrofunc)func_getattro,	     /* tp_getattro */
! 	(setattrofunc)func_setattro,         /* tp_setattro */
! 	0,                                   /* tp_as_buffer */
! 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,  /* tp_flags */
! 	0,                                   /* tp_doc */
! 	(traverseproc)func_traverse,	     /* tp_traverse */
! 	0,                                   /* tp_clear */
! 	0,                                   /* tp_richcompare */
  	offsetof(PyFunctionObject, func_weakreflist), /* tp_weaklistoffset */
  };
--- 344,600 ----
  	sizeof(PyFunctionObject) + PyGC_HEAD_SIZE,
  	0,
! 	(destructor)func_dealloc,		/* tp_dealloc */
! 	0,					/* tp_print */
! 	0,					/* tp_getattr */
! 	0,					/* tp_setattr */
! 	0,					/* tp_compare */
! 	(reprfunc)func_repr,			/* tp_repr */
! 	0,					/* tp_as_number */
! 	0,					/* tp_as_sequence */
! 	0,					/* tp_as_mapping */
! 	0,					/* tp_hash */
! 	function_call,				/* tp_call */
! 	0,					/* tp_str */
! 	func_getattro,				/* tp_getattro */
! 	func_setattro,				/* tp_setattro */
! 	0,					/* tp_as_buffer */
! 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
! 	0,					/* tp_doc */
! 	(traverseproc)func_traverse,		/* tp_traverse */
! 	0,					/* tp_clear */
! 	0,					/* tp_richcompare */
  	offsetof(PyFunctionObject, func_weakreflist), /* tp_weaklistoffset */
+ 	0,					/* tp_iter */
+ 	0,					/* tp_iternext */
+ 	0,					/* tp_methods */
+ 	func_memberlist,			/* tp_members */
+ 	0,					/* tp_getset */
+ 	0,					/* tp_base */
+ 	0,					/* tp_dict */
+ 	func_descr_get,				/* tp_descr_get */
+ 	0,					/* tp_descr_set */
+ 	offsetof(PyFunctionObject, func_dict),	/* tp_dictoffset */
+ };
+ 
+ 
+ /* Class method object */
+ 
+ /* A class method receives the class as implicit first argument,
+    just like an instance method receives the instance.
+    To declare a class method, use this idiom:
+ 
+      class C:
+          def f(cls, arg1, arg2, ...): ...
+ 	 f = classmethod(f)
+    
+    It can be called either on the class (e.g. C.f()) or on an instance
+    (e.g. C().f()); the instance is ignored except for its class.
+    If a class method is called for a derived class, the derived class
+    object is passed as the implied first argument.
+ 
+    Class methods are different than C++ or Java static methods.
+    If you want those, see static methods below.
+ */
+ 
+ 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, PyObject *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,
+ 			    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 */
+ };
+ 
+ PyObject *
+ PyClassMethod_New(PyObject *callable)
+ {
+ 	classmethod *cm = (classmethod *)
+ 		PyType_GenericAlloc(&PyClassMethod_Type, 0);
+ 	if (cm != NULL) {
+ 		Py_INCREF(callable);
+ 		cm->cm_callable = callable;
+ 	}
+ 	return (PyObject *)cm;
+ }
+ 
+ 
+ /* Static method object */
+ 
+ /* A static method does not receive an implicit first argument.
+    To declare a static method, use this idiom:
+ 
+      class C:
+          def f(arg1, arg2, ...): ...
+ 	 f = staticmethod(f)
+ 
+    It can be called either on the class (e.g. C.f()) or on an instance
+    (e.g. C().f()); the instance is ignored except for its class.
+ 
+    Static methods in Python are similar to those found in Java or C++.
+    For a more advanced concept, see class methods above.
+ */
+ 
+ typedef struct {
+ 	PyObject_HEAD
+ 	PyObject *sm_callable;
+ } staticmethod;
+ 
+ static void
+ sm_dealloc(staticmethod *sm)
+ {
+ 	Py_XDECREF(sm->sm_callable);
+ 	PyObject_DEL(sm);
+ }
+ 
+ static PyObject *
+ sm_descr_get(PyObject *self, PyObject *obj, PyObject *type)
+ {
+ 	staticmethod *sm = (staticmethod *)self;
+ 
+ 	if (sm->sm_callable == NULL) {
+ 		PyErr_SetString(PyExc_RuntimeError,
+ 				"uninitialized staticmethod object");
+ 		return NULL;
+ 	}
+ 	Py_INCREF(sm->sm_callable);
+ 	return sm->sm_callable;
+ }
+ 
+ static int
+ sm_init(PyObject *self, PyObject *args, PyObject *kwds)
+ {
+ 	staticmethod *sm = (staticmethod *)self;
+ 	PyObject *callable;
+ 
+ 	if (!PyArg_ParseTuple(args, "O:callable", &callable))
+ 		return -1;
+ 	Py_INCREF(callable);
+ 	sm->sm_callable = callable;
+ 	return 0;
+ }
+ 
+ PyTypeObject PyStaticMethod_Type = {
+ 	PyObject_HEAD_INIT(&PyType_Type)
+ 	0,
+ 	"staticmethod",
+ 	sizeof(staticmethod),
+ 	0,
+ 	(destructor)sm_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 */
+ 	sm_descr_get,				/* tp_descr_get */
+ 	0,					/* tp_descr_set */
+ 	0,					/* tp_dictoffset */
+ 	sm_init,				/* tp_init */
+ 	PyType_GenericAlloc,			/* tp_alloc */
+ 	PyType_GenericNew,			/* tp_new */
  };
+ 
+ PyObject *
+ PyStaticMethod_New(PyObject *callable)
+ {
+ 	staticmethod *sm = (staticmethod *)
+ 		PyType_GenericAlloc(&PyStaticMethod_Type, 0);
+ 	if (sm != NULL) {
+ 		Py_INCREF(callable);
+ 		sm->sm_callable = callable;
+ 	}
+ 	return (PyObject *)sm;
+ }

Index: intobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v
retrieving revision 2.59
retrieving revision 2.60
diff -C2 -d -r2.59 -r2.60
*** intobject.c	2001/07/19 21:49:38	2.59
--- intobject.c	2001/08/02 04:15:00	2.60
***************
*** 743,746 ****
--- 743,781 ----
  }
  
+ static PyObject *
+ int_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+ {
+ 	PyObject *x = NULL;
+ 	int base = -909;
+ 	static char *kwlist[] = {"x", "base", 0};
+ 
+ 	assert(type == &PyInt_Type);
+ 	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist,
+ 					 &x, &base))
+ 		return NULL;
+ 	if (x == NULL)
+ 		return PyInt_FromLong(0L);
+ 	if (base == -909)
+ 		return PyNumber_Int(x);
+ 	if (PyString_Check(x))
+ 		return PyInt_FromString(PyString_AS_STRING(x), NULL, base);
+ 	if (PyUnicode_Check(x))
+ 		return PyInt_FromUnicode(PyUnicode_AS_UNICODE(x),
+ 					 PyUnicode_GET_SIZE(x),
+ 					 base);
+ 	PyErr_SetString(PyExc_TypeError,
+ 			"int() can't convert non-string with explicit base");
+ 	return NULL;
+ }
+ 
+ static char int_doc[] =
+ "int(x[, base]) -> integer\n\
+ \n\
+ Convert a string or number to an integer, if possible.  A floating point\n\
+ argument will be truncated towards zero (this does not include a string\n\
+ representation of a floating point number!)  When converting a string, use\n\
+ the optional base.  It is an error to supply a base when converting a\n\
+ non-string.";
+ 
  static PyNumberMethods int_as_number = {
  	(binaryfunc)int_add,	/*nb_add*/
***************
*** 786,805 ****
  	sizeof(PyIntObject),
  	0,
! 	(destructor)int_dealloc, /*tp_dealloc*/
! 	(printfunc)int_print, /*tp_print*/
! 	0,		/*tp_getattr*/
! 	0,		/*tp_setattr*/
! 	(cmpfunc)int_compare, /*tp_compare*/
! 	(reprfunc)int_repr, /*tp_repr*/
! 	&int_as_number,	/*tp_as_number*/
! 	0,		/*tp_as_sequence*/
! 	0,		/*tp_as_mapping*/
! 	(hashfunc)int_hash, /*tp_hash*/
!         0,			/*tp_call*/
!         0,			/*tp_str*/
! 	0,			/*tp_getattro*/
! 	0,			/*tp_setattro*/
! 	0,			/*tp_as_buffer*/
! 	Py_TPFLAGS_CHECKTYPES	/*tp_flags*/
  };
  
--- 821,858 ----
  	sizeof(PyIntObject),
  	0,
! 	(destructor)int_dealloc,		/* tp_dealloc */
! 	(printfunc)int_print,			/* tp_print */
! 	0,					/* tp_getattr */
! 	0,					/* tp_setattr */
! 	(cmpfunc)int_compare,			/* tp_compare */
! 	(reprfunc)int_repr,			/* tp_repr */
! 	&int_as_number,				/* tp_as_number */
! 	0,					/* tp_as_sequence */
! 	0,					/* tp_as_mapping */
! 	(hashfunc)int_hash,			/* tp_hash */
!         0,					/* tp_call */
!         0,					/* tp_str */
! 	PyObject_GenericGetAttr,		/* tp_getattro */
! 	0,					/* tp_setattro */
! 	0,					/* tp_as_buffer */
! 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
! 	int_doc,				/* 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 */
! 	0,					/* tp_descr_get */
! 	0,					/* tp_descr_set */
! 	0,					/* tp_dictoffset */
! 	0,					/* tp_init */
! 	0,					/* tp_alloc */
! 	int_new,				/* tp_new */
  };
  

Index: iterobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/iterobject.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** iterobject.c	2001/07/12 13:27:25	1.5
--- iterobject.c	2001/08/02 04:15:00	1.6
***************
*** 97,106 ****
  };
  
- static PyObject *
- iter_getattr(seqiterobject *it, char *name)
- {
- 	return Py_FindMethod(iter_methods, (PyObject *)it, name);
- }
- 
  PyTypeObject PySeqIter_Type = {
  	PyObject_HEAD_INIT(&PyType_Type)
--- 97,100 ----
***************
*** 112,116 ****
  	(destructor)iter_dealloc, 		/* tp_dealloc */
  	0,					/* tp_print */
! 	(getattrfunc)iter_getattr,		/* tp_getattr */
  	0,					/* tp_setattr */
  	0,					/* tp_compare */
--- 106,110 ----
  	(destructor)iter_dealloc, 		/* tp_dealloc */
  	0,					/* tp_print */
! 	0,					/* tp_getattr */
  	0,					/* tp_setattr */
  	0,					/* tp_compare */
***************
*** 122,126 ****
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	0,					/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
--- 116,120 ----
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	PyObject_GenericGetAttr,		/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
***************
*** 133,136 ****
--- 127,137 ----
  	(getiterfunc)iter_getiter,		/* tp_iter */
  	(iternextfunc)iter_iternext,		/* tp_iternext */
+ 	iter_methods,				/* tp_methods */
+ 	0,					/* tp_members */
+ 	0,					/* tp_getset */
+ 	0,					/* tp_base */
+ 	0,					/* tp_dict */
+ 	0,					/* tp_descr_get */
+ 	0,					/* tp_descr_set */
  };
  
***************
*** 199,208 ****
  
  static PyObject *
- calliter_getattr(calliterobject *it, char *name)
- {
- 	return Py_FindMethod(calliter_methods, (PyObject *)it, name);
- }
- 
- static PyObject *
  calliter_iternext(calliterobject *it)
  {
--- 200,203 ----
***************
*** 229,233 ****
  	(destructor)calliter_dealloc, 		/* tp_dealloc */
  	0,					/* tp_print */
! 	(getattrfunc)calliter_getattr,		/* tp_getattr */
  	0,					/* tp_setattr */
  	0,					/* tp_compare */
--- 224,228 ----
  	(destructor)calliter_dealloc, 		/* tp_dealloc */
  	0,					/* tp_print */
! 	0,					/* tp_getattr */
  	0,					/* tp_setattr */
  	0,					/* tp_compare */
***************
*** 239,243 ****
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	0,					/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
--- 234,238 ----
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	PyObject_GenericGetAttr,		/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
***************
*** 250,252 ****
--- 245,254 ----
  	(getiterfunc)iter_getiter,		/* tp_iter */
  	(iternextfunc)calliter_iternext,	/* tp_iternext */
+ 	calliter_methods,			/* tp_methods */
+ 	0,					/* tp_members */
+ 	0,					/* tp_getset */
+ 	0,					/* tp_base */
+ 	0,					/* tp_dict */
+ 	0,					/* tp_descr_get */
+ 	0,					/* tp_descr_set */
  };

Index: listobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v
retrieving revision 2.97
retrieving revision 2.98
diff -C2 -d -r2.97 -r2.98
*** listobject.c	2001/07/06 17:45:43	2.97
--- listobject.c	2001/08/02 04:15:00	2.98
***************
*** 524,527 ****
--- 524,531 ----
  		PyMem_DEL(recycle);
  	}
+ 	if (a->ob_size == 0 && a->ob_item != NULL) {
+ 		PyMem_FREE(a->ob_item);
+ 		a->ob_item = NULL;
+ 	}
  	return 0;
  #undef b
***************
*** 1290,1293 ****
--- 1294,1298 ----
  	int err;
  	PyObject *compare = NULL;
+ 	PyTypeObject *savetype;
  
  	if (args != NULL) {
***************
*** 1295,1303 ****
  			return NULL;
  	}
  	self->ob_type = &immutable_list_type;
  	err = samplesortslice(self->ob_item,
  			      self->ob_item + self->ob_size,
  			      compare);
! 	self->ob_type = &PyList_Type;
  	if (err < 0)
  		return NULL;
--- 1300,1309 ----
  			return NULL;
  	}
+ 	savetype = self->ob_type;
  	self->ob_type = &immutable_list_type;
  	err = samplesortslice(self->ob_item,
  			      self->ob_item + self->ob_size,
  			      compare);
! 	self->ob_type = savetype;
  	if (err < 0)
  		return NULL;
***************
*** 1542,1545 ****
--- 1548,1645 ----
  }
  
+ /* Adapted from newer code by Tim */
+ static int
+ list_fill(PyListObject *result, PyObject *v)
+ {
+ 	PyObject *it;      /* iter(v) */
+ 	int n;		   /* guess for result list size */
+ 	int i;
+ 
+ 	n = result->ob_size;
+ 
+ 	/* Special-case list(a_list), for speed. */
+ 	if (PyList_Check(v)) {
+ 		if (v == (PyObject *)result)
+ 			return 0; /* source is destination, we're done */
+ 		return list_ass_slice(result, 0, n, v);
+ 	}
+ 
+ 	/* Empty previous contents */
+ 	if (n != 0) {
+ 		if (list_ass_slice(result, 0, n, (PyObject *)NULL) != 0)
+ 			return -1;
+ 	}
+ 
+ 	/* Get iterator.  There may be some low-level efficiency to be gained
+ 	 * by caching the tp_iternext slot instead of using PyIter_Next()
+ 	 * later, but premature optimization is the root etc.
+ 	 */
+ 	it = PyObject_GetIter(v);
+ 	if (it == NULL)
+ 		return -1;
+ 
+ 	/* Guess a result list size. */
+ 	n = -1;	 /* unknown */
+ 	if (PySequence_Check(v) &&
+ 	    v->ob_type->tp_as_sequence->sq_length) {
+ 		n = PySequence_Size(v);
+ 		if (n < 0)
+ 			PyErr_Clear();
+ 	}
+ 	if (n < 0)
+ 		n = 8;	/* arbitrary */
+ 	NRESIZE(result->ob_item, PyObject*, n);
+ 	if (result->ob_item == NULL)
+ 		goto error;
+ 	for (i = 0; i < n; i++)
+ 		result->ob_item[i] = NULL;
+ 	result->ob_size = n;
+ 
+ 	/* Run iterator to exhaustion. */
+ 	for (i = 0; ; i++) {
+ 		PyObject *item = PyIter_Next(it);
+ 		if (item == NULL) {
+ 			if (PyErr_Occurred())
+ 				goto error;
+ 			break;
+ 		}
+ 		if (i < n)
+ 			PyList_SET_ITEM(result, i, item); /* steals ref */
+ 		else {
+ 			int status = ins1(result, result->ob_size, item);
+ 			Py_DECREF(item);  /* append creates a new ref */
+ 			if (status < 0)
+ 				goto error;
+ 		}
+ 	}
+ 
+ 	/* Cut back result list if initial guess was too large. */
+ 	if (i < n && result != NULL) {
+ 		if (list_ass_slice(result, i, n, (PyObject *)NULL) != 0)
+ 			goto error;
+ 	}
+ 	Py_DECREF(it);
+ 	return 0;
+ 
+   error:
+ 	Py_DECREF(it);
+ 	return -1;
+ }
+ 
+ static int
+ list_init(PyListObject *self, PyObject *args, PyObject *kw)
+ {
+ 	PyObject *arg = NULL;
+ 	static char *kwlist[] = {"sequence", 0};
+ 
+ 	if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:list", kwlist, &arg))
+ 		return -1;
+ 	if (arg != NULL)
+ 		return list_fill(self, arg);
+ 	if (self->ob_size > 0)
+ 		return list_ass_slice(self, 0, self->ob_size, (PyObject*)NULL);
+ 	return 0;
+ }
+ 
  static char append_doc[] =
  "L.append(object) -- append object to end";
***************
*** 1574,1583 ****
  };
  
- static PyObject *
- list_getattr(PyListObject *f, char *name)
- {
- 	return Py_FindMethod(list_methods, (PyObject *)f, name);
- }
- 
  static PySequenceMethods list_as_sequence = {
  	(inquiry)list_length,			/* sq_length */
--- 1674,1677 ----
***************
*** 1593,1596 ****
--- 1687,1694 ----
  };
  
+ static char list_doc[] =
+ "list() -> new list\n"
+ "list(sequence) -> new list initialized from sequence's items";
+ 
  PyTypeObject PyList_Type = {
  	PyObject_HEAD_INIT(&PyType_Type)
***************
*** 1601,1605 ****
  	(destructor)list_dealloc,		/* tp_dealloc */
  	(printfunc)list_print,			/* tp_print */
! 	(getattrfunc)list_getattr,		/* tp_getattr */
  	0,					/* tp_setattr */
  	0,					/* tp_compare */
--- 1699,1703 ----
  	(destructor)list_dealloc,		/* tp_dealloc */
  	(printfunc)list_print,			/* tp_print */
! 	0,					/* tp_getattr */
  	0,					/* tp_setattr */
  	0,					/* tp_compare */
***************
*** 1611,1622 ****
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	0,					/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
! 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
!  	0,					/* tp_doc */
   	(traverseproc)list_traverse,		/* tp_traverse */
   	(inquiry)list_clear,			/* tp_clear */
  	list_richcompare,			/* tp_richcompare */
  };
  
--- 1709,1735 ----
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	PyObject_GenericGetAttr,		/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
! 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC |
! 		Py_TPFLAGS_BASETYPE,		/* tp_flags */
!  	list_doc,				/* tp_doc */
   	(traverseproc)list_traverse,		/* tp_traverse */
   	(inquiry)list_clear,			/* tp_clear */
  	list_richcompare,			/* tp_richcompare */
+ 	0,					/* tp_weaklistoffset */
+ 	0,					/* tp_iter */
+ 	0,					/* tp_iternext */
+ 	list_methods,				/* tp_methods */
+ 	0,					/* tp_members */
+ 	0,					/* tp_getset */
+ 	0,					/* tp_base */
+ 	0,					/* tp_dict */
+ 	0,					/* tp_descr_get */
+ 	0,					/* tp_descr_set */
+ 	0,					/* tp_dictoffset */
+ 	(initproc)list_init,			/* tp_init */
+ 	PyType_GenericAlloc,			/* tp_alloc */
+ 	PyType_GenericNew,			/* tp_new */
  };
  
***************
*** 1647,1656 ****
  };
  
- static PyObject *
- immutable_list_getattr(PyListObject *f, char *name)
- {
- 	return Py_FindMethod(immutable_list_methods, (PyObject *)f, name);
- }
- 
  static int
  immutable_list_ass(void)
--- 1760,1763 ----
***************
*** 1679,1683 ****
  	0, /* Cannot happen */			/* tp_dealloc */
  	(printfunc)list_print,			/* tp_print */
! 	(getattrfunc)immutable_list_getattr,	/* tp_getattr */
  	0,					/* tp_setattr */
  	0, /* Won't be called */		/* tp_compare */
--- 1786,1790 ----
  	0, /* Cannot happen */			/* tp_dealloc */
  	(printfunc)list_print,			/* tp_print */
! 	0,					/* tp_getattr */
  	0,					/* tp_setattr */
  	0, /* Won't be called */		/* tp_compare */
***************
*** 1689,1700 ****
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	0,					/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
  	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
!  	0,					/* tp_doc */
   	(traverseproc)list_traverse,		/* tp_traverse */
  	0,					/* tp_clear */
  	list_richcompare,			/* tp_richcompare */
  	/* NOTE: This is *not* the standard list_type struct! */
  };
--- 1796,1818 ----
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	PyObject_GenericGetAttr,		/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
  	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
!  	list_doc,				/* tp_doc */
   	(traverseproc)list_traverse,		/* tp_traverse */
  	0,					/* tp_clear */
  	list_richcompare,			/* tp_richcompare */
+ 	0,					/* tp_weaklistoffset */
+ 	0,					/* tp_iter */
+ 	0,					/* tp_iternext */
+ 	immutable_list_methods,			/* tp_methods */
+ 	0,					/* tp_members */
+ 	0,					/* tp_getset */
+ 	0,					/* tp_base */
+ 	0,					/* tp_dict */
+ 	0,					/* tp_descr_get */
+ 	0,					/* tp_descr_set */
+ 	0,					/* tp_init */
  	/* NOTE: This is *not* the standard list_type struct! */
  };

Index: longobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v
retrieving revision 1.89
retrieving revision 1.90
diff -C2 -d -r1.89 -r1.90
*** longobject.c	2001/07/15 18:38:47	1.89
--- longobject.c	2001/08/02 04:15:00	1.90
***************
*** 2032,2035 ****
--- 2032,2072 ----
  }
  
+ static PyObject *
+ long_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+ {
+ 	PyObject *x = NULL;
+ 	int base = -909;		     /* unlikely! */
+ 	static char *kwlist[] = {"x", "base", 0};
+ 
+ 	assert(type == &PyLong_Type);
+ 	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:long", kwlist,
+ 					 &x, &base))
+ 		return NULL;
+ 	if (x == NULL)
+ 		return PyLong_FromLong(0L);
+ 	if (base == -909)
+ 		return PyNumber_Long(x);
+ 	else if (PyString_Check(x))
+ 		return PyLong_FromString(PyString_AS_STRING(x), NULL, base);
+ 	else if (PyUnicode_Check(x))
+ 		return PyLong_FromUnicode(PyUnicode_AS_UNICODE(x),
+ 					  PyUnicode_GET_SIZE(x),
+ 					  base);
+ 	else {
+ 		PyErr_SetString(PyExc_TypeError,
+ 			"long() can't convert non-string with explicit base");
+ 		return NULL;
+ 	}
+ }
+ 
+ static char long_doc[] =
+ "long(x[, base]) -> integer\n\
+ \n\
+ Convert a string or number to a long integer, if possible.  A floating\n\
+ point argument will be truncated towards zero (this does not include a\n\
+ string representation of a floating point number!)  When converting a\n\
+ string, use the optional base.  It is an error to supply a base when\n\
+ converting a non-string.";
+ 
  static PyNumberMethods long_as_number = {
  	(binaryfunc)	long_add,	/*nb_add*/
***************
*** 2071,2093 ****
  PyTypeObject PyLong_Type = {
  	PyObject_HEAD_INIT(&PyType_Type)
! 	0,
! 	"long int",
! 	sizeof(PyLongObject) - sizeof(digit),
! 	sizeof(digit),
! 	(destructor)long_dealloc,	/*tp_dealloc*/
! 	0,				/*tp_print*/
! 	0,				/*tp_getattr*/
! 	0,				/*tp_setattr*/
! 	(cmpfunc)long_compare,		/*tp_compare*/
! 	(reprfunc)long_repr,		/*tp_repr*/
! 	&long_as_number,		/*tp_as_number*/
! 	0,				/*tp_as_sequence*/
! 	0,				/*tp_as_mapping*/
! 	(hashfunc)long_hash,		/*tp_hash*/
!         0,              		/*tp_call*/
!         (reprfunc)long_str,		/*tp_str*/
! 	0,				/*tp_getattro*/
! 	0,				/*tp_setattro*/
! 	0,				/*tp_as_buffer*/
! 	Py_TPFLAGS_CHECKTYPES		/*tp_flags*/
  };
--- 2108,2148 ----
  PyTypeObject PyLong_Type = {
  	PyObject_HEAD_INIT(&PyType_Type)
! 	0,					/* ob_size */
! 	"long",					/* tp_name */
! 	sizeof(PyLongObject) - sizeof(digit),	/* tp_basicsize */
! 	sizeof(digit),				/* tp_itemsize */
! 	(destructor)long_dealloc,		/* tp_dealloc */
! 	0,					/* tp_print */
! 	0,					/* tp_getattr */
! 	0,					/* tp_setattr */
! 	(cmpfunc)long_compare,			/* tp_compare */
! 	(reprfunc)long_repr,			/* tp_repr */
! 	&long_as_number,			/* tp_as_number */
! 	0,					/* tp_as_sequence */
! 	0,					/* tp_as_mapping */
! 	(hashfunc)long_hash,			/* tp_hash */
!         0,              			/* tp_call */
!         (reprfunc)long_str,			/* tp_str */
! 	PyObject_GenericGetAttr,		/* tp_getattro */
! 	0,					/* tp_setattro */
! 	0,					/* tp_as_buffer */
! 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
! 	long_doc,				/* 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 */
! 	0,					/* tp_descr_get */
! 	0,					/* tp_descr_set */
! 	0,					/* tp_dictoffset */
! 	0,					/* tp_init */
! 	0,					/* tp_alloc */
! 	long_new,				/* tp_new */
  };

Index: methodobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/methodobject.c,v
retrieving revision 2.34
retrieving revision 2.35
diff -C2 -d -r2.34 -r2.35
*** methodobject.c	2001/07/12 13:27:35	2.34
--- methodobject.c	2001/08/02 04:15:00	2.35
***************
*** 4,9 ****
  #include "Python.h"
  
- #include "token.h"
- 
  static PyCFunctionObject *free_list = NULL;
  
--- 4,7 ----
***************
*** 70,73 ****
--- 68,88 ----
  }
  
+ static PyObject *
+ meth_get__doc__(PyCFunctionObject *m, void *closure)
+ {
+ 	char *doc = m->m_ml->ml_doc;
+ 
+ 	if (doc != NULL)
+ 		return PyString_FromString(doc);
+ 	Py_INCREF(Py_None);
+ 	return Py_None;
+ }
+ 
+ static PyObject *
+ meth_get__name__(PyCFunctionObject *m, void *closure)
+ {
+ 	return PyString_FromString(m->m_ml->ml_name);
+ }
+ 
  static int
  meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg)
***************
*** 80,116 ****
  
  static PyObject *
! meth_getattr(PyCFunctionObject *m, char *name)
  {
! 	if (strcmp(name, "__name__") == 0) {
! 		return PyString_FromString(m->m_ml->ml_name);
! 	}
! 	if (strcmp(name, "__doc__") == 0) {
! 		char *doc = m->m_ml->ml_doc;
! 		if (doc != NULL)
! 			return PyString_FromString(doc);
! 		Py_INCREF(Py_None);
! 		return Py_None;
! 	}
! 	if (strcmp(name, "__self__") == 0) {
! 		PyObject *self;
! 		if (PyEval_GetRestricted()) {
! 			PyErr_SetString(PyExc_RuntimeError,
! 			 "method.__self__ not accessible in restricted mode");
! 			return NULL;
! 		}
! 		self = m->m_self;
! 		if (self == NULL)
! 			self = Py_None;
! 		Py_INCREF(self);
! 		return self;
! 	}
! 	if (strcmp(name, "__members__") == 0) {
! 		return Py_BuildValue("[sss]",
! 				     "__doc__", "__name__", "__self__");
  	}
! 	PyErr_SetString(PyExc_AttributeError, name);
! 	return NULL;
  }
  
  static PyObject *
  meth_repr(PyCFunctionObject *m)
--- 95,120 ----
  
  static PyObject *
! meth_get__self__(PyCFunctionObject *m, void *closure)
  {
! 	PyObject *self;
! 	if (PyEval_GetRestricted()) {
! 		PyErr_SetString(PyExc_RuntimeError,
! 			"method.__self__ not accessible in restricted mode");
! 		return NULL;
  	}
! 	self = m->m_self;
! 	if (self == NULL)
! 		self = Py_None;
! 	Py_INCREF(self);
! 	return self;
  }
  
+ static struct getsetlist meth_getsets [] = {
+ 	{"__doc__",  (getter)meth_get__doc__,  NULL, NULL},
+ 	{"__name__", (getter)meth_get__name__, NULL, NULL},
+ 	{"__self__", (getter)meth_get__self__, NULL, NULL},
+ 	{0}
+ };
+ 
  static PyObject *
  meth_repr(PyCFunctionObject *m)
***************
*** 160,163 ****
--- 164,202 ----
  }
  
+ static PyObject *
+ meth_call(PyObject *func, PyObject *arg, PyObject *kw)
+ {
+ 	PyCFunctionObject* f = (PyCFunctionObject*)func;
+ 	PyCFunction meth = PyCFunction_GET_FUNCTION(func);
+ 	PyObject *self = PyCFunction_GET_SELF(func);
+ 	int flags = PyCFunction_GET_FLAGS(func);
+ 
+ 	if (flags & METH_KEYWORDS) {
+ 		return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
+ 	}
+ 	if (kw != NULL && PyDict_Size(kw) != 0) {
+ 		PyErr_Format(PyExc_TypeError,
+ 			     "%.200s() takes no keyword arguments",
+ 			     f->m_ml->ml_name);
+ 		return NULL;
+ 	}
+ 	if (flags & METH_VARARGS) {
+ 		return (*meth)(self, arg);
+ 	}
+ 	if (!(flags & METH_VARARGS)) {
+ 		/* the really old style */
+ 		int size = PyTuple_GET_SIZE(arg);
+ 		if (size == 1)
+ 			arg = PyTuple_GET_ITEM(arg, 0);
+ 		else if (size == 0)
+ 			arg = NULL;
+ 		return (*meth)(self, arg);
+ 	}
+ 	/* should never get here ??? */
+ 	PyErr_BadInternalCall();
+ 	return NULL;
+ }
+ 
+ 
  PyTypeObject PyCFunction_Type = {
  	PyObject_HEAD_INIT(&PyType_Type)
***************
*** 168,172 ****
  	(destructor)meth_dealloc, 		/* tp_dealloc */
  	0,					/* tp_print */
! 	(getattrfunc)meth_getattr,		/* tp_getattr */
  	0,					/* tp_setattr */
  	(cmpfunc)meth_compare,			/* tp_compare */
--- 207,211 ----
  	(destructor)meth_dealloc, 		/* tp_dealloc */
  	0,					/* tp_print */
! 	0,					/* tp_getattr */
  	0,					/* tp_setattr */
  	(cmpfunc)meth_compare,			/* tp_compare */
***************
*** 176,182 ****
  	0,					/* tp_as_mapping */
  	(hashfunc)meth_hash,			/* tp_hash */
! 	0,					/* tp_call */
  	0,					/* tp_str */
! 	0,					/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
--- 215,221 ----
  	0,					/* tp_as_mapping */
  	(hashfunc)meth_hash,			/* tp_hash */
! 	meth_call,				/* tp_call */
  	0,					/* tp_str */
! 	PyObject_GenericGetAttr,		/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
***************
*** 184,187 ****
--- 223,236 ----
   	0,					/* tp_doc */
   	(traverseproc)meth_traverse,		/* tp_traverse */
+ 	0,					/* tp_clear */
+ 	0,					/* tp_richcompare */
+ 	0,					/* tp_weaklistoffset */
+ 	0,					/* tp_iter */
+ 	0,					/* tp_iternext */
+ 	0,					/* tp_methods */
+ 	0,					/* tp_members */
+ 	meth_getsets,				/* tp_getset */
+ 	0,					/* tp_base */
+ 	0,					/* tp_dict */
  };
  

Index: moduleobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/moduleobject.c,v
retrieving revision 2.33
retrieving revision 2.34
diff -C2 -d -r2.33 -r2.34
*** moduleobject.c	2001/05/12 20:24:22	2.33
--- moduleobject.c	2001/08/02 04:15:00	2.34
***************
*** 3,6 ****
--- 3,7 ----
  
  #include "Python.h"
+ #include "structmember.h"
  
  typedef struct {
***************
*** 9,12 ****
--- 10,18 ----
  } PyModuleObject;
  
+ struct memberlist module_members[] = {
+ 	{"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY},
+ 	{0}
+ };
+ 
  PyObject *
  PyModule_New(char *name)
***************
*** 129,132 ****
--- 135,147 ----
  /* Methods */
  
+ static int
+ module_init(PyModuleObject *m, PyObject *args, PyObject *kw)
+ {
+ 	m->md_dict = PyDict_New();
+ 	if (m->md_dict == NULL)
+ 		return -1;
+ 	return 0;
+ }
+ 
  static void
  module_dealloc(PyModuleObject *m)
***************
*** 162,218 ****
  }
  
- static PyObject *
- module_getattro(PyModuleObject *m, PyObject *name)
- {
- 	PyObject *res;
- 	char *sname = PyString_AsString(name);
- 
- 	if (sname[0] == '_' && strcmp(sname, "__dict__") == 0) {
- 		Py_INCREF(m->md_dict);
- 		return m->md_dict;
- 	}
- 	res = PyDict_GetItem(m->md_dict, name);
- 	if (res == NULL) {
- 		char *modname = PyModule_GetName((PyObject *)m);
- 		if (modname == NULL) {
- 			PyErr_Clear();
- 			modname = "?";
- 		}
- 		PyErr_Format(PyExc_AttributeError,
- 			     "'%.50s' module has no attribute '%.400s'",
- 			     modname, sname);
- 	}
- 	else
- 		Py_INCREF(res);
- 	return res;
- }
- 
- static int
- module_setattro(PyModuleObject *m, PyObject *name, PyObject *v)
- {
- 	char *sname = PyString_AsString(name);
- 	if (sname[0] == '_' && strcmp(sname, "__dict__") == 0) {
- 		PyErr_SetString(PyExc_TypeError,
- 				"read-only special attribute");
- 		return -1;
- 	}
- 	if (v == NULL) {
- 		int rv = PyDict_DelItem(m->md_dict, name);
- 		if (rv < 0) {
- 			char *modname = PyModule_GetName((PyObject *)m);
- 			if (modname == NULL) {
- 				PyErr_Clear();
- 				modname = "?";
- 			}
- 			PyErr_Format(PyExc_AttributeError,
- 				     "'%.50s' module has no attribute '%.400s'",
- 				     modname, sname);
- 		}
- 		return rv;
- 	}
- 	else
- 		return PyDict_SetItem(m->md_dict, name, v);
- }
- 
  /* We only need a traverse function, no clear function: If the module
     is in a cycle, md_dict will be cleared as well, which will break
--- 177,180 ----
***************
*** 230,241 ****
  	0,					/* ob_size */
  	"module",				/* tp_name */
! 	sizeof(PyModuleObject) + PyGC_HEAD_SIZE,/* tp_size */
  	0,					/* tp_itemsize */
! 	(destructor)module_dealloc, 		/* tp_dealloc */
  	0,					/* tp_print */
! 	0, 					/* tp_getattr */
! 	0, 					/* tp_setattr */
  	0,					/* tp_compare */
! 	(reprfunc)module_repr, 			/* tp_repr */
  	0,					/* tp_as_number */
  	0,					/* tp_as_sequence */
--- 192,203 ----
  	0,					/* ob_size */
  	"module",				/* tp_name */
! 	sizeof(PyModuleObject) + PyGC_HEAD_SIZE, /* tp_size */
  	0,					/* tp_itemsize */
! 	(destructor)module_dealloc,		/* tp_dealloc */
  	0,					/* tp_print */
! 	0,					/* tp_getattr */
! 	0,					/* tp_setattr */
  	0,					/* tp_compare */
! 	(reprfunc)module_repr,			/* tp_repr */
  	0,					/* tp_as_number */
  	0,					/* tp_as_sequence */
***************
*** 244,252 ****
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	(getattrofunc)module_getattro,		/* tp_getattro */
! 	(setattrofunc)module_setattro,		/* tp_setattro */
  	0,					/* tp_as_buffer */
! 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
  	0,					/* tp_doc */
  	(traverseproc)module_traverse,		/* tp_traverse */
  };
--- 206,231 ----
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	PyObject_GenericGetAttr,		/* tp_getattro */
! 	PyObject_GenericSetAttr,		/* tp_setattro */
  	0,					/* tp_as_buffer */
! 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC |
! 		Py_TPFLAGS_BASETYPE,		/* tp_flags */
  	0,					/* tp_doc */
  	(traverseproc)module_traverse,		/* tp_traverse */
+ 	0,					/* tp_clear */
+ 	0,					/* tp_richcompare */
+ 	0,					/* tp_weaklistoffset */
+ 	0,					/* tp_iter */
+ 	0,					/* tp_iternext */
+ 	0,					/* tp_methods */
+ 	module_members,				/* tp_members */
+ 	0,					/* tp_getset */
+ 	0,					/* tp_base */
+ 	0,					/* tp_dict */
+ 	0,					/* tp_descr_get */
+ 	0,					/* tp_descr_set */
+ 	offsetof(PyModuleObject, md_dict),	/* tp_dictoffset */
+ 	(initproc)module_init,			/* tp_init */
+ 	PyType_GenericAlloc,			/* tp_alloc */
+ 	PyType_GenericNew,			/* tp_new */
  };

Index: object.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v
retrieving revision 2.134
retrieving revision 2.135
diff -C2 -d -r2.134 -r2.135
*** object.c	2001/07/30 22:34:24	2.134
--- object.c	2001/08/02 04:15:00	2.135
***************
*** 33,37 ****
  	for (tp = type_list; tp; tp = tp->tp_next)
  		fprintf(stderr, "%s alloc'd: %d, freed: %d, max in use: %d\n",
! 			tp->tp_name, tp->tp_alloc, tp->tp_free,
  			tp->tp_maxalloc);
  	fprintf(stderr, "fast tuple allocs: %d, empty: %d\n",
--- 33,37 ----
  	for (tp = type_list; tp; tp = tp->tp_next)
  		fprintf(stderr, "%s alloc'd: %d, freed: %d, max in use: %d\n",
! 			tp->tp_name, tp->tp_allocs, tp->tp_frees,
  			tp->tp_maxalloc);
  	fprintf(stderr, "fast tuple allocs: %d, empty: %d\n",
***************
*** 54,59 ****
  		return NULL;
  	for (tp = type_list; tp; tp = tp->tp_next) {
! 		v = Py_BuildValue("(siii)", tp->tp_name, tp->tp_alloc,
! 				  tp->tp_free, tp->tp_maxalloc);
  		if (v == NULL) {
  			Py_DECREF(result);
--- 54,59 ----
  		return NULL;
  	for (tp = type_list; tp; tp = tp->tp_next) {
! 		v = Py_BuildValue("(siii)", tp->tp_name, tp->tp_allocs,
! 				  tp->tp_frees, tp->tp_maxalloc);
  		if (v == NULL) {
  			Py_DECREF(result);
***************
*** 73,77 ****
  inc_count(PyTypeObject *tp)
  {
! 	if (tp->tp_alloc == 0) {
  		/* first time; insert in linked list */
  		if (tp->tp_next != NULL) /* sanity check */
--- 73,77 ----
  inc_count(PyTypeObject *tp)
  {
! 	if (tp->tp_allocs == 0) {
  		/* first time; insert in linked list */
  		if (tp->tp_next != NULL) /* sanity check */
***************
*** 80,86 ****
  		type_list = tp;
  	}
! 	tp->tp_alloc++;
! 	if (tp->tp_alloc - tp->tp_free > tp->tp_maxalloc)
! 		tp->tp_maxalloc = tp->tp_alloc - tp->tp_free;
  }
  #endif
--- 80,86 ----
  		type_list = tp;
  	}
! 	tp->tp_allocs++;
! 	if (tp->tp_allocs - tp->tp_frees > tp->tp_maxalloc)
! 		tp->tp_maxalloc = tp->tp_allocs - tp->tp_frees;
  }
  #endif
***************
*** 94,101 ****
  		return op;
    	}
- #ifdef WITH_CYCLE_GC
  	if (PyType_IS_GC(tp))
  		op = (PyObject *) PyObject_FROM_GC(op);
- #endif
  	/* Any changes should be reflected in PyObject_INIT (objimpl.h) */
  	op->ob_type = tp;
--- 94,99 ----
***************
*** 112,119 ****
  		return op;
  	}
- #ifdef WITH_CYCLE_GC
  	if (PyType_IS_GC(tp))
  		op = (PyVarObject *) PyObject_FROM_GC(op);
- #endif
  	/* Any changes should be reflected in PyObject_INIT_VAR */
  	op->ob_size = size;
--- 110,115 ----
***************
*** 130,137 ****
  	if (op == NULL)
  		return PyErr_NoMemory();
- #ifdef WITH_CYCLE_GC
  	if (PyType_IS_GC(tp))
  		op = (PyObject *) PyObject_FROM_GC(op);
- #endif
  	return PyObject_INIT(op, tp);
  }
--- 126,131 ----
***************
*** 144,151 ****
  	if (op == NULL)
  		return (PyVarObject *)PyErr_NoMemory();
- #ifdef WITH_CYCLE_GC
  	if (PyType_IS_GC(tp))
  		op = (PyVarObject *) PyObject_FROM_GC(op);
- #endif
  	return PyObject_INIT_VAR(op, tp, size);
  }
--- 138,143 ----
***************
*** 154,162 ****
  _PyObject_Del(PyObject *op)
  {
- #ifdef WITH_CYCLE_GC
  	if (op && PyType_IS_GC(op->ob_type)) {
  		op = (PyObject *) PyObject_AS_GC(op);
  	}
- #endif
  	PyObject_FREE(op);
  }
--- 146,152 ----
***************
*** 995,1018 ****
  PyObject_GetAttrString(PyObject *v, char *name)
  {
! 	if (v->ob_type->tp_getattro != NULL) {
! 		PyObject *w, *res;
! 		w = PyString_InternFromString(name);
! 		if (w == NULL)
! 			return NULL;
! 		res = (*v->ob_type->tp_getattro)(v, w);
! 		Py_XDECREF(w);
! 		return res;
! 	}
  
! 	if (v->ob_type->tp_getattr == NULL) {
! 		PyErr_Format(PyExc_AttributeError,
! 			     "'%.50s' object has no attribute '%.400s'",
! 			     v->ob_type->tp_name,
! 			     name);
! 		return NULL;
! 	}
! 	else {
  		return (*v->ob_type->tp_getattr)(v, name);
! 	}
  }
  
--- 985,998 ----
  PyObject_GetAttrString(PyObject *v, char *name)
  {
! 	PyObject *w, *res;
  
! 	if (v->ob_type->tp_getattr != NULL)
  		return (*v->ob_type->tp_getattr)(v, name);
! 	w = PyString_InternFromString(name);
! 	if (w == NULL)
! 		return NULL;
! 	res = PyObject_GetAttr(v, w);
! 	Py_XDECREF(w);
! 	return res;
  }
  
***************
*** 1032,1058 ****
  PyObject_SetAttrString(PyObject *v, char *name, PyObject *w)
  {
! 	if (v->ob_type->tp_setattro != NULL) {
! 		PyObject *s;
! 		int res;
! 		s = PyString_InternFromString(name);
! 		if (s == NULL)
! 			return -1;
! 		res = (*v->ob_type->tp_setattro)(v, s, w);
! 		Py_XDECREF(s);
! 		return res;
! 	}
  
! 	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);
! 	}
  }
  
--- 1012,1026 ----
  PyObject_SetAttrString(PyObject *v, char *name, PyObject *w)
  {
! 	PyObject *s;
! 	int res;
  
! 	if (v->ob_type->tp_setattr != NULL)
  		return (*v->ob_type->tp_setattr)(v, name, w);
! 	s = PyString_InternFromString(name);
! 	if (s == NULL)
! 		return -1;
! 	res = PyObject_SetAttr(v, s, w);
! 	Py_XDECREF(s);
! 	return res;
  }
  
***************
*** 1060,1063 ****
--- 1028,1033 ----
  PyObject_GetAttr(PyObject *v, PyObject *name)
  {
+ 	PyTypeObject *tp = v->ob_type;
+ 
  	/* The Unicode to string conversion is done here because the
  	   existing tp_getattro slots expect a string object as name
***************
*** 1068,1072 ****
  			return NULL;
  	}
- 
  	if (!PyString_Check(name)) {
  		PyErr_SetString(PyExc_TypeError,
--- 1038,1041 ----
***************
*** 1074,1081 ****
  		return NULL;
  	}
! 	if (v->ob_type->tp_getattro != NULL)
! 		return (*v->ob_type->tp_getattro)(v, name);
! 	else
! 		return PyObject_GetAttrString(v, PyString_AS_STRING(name));
  }
  
--- 1043,1054 ----
  		return NULL;
  	}
! 	if (tp->tp_getattro != NULL)
! 		return (*tp->tp_getattro)(v, name);
! 	if (tp->tp_getattr != NULL)
! 		return (*tp->tp_getattr)(v, PyString_AS_STRING(name));
! 	PyErr_Format(PyExc_AttributeError,
! 		     "'%.50s' object has no attribute '%.400s'",
! 		     tp->tp_name, PyString_AS_STRING(name));
! 	return NULL;
  }
  
***************
*** 1095,1098 ****
--- 1068,1072 ----
  PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value)
  {
+ 	PyTypeObject *tp = v->ob_type;
  	int err;
  
***************
*** 1105,1129 ****
  			return -1;
  	}
! 	else
! 		Py_INCREF(name);
! 	
! 	if (!PyString_Check(name)){
  		PyErr_SetString(PyExc_TypeError,
  				"attribute name must be string");
! 		err = -1;
  	}
! 	else {
! 		PyString_InternInPlace(&name);
! 		if (v->ob_type->tp_setattro != NULL)
! 			err = (*v->ob_type->tp_setattro)(v, name, value);
! 		else
! 			err = PyObject_SetAttrString(v, 
! 				        PyString_AS_STRING(name), value);
  	}
! 	
  	Py_DECREF(name);
! 	return err;
  }
  
  /* Test a value used as condition, e.g., in a for or if statement.
     Return -1 if an error occurred */
--- 1079,1260 ----
  			return -1;
  	}
! 	else if (!PyString_Check(name)){
  		PyErr_SetString(PyExc_TypeError,
  				"attribute name must be string");
! 		return -1;
  	}
! 	else
! 		Py_INCREF(name);
! 
! 	PyString_InternInPlace(&name);
! 	if (tp->tp_setattro != NULL) {
! 		err = (*tp->tp_setattro)(v, name, value);
! 		Py_DECREF(name);
! 		return err;
  	}
! 	if (tp->tp_setattr != NULL) {
! 		err = (*tp->tp_setattr)(v, PyString_AS_STRING(name), value);
! 		Py_DECREF(name);
! 		return err;
! 	}
  	Py_DECREF(name);
! 	if (tp->tp_getattr == NULL && tp->tp_getattro == NULL)
! 		PyErr_Format(PyExc_TypeError,
! 			     "'%.100s' object has no attributes "
! 			     "(%s .%.100s)",
! 			     tp->tp_name,
! 			     value==NULL ? "del" : "assign to",
! 			     PyString_AS_STRING(name));
! 	else
! 		PyErr_Format(PyExc_TypeError,
! 			     "'%.100s' object has only read-only attributes "
! 			     "(%s .%.100s)",
! 			     tp->tp_name,
! 			     value==NULL ? "del" : "assign to",
! 			     PyString_AS_STRING(name));
! 	return -1;
  }
  
+ /* Helper to get a pointer to an object's __dict__ slot, if any */
+ 
+ PyObject **
+ _PyObject_GetDictPtr(PyObject *obj)
+ {
+ #define PTRSIZE (sizeof(PyObject *))
+ 
+ 	long dictoffset;
+ 	PyTypeObject *tp = obj->ob_type;
+ 
+ 	if (!(tp->tp_flags & Py_TPFLAGS_HAVE_CLASS))
+ 		return NULL;
+ 	dictoffset = tp->tp_dictoffset;
+ 	if (dictoffset == 0)
+ 		return NULL;
+ 	if (dictoffset < 0) {
+ 		dictoffset += PyType_BASICSIZE(tp);
+ 		assert(dictoffset > 0); /* Sanity check */
+ 		if (tp->tp_itemsize > 0) {
+ 			int n = ((PyVarObject *)obj)->ob_size;
+ 			if (n > 0) {
+ 				dictoffset += tp->tp_itemsize * n;
+ 				/* Round up, if necessary */
+ 				if (tp->tp_itemsize % PTRSIZE != 0) {
+ 					dictoffset += PTRSIZE - 1;
+ 					dictoffset /= PTRSIZE;
+ 					dictoffset *= PTRSIZE;
+ 				}
+ 			}
+ 		}
+ 	}
+ 	return (PyObject **) ((char *)obj + dictoffset);
+ }
+ 
+ /* Generic GetAttr functions - put these in your tp_[gs]etattro slot */
+ 
+ PyObject *
+ PyObject_GenericGetAttr(PyObject *obj, PyObject *name)
+ {
+ 	PyTypeObject *tp = obj->ob_type;
+ 	PyObject *descr;
+ 	descrgetfunc f;
+ 	PyObject **dictptr;
+ 
+ 	if (tp->tp_dict == NULL) {
+ 		if (PyType_InitDict(tp) < 0)
+ 			return NULL;
+ 	}
+ 
+ 	descr = _PyType_Lookup(tp, name);
+ 	f = NULL;
+ 	if (descr != NULL) {
+ 		f = descr->ob_type->tp_descr_get;
+ 		if (f != NULL && PyDescr_IsData(descr))
+ 			return f(descr, obj, (PyObject *)obj->ob_type);
+ 	}
+ 
+ 	dictptr = _PyObject_GetDictPtr(obj);
+ 	if (dictptr != NULL) {
+ 		PyObject *dict = *dictptr;
+ 		if (dict != NULL) {
+ 			PyObject *res = PyDict_GetItem(dict, name);
+ 			if (res != NULL) {
+ 				Py_INCREF(res);
+ 				return res;
+ 			}
+ 		}
+ 	}
+ 
+ 	if (f != NULL)
+ 		return f(descr, obj, (PyObject *)obj->ob_type);
+ 
+ 	if (descr != NULL) {
+ 		Py_INCREF(descr);
+ 		return descr;
+ 	}
+ 
+ 	PyErr_Format(PyExc_AttributeError,
+ 		     "'%.50s' object has no attribute '%.400s'",
+ 		     tp->tp_name, PyString_AS_STRING(name));
+ 	return NULL;
+ }
+ 
+ int
+ PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value)
+ {
+ 	PyTypeObject *tp = obj->ob_type;
+ 	PyObject *descr;
+ 	descrsetfunc f;
+ 	PyObject **dictptr;
+ 
+ 	if (tp->tp_dict == NULL) {
+ 		if (PyType_InitDict(tp) < 0)
+ 			return -1;
+ 	}
+ 
+ 	descr = _PyType_Lookup(tp, name);
+ 	f = NULL;
+ 	if (descr != NULL) {
+ 		f = descr->ob_type->tp_descr_set;
+ 		if (f != NULL && PyDescr_IsData(descr))
+ 			return f(descr, obj, value);
+ 	}
+ 
+ 	dictptr = _PyObject_GetDictPtr(obj);
+ 	if (dictptr != NULL) {
+ 		PyObject *dict = *dictptr;
+ 		if (dict == NULL && value != NULL) {
+ 			dict = PyDict_New();
+ 			if (dict == NULL)
+ 				return -1;
+ 			*dictptr = dict;
+ 		}
+ 		if (dict != NULL) {
+ 			int res;
+ 			if (value == NULL)
+ 				res = PyDict_DelItem(dict, name);
+ 			else
+ 				res = PyDict_SetItem(dict, name, value);
+ 			if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
+ 				PyErr_SetObject(PyExc_AttributeError, name);
+ 			return res;
+ 		}
+ 	}
+ 
+ 	if (f != NULL)
+ 		return f(descr, obj, value);
+ 
+ 	if (descr == NULL) {
+ 		PyErr_Format(PyExc_AttributeError,
+ 			     "'%.50s' object has no attribute '%.400s'",
+ 			     tp->tp_name, PyString_AS_STRING(name));
+ 		return -1;
+ 	}
+ 
+ 	PyErr_Format(PyExc_AttributeError,
+ 		     "'%.50s' object attribute '%.400s' is read-only",
+ 		     tp->tp_name, PyString_AS_STRING(name));
+ 	return -1;
+ }
+ 
  /* Test a value used as condition, e.g., in a for or if statement.
     Return -1 if an error occurred */
***************
*** 1219,1228 ****
  	if (x == NULL)
  		return 0;
- 	if (x->ob_type->tp_call != NULL ||
- 	    PyFunction_Check(x) ||
- 	    PyMethod_Check(x) ||
- 	    PyCFunction_Check(x) ||
- 	    PyClass_Check(x))
- 		return 1;
  	if (PyInstance_Check(x)) {
  		PyObject *call = PyObject_GetAttrString(x, "__call__");
--- 1350,1353 ----
***************
*** 1236,1240 ****
  		return 1;
  	}
! 	return 0;
  }
  
--- 1361,1367 ----
  		return 1;
  	}
! 	else {
! 		return x->ob_type->tp_call != NULL;
! 	}
  }
  
***************
*** 1366,1370 ****
  	op->_ob_next = op->_ob_prev = NULL;
  #ifdef COUNT_ALLOCS
! 	op->ob_type->tp_free++;
  #endif
  }
--- 1493,1497 ----
  	op->_ob_next = op->_ob_prev = NULL;
  #ifdef COUNT_ALLOCS
! 	op->ob_type->tp_frees++;
  #endif
  }

Index: rangeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/rangeobject.c,v
retrieving revision 2.26
retrieving revision 2.27
diff -C2 -d -r2.26 -r2.27
*** rangeobject.c	2001/07/09 12:30:54	2.26
--- rangeobject.c	2001/08/02 04:15:00	2.27
***************
*** 311,330 ****
  	sizeof(rangeobject),	/* Basic object size */
  	0,			/* Item size for varobject */
! 	(destructor)range_dealloc, /*tp_dealloc*/
! 	0,			/*tp_print*/
! 	(getattrfunc)range_getattr, /*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*/
  };
  
--- 311,342 ----
  	sizeof(rangeobject),	/* Basic object size */
  	0,			/* Item size for varobject */
! 	(destructor)range_dealloc,		/*tp_dealloc*/
! 	0,					/*tp_print*/
! 	(getattrfunc)range_getattr,		/*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*/
! 	PyObject_GenericGetAttr,		/*tp_getattro*/
! 	0,					/*tp_setattro*/
! 	0,					/*tp_as_buffer*/
! 	Py_TPFLAGS_DEFAULT,			/*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 */
  };
  

Index: sliceobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/sliceobject.c,v
retrieving revision 2.7
retrieving revision 2.8
diff -C2 -d -r2.7 -r2.8
*** sliceobject.c	2001/03/20 12:41:34	2.7
--- sliceobject.c	2001/08/02 04:15:00	2.8
***************
*** 15,18 ****
--- 15,19 ----
  
  #include "Python.h"
+ #include "structmember.h"
  
  static PyObject *
***************
*** 128,158 ****
  	return s;
  }
- 
  
! static PyObject *slice_getattr(PySliceObject *self, char *name)
! {
! 	PyObject *ret;
!   
! 	ret = NULL;
! 	if (strcmp(name, "start") == 0) {
! 		ret = self->start;
! 	}
! 	else if (strcmp(name, "stop") == 0) {
! 		ret = self->stop;
! 	}
! 	else if (strcmp(name, "step") == 0) {
! 		ret = self->step;
! 	}
! 	else if (strcmp(name, "__members__") == 0) {
! 		return Py_BuildValue("[sss]",
! 				     "start", "stop", "step");
! 	}
! 	else {
! 		PyErr_SetString(PyExc_AttributeError, name);
! 		return NULL;
! 	}
! 	Py_INCREF(ret);
! 	return ret;
! }
  
  static int
--- 129,139 ----
  	return s;
  }
  
! static struct memberlist slice_members[] = {
! 	{"start", T_OBJECT, offsetof(PySliceObject, start), READONLY},
! 	{"stop", T_OBJECT, offsetof(PySliceObject, stop), READONLY},
! 	{"step", T_OBJECT, offsetof(PySliceObject, step), READONLY},
! 	{0}
! };
  
  static int
***************
*** 183,194 ****
  	sizeof(PySliceObject),	/* Basic object size */
  	0,			/* Item size for varobject */
! 	(destructor)slice_dealloc, /*tp_dealloc*/
! 	0,			/*tp_print*/
! 	(getattrfunc)slice_getattr, /*tp_getattr*/
! 	0,			/*tp_setattr*/
! 	(cmpfunc)slice_compare, /*tp_compare*/
! 	(reprfunc)slice_repr,   /*tp_repr*/
! 	0,			/*tp_as_number*/
! 	0,	    		/*tp_as_sequence*/
! 	0,			/*tp_as_mapping*/
  };
--- 164,194 ----
  	sizeof(PySliceObject),	/* Basic object size */
  	0,			/* Item size for varobject */
! 	(destructor)slice_dealloc,		/* tp_dealloc */
! 	0,					/* tp_print */
! 	0,					/* tp_getattr */
! 	0,					/* tp_setattr */
! 	(cmpfunc)slice_compare, 		/* tp_compare */
! 	(reprfunc)slice_repr,   		/* 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,			/* 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 */
! 	slice_members,				/* tp_members */
! 	0,					/* tp_getset */
! 	0,					/* tp_base */
! 	0,					/* tp_dict */
  };

Index: stringobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v
retrieving revision 2.121
retrieving revision 2.122
diff -C2 -d -r2.121 -r2.122
*** stringobject.c	2001/07/30 22:34:24	2.121
--- stringobject.c	2001/08/02 04:15:00	2.122
***************
*** 2523,2561 ****
  
  static PyObject *
! string_getattr(PyStringObject *s, char *name)
  {
! 	return Py_FindMethod(string_methods, (PyObject*)s, name);
  }
  
  
  PyTypeObject PyString_Type = {
  	PyObject_HEAD_INIT(&PyType_Type)
  	0,
! 	"string",
  	sizeof(PyStringObject),
  	sizeof(char),
! 	(destructor)string_dealloc, /*tp_dealloc*/
! 	(printfunc)string_print, /*tp_print*/
! 	(getattrfunc)string_getattr,		/*tp_getattr*/
! 	0,		/*tp_setattr*/
! 	0,		/*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*/
! 	(reprfunc)string_str,	/*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*/
! 	(richcmpfunc)string_richcompare,	/*tp_richcompare*/
! 	0,		/*tp_weaklistoffset*/
! 	0,		/*tp_iter*/
! 	0,		/*tp_iternext*/
  };
  
--- 2523,2585 ----
  
  static PyObject *
! string_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
  {
! 	PyObject *x = NULL;
! 	static char *kwlist[] = {"object", 0};
! 
! 	assert(type == &PyString_Type);
! 	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:str", kwlist, &x))
! 		return NULL;
! 	if (x == NULL)
! 		return PyString_FromString("");
! 	return PyObject_Str(x);
  }
  
+ static char string_doc[] =
+ "str(object) -> string\n\
+ \n\
+ Return a nice string representation of the object.\n\
+ If the argument is a string, the return value is the same object.";
  
  PyTypeObject PyString_Type = {
  	PyObject_HEAD_INIT(&PyType_Type)
  	0,
! 	"str",
  	sizeof(PyStringObject),
  	sizeof(char),
!  	(destructor)string_dealloc, 		/* tp_dealloc */
! 	(printfunc)string_print, 		/* tp_print */
! 	0,					/* tp_getattr */
! 	0,					/* tp_setattr */
! 	0,					/* 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 */
! 	(reprfunc)string_str,			/* tp_str */
! 	PyObject_GenericGetAttr,		/* tp_getattro */
! 	0,					/* tp_setattro */
! 	&string_as_buffer,			/* tp_as_buffer */
! 	Py_TPFLAGS_DEFAULT,			/* tp_flags */
! 	string_doc,				/* tp_doc */
! 	0,					/* tp_traverse */
! 	0,					/* tp_clear */
! 	(richcmpfunc)string_richcompare,	/* tp_richcompare */
! 	0,					/* tp_weaklistoffset */
! 	0,					/* tp_iter */
! 	0,					/* tp_iternext */
! 	string_methods,				/* tp_methods */
! 	0,					/* tp_members */
! 	0,					/* tp_getset */
! 	0,					/* tp_base */
! 	0,					/* tp_dict */
! 	0,					/* tp_descr_get */
! 	0,					/* tp_descr_set */
! 	0,					/* tp_dictoffset */
! 	0,					/* tp_init */
! 	0,					/* tp_alloc */
! 	string_new,				/* tp_new */
  };
  

Index: tupleobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/tupleobject.c,v
retrieving revision 2.53
retrieving revision 2.54
diff -C2 -d -r2.53 -r2.54
*** tupleobject.c	2001/06/16 05:11:17	2.53
--- tupleobject.c	2001/08/02 04:15:00	2.54
***************
*** 481,484 ****
--- 481,506 ----
  }
  
+ static PyObject *
+ tuple_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+ {
+ 	PyObject *arg = NULL;
+ 	static char *kwlist[] = {"sequence", 0};
+ 
+ 	assert(type == &PyTuple_Type);
+ 	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:tuple", kwlist, &arg))
+ 		return NULL;
+ 
+ 	if (arg == NULL)
+ 		return PyTuple_New(0);
+ 	else
+ 		return PySequence_Tuple(arg);
+ }
+ 
+ static char tuple_doc[] =
+ "tuple(sequence) -> list\n\
+ \n\
+ Return a tuple whose items are the same as those of the argument sequence.\n\
+ If the argument is a tuple, the return value is the same object.";
+ 
  static PySequenceMethods tuple_as_sequence = {
  	(inquiry)tuplelength,			/* sq_length */
***************
*** 510,521 ****
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	0,					/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
  	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
! 	0,             				/* tp_doc */
   	(traverseproc)tupletraverse,		/* tp_traverse */
  	0,					/* tp_clear */
  	tuplerichcompare,			/* tp_richcompare */
  };
  
--- 532,557 ----
  	0,					/* tp_call */
  	0,					/* tp_str */
! 	PyObject_GenericGetAttr,		/* tp_getattro */
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
  	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */
! 	tuple_doc,				/* tp_doc */
   	(traverseproc)tupletraverse,		/* tp_traverse */
  	0,					/* tp_clear */
  	tuplerichcompare,			/* 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 */
+ 	0,					/* tp_descr_get */
+ 	0,					/* tp_descr_set */
+ 	0,					/* tp_dictoffset */
+ 	0,					/* tp_init */
+ 	0,					/* tp_alloc */
+ 	tuple_new,				/* tp_new */
  };
  

Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.18
retrieving revision 2.19
diff -C2 -d -r2.18 -r2.19
*** typeobject.c	2001/06/10 21:43:28	2.18
--- typeobject.c	2001/08/02 04:15:00	2.19
***************
*** 3,27 ****
  
  #include "Python.h"
  
! /* Type object implementation */
  
  static PyObject *
! type_getattr(PyTypeObject *t, char *name)
  {
! 	if (strcmp(name, "__name__") == 0)
! 		return PyString_FromString(t->tp_name);
[...2378 lines suppressed...]
+ 	TPSLOT("__cmp__", tp_compare);
+ 	TPSLOT("__repr__", tp_repr);
+ 	TPSLOT("__hash__", tp_hash);
+ 	TPSLOT("__call__", tp_call);
+ 	TPSLOT("__str__", tp_str);
+ 	TPSLOT("__getattr__", tp_getattro);
+ 	TPSLOT("__setattr__", tp_setattro);
+ 	TPSLOT("__lt__", tp_richcompare);
+ 	TPSLOT("__le__", tp_richcompare);
+ 	TPSLOT("__eq__", tp_richcompare);
+ 	TPSLOT("__ne__", tp_richcompare);
+ 	TPSLOT("__gt__", tp_richcompare);
+ 	TPSLOT("__ge__", tp_richcompare);
+ 	TPSLOT("__iter__", tp_iter);
+ 	TPSLOT("next", tp_iternext);
+ 	TPSLOT("__get__", tp_descr_get);
+ 	TPSLOT("__set__", tp_descr_set);
+ 	TPSLOT("__init__", tp_init);
+ 	TPSLOT("__new__", tp_new);
+ }

Index: unicodeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v
retrieving revision 2.105
retrieving revision 2.106
diff -C2 -d -r2.105 -r2.106
*** unicodeobject.c	2001/07/30 22:34:24	2.105
--- unicodeobject.c	2001/08/02 04:15:00	2.106
***************
*** 4668,4677 ****
  };
  
- static PyObject * 
- unicode_getattr(PyUnicodeObject *self, char *name)
- {
-     return Py_FindMethod(unicode_methods, (PyObject*) self, name);
- }
- 
  static PySequenceMethods unicode_as_sequence = {
      (inquiry) unicode_length, 		/* sq_length */
--- 4668,4671 ----
***************
*** 5347,5350 ****
--- 5341,5368 ----
  };
  
+ static PyObject *
+ unicode_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+ {
+         PyObject *x = NULL;
+ 	static char *kwlist[] = {"string", "encoding", "errors", 0};
+ 	char *encoding = NULL;
+ 	char *errors = NULL;
+ 
+ 	assert(type == &PyUnicode_Type);
+ 	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:unicode",
+ 					  kwlist, &x, &encoding, &errors))
+ 	    return NULL;
+ 	if (x == NULL)
+ 		return (PyObject *)_PyUnicode_New(0);
+ 	return PyUnicode_FromEncodedObject(x, encoding, errors);
+ }
+ 
+ static char unicode_doc[] =
+ "unicode(string [, encoding[, errors]]) -> object\n\
+ \n\
+ Create a new Unicode object from the given encoded string.\n\
+ encoding defaults to the current default string encoding and \n\
+ errors, defining the error handling, to 'strict'.";
+ 
  PyTypeObject PyUnicode_Type = {
      PyObject_HEAD_INIT(&PyType_Type)
***************
*** 5356,5360 ****
      (destructor)_PyUnicode_Free, 	/* tp_dealloc */
      0, 					/* tp_print */
!     (getattrfunc)unicode_getattr, 	/* tp_getattr */
      0, 					/* tp_setattr */
      (cmpfunc) unicode_compare, 		/* tp_compare */
--- 5374,5378 ----
      (destructor)_PyUnicode_Free, 	/* tp_dealloc */
      0, 					/* tp_print */
!     0,				 	/* tp_getattr */
      0, 					/* tp_setattr */
      (cmpfunc) unicode_compare, 		/* tp_compare */
***************
*** 5366,5373 ****
      0, 					/* tp_call*/
      (reprfunc) unicode_str,	 	/* tp_str */
!     (getattrofunc) NULL, 		/* tp_getattro */
!     (setattrofunc) NULL, 		/* tp_setattro */
      &unicode_as_buffer,			/* tp_as_buffer */
      Py_TPFLAGS_DEFAULT,			/* tp_flags */
  };
  
--- 5384,5409 ----
      0, 					/* tp_call*/
      (reprfunc) unicode_str,	 	/* tp_str */
!     PyObject_GenericGetAttr, 		/* tp_getattro */
!     0,			 		/* tp_setattro */
      &unicode_as_buffer,			/* tp_as_buffer */
      Py_TPFLAGS_DEFAULT,			/* tp_flags */
+     unicode_doc,			/* tp_doc */
+     0,					/* tp_traverse */
+     0,					/* tp_clear */
+     0,					/* tp_richcompare */
+     0,					/* tp_weaklistoffset */
+     0,					/* tp_iter */
+     0,					/* tp_iternext */
+     unicode_methods,			/* tp_methods */
+     0,					/* tp_members */
+     0,					/* tp_getset */
+     0,					/* tp_base */
+     0,					/* tp_dict */
+     0,					/* tp_descr_get */
+     0,					/* tp_descr_set */
+     0,					/* tp_dictoffset */
+     0,					/* tp_init */
+     0,					/* tp_alloc */
+     unicode_new,			/* tp_new */
  };