⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dictproxy.cpp

📁 orange源码 数据挖掘技术
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
    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 + -