Merged revisions 59488-59511 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r59489 | christian.heimes | 2007-12-14 03:33:57 +0100 (Fri, 14 Dec 2007) | 1 line

  Silence a warning about an unsed variable in debug builds
........
  r59490 | christian.heimes | 2007-12-14 03:35:23 +0100 (Fri, 14 Dec 2007) | 2 lines

  Fixed bug #1620: New @spam.getter property syntax modifies the property in place.
  I added also the feature that a @prop.getter decorator does not overwrite the doc string of the property if it was given as an argument to property().
........
  r59491 | raymond.hettinger | 2007-12-14 03:49:47 +0100 (Fri, 14 Dec 2007) | 1 line

  Cleaner method naming convention
........
  r59492 | christian.heimes | 2007-12-14 04:02:34 +0100 (Fri, 14 Dec 2007) | 1 line

  Fixed a warning in _codecs_iso2022.c and some non C89 conform // comments.
........
  r59493 | christian.heimes | 2007-12-14 05:38:13 +0100 (Fri, 14 Dec 2007) | 1 line

  Fixed warning in ssl module
........
  r59500 | raymond.hettinger | 2007-12-14 19:08:20 +0100 (Fri, 14 Dec 2007) | 1 line

  Add line spacing for readability
........
  r59501 | raymond.hettinger | 2007-12-14 19:12:21 +0100 (Fri, 14 Dec 2007) | 3 lines

  Update method names for named tuples.
........
  r59503 | georg.brandl | 2007-12-14 20:03:36 +0100 (Fri, 14 Dec 2007) | 3 lines

  Add a section about nested listcomps to the tutorial.
  Thanks to Ian Bruntlett and Robert Lehmann.
........
  r59504 | raymond.hettinger | 2007-12-14 20:19:59 +0100 (Fri, 14 Dec 2007) | 1 line

  Faster and simpler _replace() method
........
  r59505 | raymond.hettinger | 2007-12-14 22:51:50 +0100 (Fri, 14 Dec 2007) | 1 line

  Add usage note
........
  r59507 | andrew.kuchling | 2007-12-14 23:41:18 +0100 (Fri, 14 Dec 2007) | 1 line

  Remove warning about URL
........
  r59510 | andrew.kuchling | 2007-12-14 23:52:36 +0100 (Fri, 14 Dec 2007) | 1 line

  Bump the version number, and make a few small edits
........
  r59511 | christian.heimes | 2007-12-15 00:42:36 +0100 (Sat, 15 Dec 2007) | 2 lines

  Fixed bug #1628
  The detection now works on Unix with Makefile, Makefile with VPATH and on Windows.
........
diff --git a/Objects/descrobject.c b/Objects/descrobject.c
index d683587..ea47181 100644
--- a/Objects/descrobject.c
+++ b/Objects/descrobject.c
@@ -1065,8 +1065,12 @@
 	PyObject *prop_set;
 	PyObject *prop_del;
 	PyObject *prop_doc;
+	int getter_doc;
 } propertyobject;
 
+static PyObject * property_copy(PyObject *, PyObject *, PyObject *,
+				  PyObject *, PyObject *);
+
 static PyMemberDef property_members[] = {
 	{"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY},
 	{"fset", T_OBJECT, offsetof(propertyobject, prop_set), READONLY},
@@ -1075,53 +1079,37 @@
 	{0}
 };
 
+
 PyDoc_STRVAR(getter_doc,
 	     "Descriptor to change the getter on a property.");
 
 PyObject *
 property_getter(PyObject *self, PyObject *getter)
 {
-	Py_XDECREF(((propertyobject *)self)->prop_get);
-	if (getter == Py_None)
-		getter = NULL;
-	Py_XINCREF(getter);
-	((propertyobject *)self)->prop_get = getter;
-	Py_INCREF(self);
-	return self;
+	return property_copy(self, getter, NULL, NULL, NULL);
 }
 
+
 PyDoc_STRVAR(setter_doc,
-	     "Descriptor to change the setter on a property.\n");
+	     "Descriptor to change the setter on a property.");
 
 PyObject *
 property_setter(PyObject *self, PyObject *setter)
 {
-	Py_XDECREF(((propertyobject *)self)->prop_set);
-	if (setter == Py_None)
-		setter = NULL;
-	Py_XINCREF(setter);
-	((propertyobject *)self)->prop_set = setter;
-	Py_INCREF(self);
-	return self;
+	return property_copy(self, NULL, setter, NULL, NULL);
 }
 
