New submission from Guido van Rossum:
Here's an implementation of the idea I floated recently on python-dev
(Subject: Declaring setters with getters). This implements the kind of
syntax that I believe won over most folks in the end:
@property
def foo(self): ...
@foo.setter
def foo(self, value=None): ...
There are also .getter and .deleter descriptors. This includes the hack
that if you specify a setter but no deleter, the setter is called
without a value argument when attempting to delete something. If the
setter isn't ready for this, a TypeError will be raised, pretty much
just as if no deleter was provided (just with a somewhat worse error
message :-).
I intend to check this into 2.6 and 3.0 unless there is a huge cry of
dismay. Docs will be left to volunteers as always.
----------
assignee: gvanrossum
files: propset.diff
keywords: patch
messages: 57345
nosy: gvanrossum
priority: normal
severity: normal
status: open
title: @prop.setter decorators
versions: Python 2.6, Python 3.0
Added file: http://bugs.python.org/file8724/propset.diff
__________________________________
Tracker <[EMAIL PROTECTED]>
<http://bugs.python.org/issue1416>
__________________________________
Index: Objects/descrobject.c
===================================================================
--- Objects/descrobject.c (revision 58892)
+++ Objects/descrobject.c (working copy)
@@ -1099,7 +1099,66 @@
{0}
};
+PyDoc_STRVAR(getter_doc,
+ "Descriptor to change the setter 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;
+}
+
+PyDoc_STRVAR(setter_doc,
+ "Descriptor to change the setter on a property.\n"
+ "This also sets the deleter if it hasn't been set before.");
+
+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;
+ if (((propertyobject *)self)->prop_del == NULL && setter != NULL) {
+ Py_INCREF(setter);
+ ((propertyobject *)self)->prop_del = setter;
+ }
+ Py_INCREF(self);
+ return self;
+}
+
+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;
+}
+
+
+
+static PyMethodDef property_methods[] = {
+ {"getter", property_getter, METH_O, getter_doc},
+ {"setter", property_setter, METH_O, setter_doc},
+ {"deleter", property_deleter, METH_O, deleter_doc},
+ {0}
+};
+
+
static void
property_dealloc(PyObject *self)
{
@@ -1251,7 +1310,7 @@
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
- 0, /* tp_methods */
+ property_methods, /* tp_methods */
property_members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
Index: Lib/test/test_descr.py
===================================================================
--- Lib/test/test_descr.py (revision 58892)
+++ Lib/test/test_descr.py (working copy)
@@ -1984,6 +1984,43 @@
p = property(_testcapi.test_with_docstring)
+def properties_more():
+ class C:
+ foo = property(doc="hello")
+
+ @foo.getter
+ def foo(self):
+ return self._foo
+
+ @foo.setter
+ def foo(self, value=None):
+ if value is None:
+ del self._foo
+ else:
+ self._foo = abs(value)
+
+ c = C()
+ assert C.foo.__doc__ == "hello"
+ assert not hasattr(c, "foo")
+ c.foo = -42
+ assert c.foo == 42
+ del c.foo
+ assert not hasattr(c, "foo")
+
+ class D(C):
+ @C.foo.deleter
+ def foo(self):
+ try:
+ del self._foo
+ except AttributeError:
+ pass
+
+ d = D()
+ d.foo = 24
+ del d.foo
+ del d.foo
+
+
def supers():
if verbose: print("Testing super...")
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com