Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/python/src/object_protocol.cpp @ 29

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

updated boost from 1_33_1 to 1_34_1

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