[pypy-svn] r75122 - in pypy/trunk/pypy/module/cpyext: . test

afa at codespeak.net afa at codespeak.net
Fri Jun 4 23:26:15 CEST 2010


Author: afa
Date: Fri Jun  4 23:26:14 2010
New Revision: 75122

Modified:
   pypy/trunk/pypy/module/cpyext/slotdefs.py
   pypy/trunk/pypy/module/cpyext/test/foo.c
   pypy/trunk/pypy/module/cpyext/test/test_typeobject.py
Log:
implement wrap_descr_get, wrap_descr_set, wrap_descr_delete


Modified: pypy/trunk/pypy/module/cpyext/slotdefs.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/slotdefs.py	(original)
+++ pypy/trunk/pypy/module/cpyext/slotdefs.py	Fri Jun  4 23:26:14 2010
@@ -5,7 +5,8 @@
 from pypy.module.cpyext.typeobjectdefs import (
     unaryfunc, wrapperfunc, ternaryfunc, PyTypeObjectPtr, binaryfunc,
     getattrfunc, setattrofunc, lenfunc, ssizeargfunc, ssizessizeargfunc,
-    ssizeobjargproc, iternextfunc, initproc, richcmpfunc, hashfunc)
+    ssizeobjargproc, iternextfunc, initproc, richcmpfunc, hashfunc,
+    descrgetfunc, descrsetfunc)
 from pypy.module.cpyext.pyobject import from_ref
 from pypy.module.cpyext.pyerrors import PyErr_Occurred
 from pypy.module.cpyext.state import State
@@ -82,6 +83,44 @@
     if rffi.cast(lltype.Signed, res) == -1:
         space.fromcache(State).check_and_raise_exception(always=True)
 
+def wrap_descr_get(space, w_self, w_args, func):
+    func_target = rffi.cast(descrgetfunc, func)
+    args_w = space.fixedview(w_args)
+    if len(args_w) == 1:
+        w_obj, = args_w
+        w_type = None
+    elif len(args_w) == 2:
+        w_obj, w_type = args_w
+    else:
+        raise operationerrfmt(
+            space.w_TypeError,
+            "expected 1 or 2 arguments, got %d", len(args_w))
+    if w_obj is space.w_None:
+        w_obj = None
+    if w_type is space.w_None:
+        w_type = None
+    if w_obj is None and w_type is None:
+        raise OperationError(
+            space.w_TypeError,
+            space.wrap("__get__(None, None) is invalid"))
+    return generic_cpy_call(space, func_target, w_self, w_obj, w_type)
+
+def wrap_descr_set(space, w_self, w_args, func):
+    func_target = rffi.cast(descrsetfunc, func)
+    check_num_args(space, w_args, 2)
+    w_obj, w_value = space.fixedview(w_args)
+    res = generic_cpy_call(space, func_target, w_self, w_obj, w_value)
+    if rffi.cast(lltype.Signed, res) == -1:
+        space.fromcache(State).check_and_raise_exception(always=True)
+
+def wrap_descr_delete(space, w_self, w_args, func):
+    func_target = rffi.cast(descrsetfunc, func)
+    check_num_args(space, w_args, 1)
+    w_obj, = space.fixedview(w_args)
+    res = generic_cpy_call(space, func_target, w_self, w_obj, None)
+    if rffi.cast(lltype.Signed, res) == -1:
+        space.fromcache(State).check_and_raise_exception(always=True)
+
 def wrap_call(space, w_self, w_args, func, w_kwds):
     func_target = rffi.cast(ternaryfunc, func)
     return generic_cpy_call(space, func_target, w_self, w_args, w_kwds)

Modified: pypy/trunk/pypy/module/cpyext/test/foo.c
==============================================================================
--- pypy/trunk/pypy/module/cpyext/test/foo.c	(original)
+++ pypy/trunk/pypy/module/cpyext/test/foo.c	Fri Jun  4 23:26:14 2010
@@ -483,6 +483,90 @@
     0           /*tp_weaklist*/
 };
 
+PyObject * prop_descr_get(PyObject *self, PyObject *obj, PyObject *type)
+{
+    if (obj == NULL)
+	obj = Py_None;
+    if (type == NULL)
+	type = Py_None;
+
+    return PyTuple_Pack(3, self, obj, type);
+}
+
+int prop_descr_set(PyObject *self, PyObject *obj, PyObject *value)
+{
+    int res;
+    if (value != NULL) {
+	PyObject *result = PyTuple_Pack(2, self, value);
+	res = PyObject_SetAttrString(obj, "y", result);
+	Py_DECREF(result);
+    }
+    else {
+	res = PyObject_SetAttrString(obj, "z", self);
+    }
+    return res;
+}
+
+
+PyTypeObject SimplePropertyType = {
+    PyObject_HEAD_INIT(NULL)
+    0,
+    "foo.Property",
+    sizeof(PyObject),
+    0,
+    0,          /*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*/
+    0,          /*tp_getattro*/
+    0,          /*tp_setattro*/
+    0,          /*tp_as_buffer*/
+
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
+    0,          /*tp_doc*/
+
+    0,          /*tp_traverse*/
+    0,          /*tp_clear*/
+
+    0,          /*tp_richcompare*/
+    0,          /*tp_weaklistoffset*/
+
+    0,          /*tp_iter*/
+    0,          /*tp_iternext*/
+
+    /* Attribute descriptor and subclassing stuff */
+
+    0,          /*tp_methods*/
+    0,          /*tp_members*/
+    0,          /*tp_getset*/
+    0,          /*tp_base*/
+    0,          /*tp_dict*/
+
+    prop_descr_get, /*tp_descr_get*/
+    prop_descr_set, /*tp_descr_set*/
+    0,          /*tp_dictoffset*/
+
+    0,          /*tp_init*/
+    0,          /*tp_alloc  will be set to PyType_GenericAlloc in module init*/
+    0,          /*tp_new*/
+    0,          /*tp_free  Low-level free-memory routine */
+    0,          /*tp_is_gc For PyObject_IS_GC */
+    0,          /*tp_bases*/
+    0,          /*tp_mro method resolution order */
+    0,          /*tp_cache*/
+    0,          /*tp_subclasses*/
+    0           /*tp_weaklist*/
+};
+
 
 /* Initialize this module. */
 
@@ -506,6 +590,8 @@
         return;
     if (PyType_Ready(&InitErrType) < 0)
         return;
+    if (PyType_Ready(&SimplePropertyType) < 0)
+	return;
     m = Py_InitModule("foo", foo_functions);
     if (m == NULL)
         return;
@@ -522,4 +608,6 @@
         return;
     if (PyDict_SetItemString(d, "InitErrType", (PyObject *) &InitErrType) < 0)
         return;
+    if (PyDict_SetItemString(d, "Property", (PyObject *) &SimplePropertyType) < 0)
+        return;
 }

Modified: pypy/trunk/pypy/module/cpyext/test/test_typeobject.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/test/test_typeobject.py	(original)
+++ pypy/trunk/pypy/module/cpyext/test/test_typeobject.py	Fri Jun  4 23:26:14 2010
@@ -192,6 +192,20 @@
         assert d[cmpr] == 72
         assert d[3] == 72
 
+    def test_descriptor(self):
+        module = self.import_module("foo")
+        prop = module.Property()
+        class C(object):
+            x = prop
+        obj = C()
+        assert obj.x == (prop, obj, C)
+        assert C.x == (prop, None, C)
+
+        obj.x = 2
+        assert obj.y == (prop, 2)
+        del obj.x
+        assert obj.z == prop
+
 
 class TestTypes(BaseApiTest):
     def test_type_attributes(self, space, api):



More information about the Pypy-commit mailing list