📄 dictproxy.cpp
字号:
}
static int PyOrange_DictProxy_contains(TPyOrange_DictProxy *mp, PyObject *key)
{
if (!PyString_Check(key))
PYERROR(PyExc_AttributeError, "object's attribute name must be string", -1);
char *name = PyString_AsString(key);
const TPropertyDescription *pd = PyOrange_AS_Orange(mp->backlink)->classDescription()->properties;
while(pd->name && strcmp(pd->name, name))
pd++;
if (pd->name)
return 1;
return PyDict_GetItem((PyObject *)mp, key)!=NULL ? 1 : 0;
}
PyObject *PyOrange_DictProxyIter_new(TPyOrange_DictProxy *dict, binaryfunc select);
PyObject *select_key(PyObject *key, PyObject *value);
PyObject *select_value(PyObject *key, PyObject *value);
PyObject *select_item(PyObject *key, PyObject *value);
PyObject *PyOrange_DictProxy_iterkeys(TPyOrange_DictProxy *dict)
{ return PyOrange_DictProxyIter_new(dict, select_key); }
static PyObject *PyOrange_DictProxy_itervalues(TPyOrange_DictProxy *dict)
{ return PyOrange_DictProxyIter_new(dict, select_value); }
static PyObject *PyOrange_DictProxy_iteritems(TPyOrange_DictProxy *dict)
{ return PyOrange_DictProxyIter_new(dict, select_item); }
static PyObject *PyOrange_DictProxy_iter(TPyOrange_DictProxy *mp)
{ return PyOrange_DictProxyIter_new(mp, select_key); }
#define NO_METHOD(name) \
PyObject *PyOrange_DictProxy_##name(PyObject *, PyObject *, PyObject *) \
{ PYERROR(PyExc_AttributeError, "Orange dictionary proxy does not support "#name, PYNULL); }
NO_METHOD(popitem)
NO_METHOD(fromkeys)
NO_METHOD(copy)
NO_METHOD(clear)
#undef NO_METHOD
#define NO_METHOD(name) \
{#name, (PyCFunction)PyOrange_DictProxy_##name, METH_VARARGS, ""},
static PyMethodDef PyOrange_DictProxy_methods[] = {
{"has_key", (PyCFunction)PyOrange_DictProxy_has_key, METH_O, ""},
{"get", (PyCFunction)PyOrange_DictProxy_get, METH_VARARGS, ""},
{"setdefault", (PyCFunction)PyOrange_DictProxy_setdefault, METH_VARARGS, ""},
{"pop", (PyCFunction)PyOrange_DictProxy_pop, METH_VARARGS, ""},
{"keys", (PyCFunction)PyOrange_DictProxy_keys, METH_NOARGS, ""},
{"items", (PyCFunction)PyOrange_DictProxy_items, METH_NOARGS, ""},
{"values", (PyCFunction)PyOrange_DictProxy_values, METH_NOARGS, ""},
{"update", (PyCFunction)PyOrange_DictProxy_update, METH_O, ""},
{"iterkeys", (PyCFunction)PyOrange_DictProxy_iterkeys, METH_NOARGS, ""},
{"itervalues", (PyCFunction)PyOrange_DictProxy_itervalues, METH_NOARGS, ""},
{"iteritems", (PyCFunction)PyOrange_DictProxy_iteritems, METH_NOARGS, ""},
NO_METHOD(popitem)
NO_METHOD(fromkeys)
NO_METHOD(copy)
NO_METHOD(clear)
#undef NO_METHOD
{NULL, NULL} /* sentinel */
};
static PyMappingMethods PyOrange_DictProxy_as_mapping = {
(inquiry)PyOrange_DictProxy_length,
(binaryfunc)PyOrange_DictProxy_subscript, /*mp_subscript*/
(objobjargproc)PyOrange_DictProxy_ass_sub, /*mp_ass_subscript*/
};
/* Hack to implement "key in dict" */
static PySequenceMethods PyOrange_DictProxy_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)PyOrange_DictProxy_contains, /* sq_contains */
0, /* sq_inplace_concat */
0, /* sq_inplace_repeat */
};
static PyObject *PyOrange_DictProxy_hash(PyObject *v, PyObject *w, int op)
{ PYERROR(PyExc_AttributeError, "Orange dictionary proxy is not hashable", PYNULL); }
PyTypeObject PyOrange_DictProxy_Type = {
PyObject_HEAD_INIT(&PyType_Type)
0,
"Orange proxy dict",
sizeof(TPyOrange_DictProxy),
0,
PyOrange_DictProxy_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
(reprfunc)PyOrange_DictProxy_repr,
0,
&PyOrange_DictProxy_as_sequence,
&PyOrange_DictProxy_as_mapping,
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr,
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
0, /* tp_doc */
(traverseproc)PyDict_Type.tp_traverse,
(inquiry)PyDict_Type.tp_clear,
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
(getiterfunc)PyOrange_DictProxy_iter,
0, /* tp_iternext */
PyOrange_DictProxy_methods,
0, /* tp_members */
0, /* tp_getset */
&PyDict_Type, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
PyType_GenericAlloc,
0, /* tp_new */
_PyObject_GC_Del,
};
/* PyDictIter_Type has no Py_TPFLAGS_BASETYPE set, so I cannot
derive the iterator. Most of the following code is base on
the corresponding functions from dictobject.c. */
PyObject *select_key(PyObject *key, PyObject *value)
{
Py_INCREF(key);
return key;
}
PyObject *select_value(PyObject *key, PyObject *value)
{
Py_INCREF(value);
return value;
}
PyObject *select_item(PyObject *key, PyObject *value)
{
PyObject *res = PyTuple_New(2);
if (res != NULL) {
Py_INCREF(key);
Py_INCREF(value);
PyTuple_SET_ITEM(res, 0, key);
PyTuple_SET_ITEM(res, 1, value);
}
return res;
}
extern PyTypeObject PyOrange_DictProxyIter_Type;
class TPyOrange_DictyProxyIter {
public:
PyObject_HEAD
TPyOrange_DictProxy *di_dict; /* Set to NULL when iterator is exhausted */
binaryfunc di_select;
// This is for iteration over built-ins...
const TPropertyDescription *pd;
// ...and that's for the dictionary
int di_used;
int di_pos;
};
PyObject *PyOrange_DictProxyIter_new(TPyOrange_DictProxy *dict, binaryfunc select)
{
TPyOrange_DictyProxyIter *di = PyObject_New(TPyOrange_DictyProxyIter, &PyOrange_DictProxyIter_Type);
if (di == NULL)
return NULL;
Py_INCREF(dict);
di->di_dict = dict;
di->di_select = select;
di->pd = dict->backlink ? PyOrange_AS_Orange(di->di_dict->backlink)->classDescription()->properties : NULL;
di->di_used = dict->ma_used;
di->di_pos = 0;
return (PyObject *)di;
}
void PyOrange_DictProxyIter_dealloc(TPyOrange_DictyProxyIter *di)
{
Py_XDECREF(di->di_dict);
PyObject_Del(di);
}
static PyObject *PyOrange_DictProxyIter_iternext(TPyOrange_DictyProxyIter *di)
{
PyObject *key, *value;
if (di->di_dict == NULL)
return NULL;
if (di->pd) {
if (!di->di_dict->backlink) {
di->di_used = -1;
PYERROR(PyExc_RuntimeError, "Orange object destroyed during iteration", PYNULL);
}
PyObject *res;
if (di->di_select == select_key)
res = PyString_FromString(di->pd->name);
else {
PyObject *value = Orange_getattr1(di->di_dict->backlink, di->pd->name);
if (di->di_select == select_value)
res = value;
else {
res = select_item(PyString_FromString(di->pd->name), value);
Py_DECREF(value);
}
}
if (!(++di->pd)->name)
di->pd = NULL;
return res;
}
else {
if (di->di_used != di->di_dict->ma_used) {
di->di_used = -1; /* Make this state sticky */
PYERROR(PyExc_RuntimeError, "dictionary changed size during iteration", PYNULL);
}
if (PyDict_Next((PyObject *)(di->di_dict), &di->di_pos, &key, &value))
return (*di->di_select)(key, value);
}
Py_DECREF(di->di_dict);
di->di_dict = NULL;
return NULL;
}
// Could use Python's, but it only appeared in 2.3
// We can remove this when we stop caring about 2.2 users
PyObject *PyObject_MySelfIter(PyObject *obj)
{
Py_INCREF(obj);
return obj;
}
PyTypeObject PyOrange_DictProxyIter_Type = {
PyObject_HEAD_INIT(&PyType_Type)
0, /* ob_size */
"orange dictionary proxy-iterator", /* tp_name */
sizeof(TPyOrange_DictyProxyIter), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
(destructor)PyOrange_DictProxyIter_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 */
PyObject_MySelfIter, /* tp_iter */
(iternextfunc)PyOrange_DictProxyIter_iternext, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -