]> granicus.if.org Git - python/commitdiff
Add new built-in type 'getset' (PyGetSet_Type).
authorGuido van Rossum <guido@python.org>
Thu, 23 Aug 2001 21:40:38 +0000 (21:40 +0000)
committerGuido van Rossum <guido@python.org>
Thu, 23 Aug 2001 21:40:38 +0000 (21:40 +0000)
This implements the 'getset' class from test_binop.py.

Include/descrobject.h
Objects/descrobject.c
Python/bltinmodule.c

index b6fc52102236af44071cab531230cee841d5e881..03543aee38587b1a614c539954fe0128b43bd78a 100644 (file)
@@ -30,3 +30,6 @@ extern DL_IMPORT(int) PyDescr_IsData(PyObject *);
 
 extern DL_IMPORT(PyObject *) PyDictProxy_New(PyObject *);
 extern DL_IMPORT(PyObject *) PyWrapper_New(PyObject *, PyObject *);
+
+
+extern DL_IMPORT(PyTypeObject) PyGetSet_Type;
index facd1c4ff58831319eea04cd2a413df94f56c08f..2cb28b3a0f25346ba3fb2728574989a86297c651 100644 (file)
@@ -840,3 +840,138 @@ PyWrapper_New(PyObject *d, PyObject *self)
        }
        return (PyObject *)wp;
 }
+
+
+/* A built-in 'getset' type */
+
+/*
+    class getset(object):
+
+       def __init__(self, get=None, set=None):
+           self.__get = get
+           self.__set = set
+
+       def __get__(self, inst, type=None):
+           if self.__get is None:
+               raise AttributeError, "unreadable attribute"
+           if inst is None:
+               return self
+           return self.__get(inst)
+
+       def __set__(self, inst, value):
+           if self.__set is None:
+               raise AttributeError, "unsettable attribute"
+           return self.__set(inst, value)
+*/
+
+typedef struct {
+       PyObject_HEAD
+       PyObject *get;
+       PyObject *set;
+} getsetobject;
+
+static void
+getset_dealloc(PyObject *self)
+{
+       getsetobject *gs = (getsetobject *)self;
+
+       Py_XDECREF(gs->get);
+       Py_XDECREF(gs->set);
+       self->ob_type->tp_free(self);
+}
+
+static PyObject *
+getset_descr_get(PyObject *self, PyObject *obj, PyObject *type)
+{
+       getsetobject *gs = (getsetobject *)self;
+
+       if (gs->get == NULL) {
+               PyErr_SetString(PyExc_AttributeError, "unreadable attribute");
+               return NULL;
+       }
+       if (obj == NULL || obj == Py_None) {
+               Py_INCREF(self);
+               return self;
+       }
+       return PyObject_CallFunction(gs->get, "(O)", obj);
+}
+
+static int
+getset_descr_set(PyObject *self, PyObject *obj, PyObject *value)
+{
+       getsetobject *gs = (getsetobject *)self;
+       PyObject *res;
+
+       if (gs->set == NULL) {
+               PyErr_SetString(PyExc_AttributeError, "unsettable attribute");
+               return -1;
+       }
+       res = PyObject_CallFunction(gs->set, "(OO)", obj, value);
+       if (res == NULL)
+               return -1;
+       Py_DECREF(res);
+       return 0;
+}
+
+static int
+getset_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+       PyObject *get, *set;
+       getsetobject *gs = (getsetobject *)self;
+
+       if (!PyArg_ParseTuple(args, "OO:getset.__init__", &get, &set))
+               return -1;
+       if (get == Py_None)
+               get = NULL;
+       if (set == Py_None)
+               set = NULL;
+       Py_XINCREF(get);
+       Py_XINCREF(set);
+       gs->get = get;
+       gs->set = set;
+       return 0;
+}
+
+PyTypeObject PyGetSet_Type = {
+       PyObject_HEAD_INIT(&PyType_Type)
+       0,                                      /* ob_size */
+       "getset",                               /* tp_name */
+       sizeof(getsetobject),                   /* tp_basicsize */
+       0,                                      /* tp_itemsize */
+       /* methods */
+       getset_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,                     /* 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 */
+       getset_descr_get,                       /* tp_descr_get */
+       getset_descr_set,                       /* tp_descr_set */
+       0,                                      /* tp_dictoffset */
+       getset_init,                            /* tp_init */
+       PyType_GenericAlloc,                    /* tp_alloc */
+       PyType_GenericNew,                      /* tp_new */
+       _PyObject_Del,                          /* tp_free */
+};
index 9a6f5e411a475535ed1aca2f2383b5e2d37f0859..77fe3844c314ccb7602e1ea35dab0a7e6a3be545 100644 (file)
@@ -1921,6 +1921,9 @@ _PyBuiltin_Init(void)
        if (PyDict_SetItemString(dict, "float",
                                 (PyObject *) &PyFloat_Type) < 0)
                return NULL;
+       if (PyDict_SetItemString(dict, "getset",
+                                (PyObject *) &PyGetSet_Type) < 0)
+               return NULL;
        if (PyDict_SetItemString(dict, "int", (PyObject *) &PyInt_Type) < 0)
                return NULL;
        if (PyDict_SetItemString(dict, "list", (PyObject *) &PyList_Type) < 0)