+
 PyDoc_STRVAR(deleter_doc,
 	     "Descriptor to change the deleter on a property.");
 
 PyObject *
 property_deleter(PyObject *self, PyObject *deleter)
 {
-	Py_XDECREF(((propertyobject *)self)->prop_del);
-	if (deleter == Py_None)
-		deleter = NULL;
-	Py_XINCREF(deleter);
-	((propertyobject *)self)->prop_del = deleter;
-	Py_INCREF(self);
-	return self;
+	return property_copy(self, NULL, NULL, deleter, NULL);
 }
 
 
-
 static PyMethodDef property_methods[] = {
 	{"getter", property_getter, METH_O, getter_doc},
 	{"setter", property_setter, METH_O, setter_doc},
@@ -1186,15 +1174,62 @@
 	return 0;
 }
 
+static PyObject *
+property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del,
+		PyObject *doc)
+{
+	propertyobject *pold = (propertyobject *)old;
+	propertyobject *pnew = NULL;
+	PyObject *new, *type;
+
+	type = PyObject_Type(old);
+	if (type == NULL)
+		return NULL;
+
+	if (get == NULL || get == Py_None) {
+		Py_XDECREF(get);
+		get = pold->prop_get ? pold->prop_get : Py_None;
+	}
+	if (set == NULL || set == Py_None) {
+		Py_XDECREF(set);
+		set = pold->prop_set ? pold->prop_set : Py_None;
+	}
+	if (del == NULL || del == Py_None) {
+		Py_XDECREF(del);
+		del = pold->prop_del ? pold->prop_del : Py_None;
+	}
+	if (doc == NULL || doc == Py_None) {
+		Py_XDECREF(doc);
+		doc = pold->prop_doc ? pold->prop_doc : Py_None;
+	}
+	
+	new =  PyObject_CallFunction(type, "OOOO", get, set, del, doc);
+	if (new == NULL)
+		return NULL;
+	pnew = (propertyobject *)new;
+	
+	if (pold->getter_doc && get != Py_None) {
+		PyObject *get_doc = PyObject_GetAttrString(get, "__doc__");
+		if (get_doc != NULL) {
+			Py_XDECREF(pnew->prop_doc);
+			pnew->prop_doc = get_doc;  /* get_doc already INCREF'd by GetAttr */
+			pnew->getter_doc = 1;
+		} else {
+			PyErr_Clear();
+		}
+	}
+	return new;
+}
+
 static int
 property_init(PyObject *self, PyObject *args, PyObject *kwds)
 {
 	PyObject *get = NULL, *set = NULL, *del = NULL, *doc = NULL;
 	static char *kwlist[] = {"fget", "fset", "fdel", "doc", 0};
-	propertyobject *gs = (propertyobject *)self;
-
+	propertyobject *prop = (propertyobject *)self;
+	
 	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOO:property",
-	     				 kwlist, &get, &set, &del, &doc))
+					 kwlist, &get, &set, &del, &doc))
 		return -1;
 
 	if (get == Py_None)
@@ -1209,22 +1244,24 @@
 	Py_XINCREF(del);
 	Py_XINCREF(doc);
 
+	prop->prop_get = get;
+	prop->prop_set = set;
+	prop->prop_del = del;
+	prop->prop_doc = doc;
+	prop->getter_doc = 0;
+
 	/* if no docstring given and the getter has one, use that one */
 	if ((doc == NULL || doc == Py_None) && get != NULL) {
 		PyObject *get_doc = PyObject_GetAttrString(get, "__doc__");
 		if (get_doc != NULL) {
-			Py_XDECREF(doc);
-			doc = get_doc;  /* get_doc already INCREF'd by GetAttr */
+			Py_XDECREF(prop->prop_doc);
+			prop->prop_doc = get_doc;  /* get_doc already INCREF'd by GetAttr */
+			prop->getter_doc = 1;
 		} else {
 			PyErr_Clear();
 		}
 	}
 
-	gs->prop_get = get;
-	gs->prop_set = set;
-	gs->prop_del = del;
-	gs->prop_doc = doc;
-
 	return 0;
 }