diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 1dfc5abe87b..543dfa475fa 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -1399,13 +1399,16 @@ def compattr(): if verbose: print "Testing computed attributes..." class C(object): class computed_attribute(object): - def __init__(self, get, set=None): + def __init__(self, get, set=None, delete=None): self.__get = get self.__set = set + self.__delete = delete def __get__(self, obj, type=None): return self.__get(obj) def __set__(self, obj, value): return self.__set(obj, value) + def __delete__(self, obj): + return self.__delete(obj) def __init__(self): self.__x = 0 def __get_x(self): @@ -1414,13 +1417,17 @@ def compattr(): return x def __set_x(self, x): self.__x = x - x = computed_attribute(__get_x, __set_x) + def __delete_x(self): + del self.__x + x = computed_attribute(__get_x, __set_x, __delete_x) a = C() vereq(a.x, 0) vereq(a.x, 1) a.x = 10 vereq(a.x, 10) vereq(a.x, 11) + del a.x + vereq(hasattr(a, 'x'), 0) def newslot(): if verbose: print "Testing __new__ slot override..." @@ -1733,8 +1740,8 @@ def properties(): verify(not hasattr(a, "_C__x")) C.x.__set__(a, 100) vereq(C.x.__get__(a), 100) -## C.x.__set__(a) -## verify(not hasattr(a, "x")) + C.x.__delete__(a) + verify(not hasattr(a, "x")) raw = C.__dict__['x'] verify(isinstance(raw, property)) diff --git a/Misc/ACKS b/Misc/ACKS index fa08b8a7236..6e484574863 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -452,6 +452,7 @@ Nathan Sullivan Mark Summerfield Kalle Svensson Hajime Saitou +Nathan Srebro RajGopal Srinivasan Jim St. Pierre Quentin Stafford-Fraser diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 6bd2b7a366c..f7069a0c64b 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2807,6 +2807,22 @@ wrap_descr_set(PyObject *self, PyObject *args, void *wrapped) Py_INCREF(Py_None); return Py_None; } + +static PyObject * +wrap_descr_delete(PyObject *self, PyObject *args, void *wrapped) +{ + descrsetfunc func = (descrsetfunc)wrapped; + PyObject *obj; + int ret; + + if (!PyArg_ParseTuple(args, "O", &obj)) + return NULL; + ret = (*func)(self, obj, NULL); + if (ret < 0) + return NULL; + Py_INCREF(Py_None); + return Py_None; +} static PyObject * wrap_init(PyObject *self, PyObject *args, void *wrapped, PyObject *kwds) @@ -3883,6 +3899,8 @@ static slotdef slotdefs[] = { "descr.__get__(obj[, type]) -> value"), TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set, "descr.__set__(obj, value)"), + TPSLOT("__delete__", tp_descr_set, slot_tp_descr_set, + wrap_descr_delete, "descr.__delete__(obj)"), FLSLOT("__init__", tp_init, slot_tp_init, (wrapperfunc)wrap_init, "x.__init__(...) initializes x; " "see x.__class__.__doc__ for signature",