📄 dictproxy.cpp
字号:
/*
This file is part of Orange.
Orange is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Orange is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Orange; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Authors: Janez Demsar, Blaz Zupan, 1996--2002
Contact: janez.demsar@fri.uni-lj.si
*/
#include "cls_orange.hpp"
PyObject *PyOrange_DictProxy_New(TPyOrange *bl)
{
// Cannot implement print (crashes due to FILE *)
// So I need to disable the inherited
PyOrange_DictProxy_Type.tp_print = 0;
PyObject *mp = PyDict_Type.tp_new(&PyOrange_DictProxy_Type, PYNULL, PYNULL);
((TPyOrange_DictProxy *)mp)->backlink = bl;
bl->orange_dict = mp;
return mp;
}
void PyOrange_DictProxy_dealloc(PyObject *mp)
{
TPyOrange *backlink = ((TPyOrange_DictProxy *)mp)->backlink;
if (backlink)
backlink->orange_dict = NULL;
PyDict_Type.tp_dealloc(mp);
}
PyObject *PyOrange_DictProxy_repr(TPyOrange_DictProxy *mp)
{
string s = "{";
bool notFirst = false;
if (mp->backlink) {
for (const TPropertyDescription *pd = PyOrange_AS_Orange(mp->backlink)->classDescription()->properties; pd->name; pd++) {
PyObject *pyval = Orange_getattr1(mp->backlink, pd->name);
if (!pyval)
return PYNULL;
PyObject *pystr = PyObject_Repr(pyval);
Py_DECREF(pyval);
if (!pystr || !PyString_Check(pystr)) {
Py_XDECREF(pystr);
return PYNULL;
}
if (notFirst)
s += ", ";
else
notFirst = true;
s += "'";
s += pd->name;
s += "': ";
s += PyString_AsString(pystr);
Py_DECREF(pystr);
}
}
PyObject *pystr = PyDict_Type.tp_repr((PyObject *)mp);
if (!pystr || !PyString_Check(pystr)) {
Py_XDECREF(pystr);
return PYNULL;
}
if (notFirst && (PyString_Size(pystr) > 2))
s += "; ";
s += PyString_AsString(pystr) + 1;
Py_DECREF(pystr);
return PyString_FromString(s.c_str());
}
int PyOrange_DictProxy_length(TPyOrange_DictProxy *mp)
{
int inlen = PyDict_Size((PyObject *)mp);
if (mp->backlink) {
const TPropertyDescription *ppd = PyOrange_AS_Orange(mp->backlink)->classDescription()->properties, *pd = ppd;
while(pd->name)
pd++;
inlen += pd-ppd;
}
return inlen;
}
PyObject *PyOrange_DictProxy_subscript(TPyOrange_DictProxy *mp, PyObject *key)
{
if (!PyString_Check(key))
PYERROR(PyExc_AttributeError, "object's attribute name must be string", PYNULL);
if (mp->backlink)
return Orange_getattr(mp->backlink, key);
return PyDict_Type.tp_as_mapping->mp_subscript((PyObject *)mp, key);
}
int PyOrange_DictProxy_ass_sub(TPyOrange_DictProxy *mp, PyObject *v, PyObject *w)
{
if (!PyString_Check(v))
PYERROR(PyExc_AttributeError, "object's attribute name must be string", -1);
if (mp->backlink)
return Orange_setattrLow(mp->backlink, v, w, false);
return PyDict_Type.tp_as_mapping->mp_ass_subscript((PyObject *)mp, v, w);
}
static PyObject *PyOrange_DictProxy_keys(TPyOrange_DictProxy *mp)
{
PyObject *keys = PyDict_Keys((PyObject *)mp);
if (mp->backlink)
for(const TPropertyDescription *pd = PyOrange_AS_Orange(mp->backlink)->classDescription()->properties; pd->name; pd++) {
PyObject *pyname = PyString_FromString(pd->name);
PyList_Append(keys, pyname);
Py_DECREF(pyname);
}
return keys;
}
static PyObject *PyOrange_DictProxy_values(TPyOrange_DictProxy *mp)
{
PyObject *values = PyDict_Values((PyObject *)mp);
if (mp->backlink)
for(const TPropertyDescription *pd = PyOrange_AS_Orange(mp->backlink)->classDescription()->properties; pd->name; pd++) {
PyObject *pyattr = Orange_getattr1(mp->backlink, pd->name);
if (!pyattr) {
Py_DECREF(values);
return PYNULL;
}
PyList_Append(values, pyattr);
Py_DECREF(pyattr);
}
return values;
}
static PyObject *PyOrange_DictProxy_items(TPyOrange_DictProxy *mp)
{
PyObject *items = PyDict_Items((PyObject *)mp);
if (mp->backlink)
for(const TPropertyDescription *pd = PyOrange_AS_Orange(mp->backlink)->classDescription()->properties; pd->name; pd++) {
PyObject *pyattr = Orange_getattr1(mp->backlink, pd->name);
if (!pyattr) {
Py_DECREF(items);
return PYNULL;
}
PyList_Append(items, Py_BuildValue("sN", pd->name, pyattr));
}
return items;
}
static PyObject *PyOrange_DictProxy_update(TPyOrange_DictProxy *mp, PyObject *seq2)
{
PyObject *key, *value;
int pos = 0;
while (PyDict_Next(seq2, &pos, &key, &value)) {
if (!PyString_Check(key))
PYERROR(PyExc_AttributeError, "object's attribute name must be string", PYNULL);
int res = mp->backlink ? Orange_setattrLow(mp->backlink, key, value, false) : 1;
if ( (res == -1)
|| ((res == 1) && (PyDict_SetItem((PyObject *)mp, key, value) == -1)))
return PYNULL;
}
RETURN_NONE;
}
PyObject *PyOrange_DictProxy_has_key(TPyOrange_DictProxy *mp, PyObject *key)
{
if (!PyString_Check(key))
PYERROR(PyExc_AttributeError, "object's attribute name must be string", PYNULL);
if (mp->backlink) {
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 PyInt_FromLong(1);
}
return PyInt_FromLong(PyDict_GetItem((PyObject *)mp, key) ? 1 : 0);
}
PyObject *PyOrange_DictProxy_get(TPyOrange_DictProxy *mp, PyObject *args)
{
PyObject *key;
PyObject *failobj = Py_None;
if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &failobj))
return NULL;
if (!PyString_Check(key))
PYERROR(PyExc_AttributeError, "object's attribute name must be string", PYNULL);
if (mp->backlink) {
PyObject *res = Orange_getattr(mp->backlink, key);
if (res)
return res;
PyErr_Clear();
}
PyObject *val = PyDict_GetItem((PyObject *)mp, key);
if (!val)
val = failobj;
Py_INCREF(val);
return val;
}
PyObject *PyOrange_DictProxy_setdefault(TPyOrange_DictProxy *mp, PyObject *args)
{
PyObject *key;
PyObject *failobj = Py_None;
if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &failobj))
return NULL;
if (!PyString_Check(key))
PYERROR(PyExc_AttributeError, "object's attribute name must be string", PYNULL);
if (mp->backlink) {
PyObject *val = Orange_getattr(mp->backlink, key);
if (val)
return val;
PyErr_Clear();
}
PyObject *val = PyDict_GetItem((PyObject *)mp, key);
if (!val) {
val = failobj;
PyDict_SetItem((PyObject *)mp, key, val);
}
Py_INCREF(val);
return val;
}
PyObject *PyOrange_DictProxy_pop(TPyOrange_DictProxy *mp, PyObject *args)
{
PyObject *key;
PyObject *failobj = PYNULL;
if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &failobj))
return PYNULL;
if (!PyString_Check(key))
PYERROR(PyExc_AttributeError, "object's attribute name must be string", PYNULL);
if (mp->backlink) {
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)
PYERROR(PyExc_KeyError, "cannot remove built-in attributes", PYNULL);
}
PyObject *val = PyDict_GetItem((PyObject *)mp, key);
if (val) {
Py_INCREF(val);
PyDict_DelItem((PyObject *)mp, key);
return val;
}
if (failobj) {
Py_INCREF(failobj);
return failobj;
}
PyErr_SetObject(PyExc_KeyError, key);
return PYNULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -