Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/python/src/object_protocol.cpp @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

  • Property svn:executable set to *
File size: 5.5 KB
Line 
1// Copyright David Abrahams 2002.
2// Distributed under the Boost Software License, Version 1.0. (See
3// accompanying file LICENSE_1_0.txt or copy at
4// http://www.boost.org/LICENSE_1_0.txt)
5
6#include <boost/python/object_protocol.hpp>
7#include <boost/python/errors.hpp>
8#include <boost/python/object.hpp>
9
10namespace boost { namespace python { namespace api {
11
12BOOST_PYTHON_DECL object getattr(object const& target, object const& key)
13{
14    return object(detail::new_reference(PyObject_GetAttr(target.ptr(), key.ptr())));
15}
16   
17BOOST_PYTHON_DECL object getattr(object const& target, object const& key, object const& default_)
18{
19    PyObject* result = PyObject_GetAttr(target.ptr(), key.ptr());
20    if (result == NULL && PyErr_ExceptionMatches(PyExc_AttributeError))
21    {
22        PyErr_Clear();
23        return default_;
24    }
25    return object(detail::new_reference(result));
26}
27       
28BOOST_PYTHON_DECL void setattr(object const& target, object const& key, object const& value)
29{
30    if (PyObject_SetAttr(target.ptr(), key.ptr(), value.ptr()) == -1)
31        throw_error_already_set();
32}
33
34BOOST_PYTHON_DECL void delattr(object const& target, object const& key)
35{
36    if (PyObject_DelAttr(target.ptr(), key.ptr()) == -1)
37        throw_error_already_set();
38}
39
40BOOST_PYTHON_DECL object getattr(object const& target, char const* key)
41{
42    return object(
43        detail::new_reference(
44            PyObject_GetAttrString(target.ptr(), const_cast<char*>(key))
45        ));
46}
47   
48BOOST_PYTHON_DECL object getattr(object const& target, char const* key, object const& default_)
49{
50    PyObject* result = PyObject_GetAttrString(target.ptr(), const_cast<char*>(key));
51    if (result == NULL && PyErr_ExceptionMatches(PyExc_AttributeError))
52    {
53        PyErr_Clear();
54        return default_;
55    }
56    return object(detail::new_reference(result));
57   
58}
59BOOST_PYTHON_DECL void setattr(object const& target, char const* key, object const& value)
60{
61    if (PyObject_SetAttrString(
62            target.ptr(), const_cast<char*>(key), value.ptr()) == -1
63        )
64    {
65        throw_error_already_set();
66    }
67}
68
69BOOST_PYTHON_DECL void delattr(object const& target, char const* key)
70{
71    if (PyObject_DelAttrString(
72            target.ptr(), const_cast<char*>(key)) == -1
73        )
74    {
75        throw_error_already_set();
76    }
77}
78
79BOOST_PYTHON_DECL object getitem(object const& target, object const& key)
80{
81    return object(detail::new_reference(
82                      PyObject_GetItem(target.ptr(), key.ptr())));
83}
84   
85BOOST_PYTHON_DECL void setitem(object const& target, object const& key, object const& value)
86{
87    if (PyObject_SetItem(target.ptr(), key.ptr(), value.ptr()) == -1)
88        throw_error_already_set();
89}
90   
91BOOST_PYTHON_DECL void delitem(object const& target, object const& key)
92{
93    if (PyObject_DelItem(target.ptr(), key.ptr()) == -1)
94        throw_error_already_set();
95}
96
97namespace // slicing code copied directly out of the Python implementation
98{
99  #undef ISINT
100  #define ISINT(x) ((x) == NULL || PyInt_Check(x) || PyLong_Check(x))
101
102  static PyObject *
103  apply_slice(PyObject *u, PyObject *v, PyObject *w) /* return u[v:w] */
104  {
105      PyTypeObject *tp = u->ob_type;
106      PySequenceMethods *sq = tp->tp_as_sequence;
107
108      if (sq && sq->sq_slice && ISINT(v) && ISINT(w)) {
109          int ilow = 0, ihigh = INT_MAX;
110          if (!_PyEval_SliceIndex(v, &ilow))
111              return NULL;
112          if (!_PyEval_SliceIndex(w, &ihigh))
113              return NULL;
114          return PySequence_GetSlice(u, ilow, ihigh);
115      }
116      else {
117          PyObject *slice = PySlice_New(v, w, NULL);
118          if (slice != NULL) {
119              PyObject *res = PyObject_GetItem(u, slice);
120              Py_DECREF(slice);
121              return res;
122          }
123          else
124              return NULL;
125      }
126  }
127
128  static int
129  assign_slice(PyObject *u, PyObject *v, PyObject *w, PyObject *x)
130      /* u[v:w] = x */
131  {
132      PyTypeObject *tp = u->ob_type;
133      PySequenceMethods *sq = tp->tp_as_sequence;
134
135      if (sq && sq->sq_slice && ISINT(v) && ISINT(w)) {
136          int ilow = 0, ihigh = INT_MAX;
137          if (!_PyEval_SliceIndex(v, &ilow))
138              return -1;
139          if (!_PyEval_SliceIndex(w, &ihigh))
140              return -1;
141          if (x == NULL)
142              return PySequence_DelSlice(u, ilow, ihigh);
143          else
144              return PySequence_SetSlice(u, ilow, ihigh, x);
145      }
146      else {
147          PyObject *slice = PySlice_New(v, w, NULL);
148          if (slice != NULL) {
149              int res;
150              if (x != NULL)
151                  res = PyObject_SetItem(u, slice, x);
152              else
153                  res = PyObject_DelItem(u, slice);
154              Py_DECREF(slice);
155              return res;
156          }
157          else
158              return -1;
159      }
160  }
161}
162
163BOOST_PYTHON_DECL object getslice(object const& target, handle<> const& begin, handle<> const& end)
164{
165    return object(
166        detail::new_reference(
167            apply_slice(target.ptr(), begin.get(), end.get())));
168}
169
170BOOST_PYTHON_DECL void setslice(object const& target, handle<> const& begin, handle<> const& end, object const& value)
171{
172    if (assign_slice(
173            target.ptr(), begin.get(), end.get(), value.ptr()) == -1
174        )
175    {
176        throw_error_already_set();
177    }
178}
179
180BOOST_PYTHON_DECL void delslice(object const& target, handle<> const& begin, handle<> const& end)
181{
182    if (assign_slice(
183            target.ptr(), begin.get(), end.get(), 0) == -1
184        )
185    {
186        throw_error_already_set();
187    }
188}
189
190}}} // namespace boost::python::api
Note: See TracBrowser for help on using the repository browser.