Пример #1
0
static int
wrap_setattro(PyObject *self, PyObject *name, PyObject *value)
{
    PyObject *wrapped;
    PyObject *descriptor;
    const char *name_as_string;
    int res = -1;

#if PY_MAJOR_VERSION < 3 && defined(Py_USING_UNICODE)
    /* The Unicode to string conversion is done here because the
       existing tp_setattro slots expect a string object as name
       (except under Python 3) and we wouldn't want to break those. */

    if (PyUnicode_Check(name)) {
        name = PyUnicode_AsEncodedString(name, NULL, NULL);
        if (name == NULL)
            return -1;
    }
    else
#endif

    if (!IS_STRING(name)){
        PyErr_SetString(PyExc_TypeError, "attribute name must be string");
        return -1;
    }
    else
        Py_INCREF(name);

    descriptor = WrapperType_Lookup(self->ob_type, name);

    if (descriptor != NULL
#if PY_MAJOR_VERSION < 3 // This is always true in Python 3 (I think)
        && PyType_HasFeature(descriptor->ob_type, Py_TPFLAGS_HAVE_CLASS)
#endif
        && descriptor->ob_type->tp_descr_set != NULL)
      {
        res = descriptor->ob_type->tp_descr_set(descriptor, self, value);
        goto finally;
      }

    name_as_string = MAKE_STRING(name);

    wrapped = Proxy_GET_OBJECT(self);
    if (wrapped == NULL) {
        PyErr_Format(PyExc_RuntimeError,
            "object is NULL; requested to set attribute '%s'",
            name_as_string);
        goto finally;
    }
    res = PyObject_SetAttr(wrapped, name, value);

finally:
    Py_DECREF(name);
    return res;
}
static int
wrap_setattro(PyObject *self, PyObject *name, PyObject *value)
{
    PyObject *wrapped;
    PyObject *descriptor;
    int res = -1;

#ifdef Py_USING_UNICODE
    /* The Unicode to string conversion is done here because the
       existing tp_setattro slots expect a string object as name
       and we wouldn't want to break those. */
    if (PyUnicode_Check(name)) {
        name = PyUnicode_AsEncodedString(name, NULL, NULL);
        if (name == NULL)
            return -1;
    }
    else
#endif
    if (!PyString_Check(name)){
        PyErr_SetString(PyExc_TypeError, "attribute name must be string");
        return -1;
    }
    else
        Py_INCREF(name);

    descriptor = WrapperType_Lookup(self->ob_type, name);
    if (descriptor != NULL) {
        if (PyType_HasFeature(descriptor->ob_type, Py_TPFLAGS_HAVE_CLASS) &&
            descriptor->ob_type->tp_descr_set != NULL) {
            res = descriptor->ob_type->tp_descr_set(descriptor, self, value);
        } else {
            PyErr_Format(PyExc_TypeError,
                "Tried to set attribute '%s' on wrapper, but it is not"
                " a data descriptor", PyString_AS_STRING(name));
        }
        goto finally;
    }

    wrapped = Proxy_GET_OBJECT(self);
    if (wrapped == NULL) {
        PyErr_Format(PyExc_RuntimeError,
            "object is NULL; requested to set attribute '%s'",
            PyString_AS_STRING(name));
        goto finally;
    }
    res = PyObject_SetAttr(wrapped, name, value);

finally:
    Py_DECREF(name);
    return res;
}
static PyObject *
wrap_getattro(PyObject *self, PyObject *name)
{
    PyObject *wrapped;
    PyObject *descriptor;
    PyObject *res = NULL;
    char *name_as_string;
    int maybe_special_name;

#ifdef Py_USING_UNICODE
    /* The Unicode to string conversion is done here because the
       existing tp_getattro slots expect a string object as name
       and we wouldn't want to break those. */
    if (PyUnicode_Check(name)) {
        name = PyUnicode_AsEncodedString(name, NULL, NULL);
        if (name == NULL)
            return NULL;
    }
    else
#endif
    if (!PyString_Check(name)){
        PyErr_SetString(PyExc_TypeError, "attribute name must be string");
        return NULL;
    }
    else
        Py_INCREF(name);

    name_as_string = PyString_AS_STRING(name);
    wrapped = Proxy_GET_OBJECT(self);
    if (wrapped == NULL) {
        PyErr_Format(PyExc_RuntimeError,
            "object is NULL; requested to get attribute '%s'",
            name_as_string);
        goto finally;
    }

    maybe_special_name = name_as_string[0] == '_' && name_as_string[1] == '_';

    if (!(maybe_special_name && strcmp(name_as_string, "__class__") == 0)) {

        descriptor = WrapperType_Lookup(self->ob_type, name);

        if (descriptor != NULL) {
            if (PyType_HasFeature(descriptor->ob_type, Py_TPFLAGS_HAVE_CLASS)
                && descriptor->ob_type->tp_descr_get != NULL) {
                res = descriptor->ob_type->tp_descr_get(
                        descriptor,
                        self,
                        (PyObject *)self->ob_type);
            } else {
                Py_INCREF(descriptor);
                res = descriptor;
            }
            goto finally;
        }
    }
    res = PyObject_GetAttr(wrapped, name);

finally:
    Py_DECREF(name);
    return res;
}