📄 descrobject.c
字号:
}
DL_EXPORT(int)
PyDescr_IsData(PyObject *d)
{
return d->ob_type->tp_descr_set != NULL;
}
/* --- Readonly proxy for dictionaries (actually any mapping) --- */
/* This has no reason to be in this file except that adding new files is a
bit of a pain */
typedef struct {
PyObject_HEAD
PyObject *dict;
} proxyobject;
static int
proxy_len(proxyobject *pp)
{
return PyObject_Size(pp->dict);
}
static PyObject *
proxy_getitem(proxyobject *pp, PyObject *key)
{
return PyObject_GetItem(pp->dict, key);
}
static const PyMappingMethods proxy_as_mapping = {
(inquiry)proxy_len, /* mp_length */
(binaryfunc)proxy_getitem, /* mp_subscript */
0, /* mp_ass_subscript */
};
static int
proxy_contains(proxyobject *pp, PyObject *key)
{
return PySequence_Contains(pp->dict, key);
}
const static PySequenceMethods proxy_as_sequence = {
0, /* sq_length */
0, /* sq_concat */
0, /* sq_repeat */
0, /* sq_item */
0, /* sq_slice */
0, /* sq_ass_item */
0, /* sq_ass_slice */
(objobjproc)proxy_contains, /* sq_contains */
0, /* sq_inplace_concat */
0, /* sq_inplace_repeat */
};
static PyObject *
proxy_has_key(proxyobject *pp, PyObject *key)
{
return PyInt_FromLong(PySequence_Contains(pp->dict, key));
}
static PyObject *
proxy_get(proxyobject *pp, PyObject *args)
{
PyObject *key, *def = Py_None;
if (!PyArg_ParseTuple(args, "O|O:get", &key, &def))
return NULL;
return PyObject_CallMethod(pp->dict, "get", "(OO)", key, def);
}
static PyObject *
proxy_keys(proxyobject *pp)
{
return PyMapping_Keys(pp->dict);
}
static PyObject *
proxy_values(proxyobject *pp)
{
return PyMapping_Values(pp->dict);
}
static PyObject *
proxy_items(proxyobject *pp)
{
return PyMapping_Items(pp->dict);
}
static PyObject *
proxy_copy(proxyobject *pp)
{
return PyObject_CallMethod(pp->dict, "copy", NULL);
}
const static PyMethodDef proxy_methods[] = {
{"has_key", (PyCFunction)proxy_has_key, METH_O, "XXX"},
{"get", (PyCFunction)proxy_get, METH_VARARGS, "XXX"},
{"keys", (PyCFunction)proxy_keys, METH_NOARGS, "XXX"},
{"values", (PyCFunction)proxy_values, METH_NOARGS, "XXX"},
{"items", (PyCFunction)proxy_items, METH_NOARGS, "XXX"},
{"copy", (PyCFunction)proxy_copy, METH_NOARGS, "XXX"},
{0}
};
static void
proxy_dealloc(proxyobject *pp)
{
_PyObject_GC_UNTRACK(pp);
Py_DECREF(pp->dict);
PyObject_GC_Del(pp);
}
static PyObject *
proxy_getiter(proxyobject *pp)
{
return PyObject_GetIter(pp->dict);
}
static PyObject *
proxy_str(proxyobject *pp)
{
return PyObject_Str(pp->dict);
}
static int
proxy_traverse(PyObject *self, visitproc visit, void *arg)
{
proxyobject *pp = (proxyobject *)self;
int err;
if (pp->dict) {
err = visit(pp->dict, arg);
if (err)
return err;
}
return 0;
}
#ifndef SYMBIAN
PyTypeObject proxytype = {
PyObject_HEAD_INIT(&PyType_Type)
#else
const PyTypeObject c_proxytype = {
PyObject_HEAD_INIT(NULL)
#endif
0, /* ob_size */
"dict-proxy", /* tp_name */
sizeof(proxyobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
(destructor)proxy_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
&proxy_as_sequence, /* tp_as_sequence */
&proxy_as_mapping, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
(reprfunc)proxy_str, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
0, /* tp_doc */
proxy_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
(getiterfunc)proxy_getiter, /* tp_iter */
0, /* tp_iternext */
proxy_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
};
DL_EXPORT(PyObject *)
PyDictProxy_New(PyObject *dict)
{
proxyobject *pp;
pp = PyObject_GC_New(proxyobject, &proxytype);
if (pp != NULL) {
Py_INCREF(dict);
pp->dict = dict;
_PyObject_GC_TRACK(pp);
}
return (PyObject *)pp;
}
/* --- Wrapper object for "slot" methods --- */
/* This has no reason to be in this file except that adding new files is a
bit of a pain */
typedef struct {
PyObject_HEAD
PyWrapperDescrObject *descr;
PyObject *self;
} wrapperobject;
static void
wrapper_dealloc(wrapperobject *wp)
{
_PyObject_GC_UNTRACK(wp);
Py_XDECREF(wp->descr);
Py_XDECREF(wp->self);
PyObject_GC_Del(wp);
}
const static PyMethodDef wrapper_methods[] = {
{0}
};
static PyObject *
wrapper_name(wrapperobject *wp)
{
char *s = wp->descr->d_base->name;
return PyString_FromString(s);
}
static PyObject *
wrapper_doc(wrapperobject *wp)
{
char *s = wp->descr->d_base->doc;
if (s == NULL) {
Py_INCREF(Py_None);
return Py_None;
}
else {
return PyString_FromString(s);
}
}
const static PyGetSetDef wrapper_getsets[] = {
{"__name__", (getter)wrapper_name},
{"__doc__", (getter)wrapper_doc},
{0}
};
static PyObject *
wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds)
{
wrapperfunc wrapper = wp->descr->d_base->wrapper;
PyObject *self = wp->self;
if (wp->descr->d_base->flags & PyWrapperFlag_KEYWORDS) {
wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper;
return (*wk)(self, args, wp->descr->d_wrapped, kwds);
}
if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_Size(kwds) != 0)) {
PyErr_Format(PyExc_TypeError,
"wrapper %s doesn't take keyword arguments",
wp->descr->d_base->name);
return NULL;
}
return (*wrapper)(self, args, wp->descr->d_wrapped);
}
static int
wrapper_traverse(PyObject *self, visitproc visit, void *arg)
{
wrapperobject *wp = (wrapperobject *)self;
int err;
if (wp->descr) {
err = visit((PyObject *)(wp->descr), arg);
if (err)
return err;
}
if (wp->self) {
err = visit(wp->self, arg);
if (err)
return err;
}
return 0;
}
#ifndef SYMBIAN
PyTypeObject wrappertype = {
PyObject_HEAD_INIT(&PyType_Type)
#else
const PyTypeObject c_wrappertype = {
PyObject_HEAD_INIT(NULL)
#endif
0, /* ob_size */
"method-wrapper", /* tp_name */
sizeof(wrapperobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
(destructor)wrapper_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 */
(ternaryfunc)wrapper_call, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
0, /* tp_doc */
wrapper_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
wrapper_methods, /* tp_methods */
0, /* tp_members */
wrapper_getsets, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
};
DL_EXPORT(PyObject *)
PyWrapper_New(PyObject *d, PyObject *self)
{
wrapperobject *wp;
PyWrapperDescrObject *descr;
assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type));
descr = (PyWrapperDescrObject *)d;
assert(PyObject_IsInstance(self, (PyObject *)(descr->d_type)));
wp = PyObject_GC_New(wrapperobject, &wrappertype);
if (wp != NULL) {
Py_INCREF(descr);
wp->descr = descr;
Py_INCREF(self);
wp->self = self;
_PyObject_GC_TRACK(wp);
}
return (PyObject *)wp;
}
/* A built-in 'property' type */
/*
class property(object):
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
self.__get = fget
self.__set = fset
self.__del = fdel
self.__doc__ = doc
def __get__(self, inst, type=None):
if inst is None:
return self
if self.__get is None:
raise AttributeError, "unreadable attribute"
return self.__get(inst)
def __set__(self, inst, value):
if self.__set is None:
raise AttributeError, "can't set attribute"
return self.__set(inst, value)
def __delete__(self, inst):
if self.__del is None:
raise AttributeError, "can't delete attribute"
return self.__del(inst)
*/
typedef struct {
PyObject_HEAD
PyObject *prop_get;
PyObject *prop_set;
PyObject *prop_del;
PyObject *prop_doc;
} propertyobject;
const static PyMemberDef property_members[] = {
{"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY},
{"fset", T_OBJECT, offsetof(propertyobject, prop_set), READONLY},
{"fdel", T_OBJECT, offsetof(propertyobject, prop_del), READONLY},
{"__doc__", T_OBJECT, offsetof(propertyobject, prop_doc), READONLY},
{0}
};
static void
property_dealloc(PyObject *self)
{
propertyobject *gs = (propertyobject *)self;
_PyObject_GC_UNTRACK(self);
Py_XDECREF(gs->prop_get);
Py_XDECREF(gs->prop_set);
Py_XDECREF(gs->prop_del);
Py_XDECREF(gs->prop_doc);
self->ob_type->tp_free(self);
}
static PyObject *
property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
{
propertyobject *gs = (propertyobject *)self;
if (obj == NULL || obj == Py_None) {
Py_INCREF(self);
return self;
}
if (gs->prop_get == NULL) {
PyErr_SetString(PyExc_AttributeError, "unreadable attribute");
return NULL;
}
return PyObject_CallFunction(gs->prop_get, "(O)", obj);
}
static int
property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
{
propertyobject *gs = (propertyobject *)self;
PyObject *func, *res;
if (value == NULL)
func = gs->prop_del;
else
func = gs->prop_set;
if (func == NULL) {
PyErr_SetString(PyExc_AttributeError,
value == NULL ?
"can't delete attribute" :
"can't set attribute");
return -1;
}
if (value == NULL)
res = PyObject_CallFunction(func, "(O)", obj);
else
res = PyObject_CallFunction(func, "(OO)", obj, value);
if (res == NULL)
return -1;
Py_DECREF(res);
return 0;
}
static int
property_init(PyObject *self, PyObject *args, PyObject *kwds)
{
PyObject *get = NULL, *set = NULL, *del = NULL, *doc = NULL;
static const char *const kwlist[] = {"fget", "fset", "fdel", "doc", 0};
propertyobject *gs = (propertyobject *)self;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOO:property", kwlist,
&get, &set, &del, &doc))
return -1;
if (get == Py_None)
get = NULL;
if (set == Py_None)
set = NULL;
if (del == Py_None)
del = NULL;
Py_XINCREF(get);
Py_XINCREF(set);
Py_XINCREF(del);
Py_XINCREF(doc);
gs->prop_get = get;
gs->prop_set = set;
gs->prop_del = del;
gs->prop_doc = doc;
return 0;
}
const static char property_doc[] =
#ifdef SYMBIAN
"";
#else
"property(fget=None, fset=None, fdel=None, doc=None) -> property attribute\n"
"\n"
"fget is a function to be used for getting an attribute value, and likewise\n"
"fset is a function for setting, and fdel a function for del'ing, an\n"
"attribute. Typical use is to define a managed attribute x:\n"
"class C(object):\n"
" def getx(self): return self.__x\n"
" def setx(self, value): self.__x = value\n"
" def delx(self): del self.__x\n"
" x = property(getx, setx, delx, \"I'm the 'x' property.\")";
#endif
static int
property_traverse(PyObject *self, visitproc visit, void *arg)
{
propertyobject *pp = (propertyobject *)self;
int err;
#define VISIT(SLOT) \
if (pp->SLOT) { \
err = visit((PyObject *)(pp->SLOT), arg); \
if (err) \
return err; \
}
VISIT(prop_get);
VISIT(prop_set);
VISIT(prop_del);
return 0;
}
#ifndef SYMBIAN
PyTypeObject PyProperty_Type = {
PyObject_HEAD_INIT(&PyType_Type)
#else
const PyTypeObject c_PyProperty_Type = {
PyObject_HEAD_INIT(NULL)
#endif
0, /* ob_size */
"property", /* tp_name */
sizeof(propertyobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
property_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 | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
property_doc, /* tp_doc */
property_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
property_members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
property_descr_get, /* tp_descr_get */
property_descr_set, /* tp_descr_set */
0, /* tp_dictoffset */
property_init, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
PyType_GenericNew, /* tp_new */
_PyObject_GC_Del, /* tp_free */
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -