]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/python/src/object_protocol.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / python / src / object_protocol.cpp
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
11 namespace boost { namespace python { namespace api {
12
13 BOOST_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
18 BOOST_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
29 BOOST_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
35 BOOST_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
41 BOOST_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
49 BOOST_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 }
60 BOOST_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
70 BOOST_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
80 BOOST_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
86 BOOST_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
92 BOOST_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
98 namespace // 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 #if PY_VERSION_HEX < 0x03000000
107 PyTypeObject *tp = u->ob_type;
108 PySequenceMethods *sq = tp->tp_as_sequence;
109
110 if (sq && sq->sq_slice && ISINT(v) && ISINT(w)) {
111 ssize_t ilow = 0, ihigh = ssize_t_max;
112 if (!_PyEval_SliceIndex(v, &ilow))
113 return NULL;
114 if (!_PyEval_SliceIndex(w, &ihigh))
115 return NULL;
116 return PySequence_GetSlice(u, ilow, ihigh);
117 }
118 else
119 #endif
120 {
121 PyObject *slice = PySlice_New(v, w, NULL);
122 if (slice != NULL) {
123 PyObject *res = PyObject_GetItem(u, slice);
124 Py_DECREF(slice);
125 return res;
126 }
127 else
128 return NULL;
129 }
130 }
131
132 static int
133 assign_slice(PyObject *u, PyObject *v, PyObject *w, PyObject *x)
134 /* u[v:w] = x */
135 {
136 #if PY_VERSION_HEX < 0x03000000
137 PyTypeObject *tp = u->ob_type;
138 PySequenceMethods *sq = tp->tp_as_sequence;
139
140 if (sq && sq->sq_slice && ISINT(v) && ISINT(w)) {
141 ssize_t ilow = 0, ihigh = ssize_t_max;
142 if (!_PyEval_SliceIndex(v, &ilow))
143 return -1;
144 if (!_PyEval_SliceIndex(w, &ihigh))
145 return -1;
146 if (x == NULL)
147 return PySequence_DelSlice(u, ilow, ihigh);
148 else
149 return PySequence_SetSlice(u, ilow, ihigh, x);
150 }
151 else
152 #endif
153 {
154 PyObject *slice = PySlice_New(v, w, NULL);
155 if (slice != NULL) {
156 int res;
157 if (x != NULL)
158 res = PyObject_SetItem(u, slice, x);
159 else
160 res = PyObject_DelItem(u, slice);
161 Py_DECREF(slice);
162 return res;
163 }
164 else
165 return -1;
166 }
167 }
168 }
169
170 BOOST_PYTHON_DECL object getslice(object const& target, handle<> const& begin, handle<> const& end)
171 {
172 return object(
173 detail::new_reference(
174 apply_slice(target.ptr(), begin.get(), end.get())));
175 }
176
177 BOOST_PYTHON_DECL void setslice(object const& target, handle<> const& begin, handle<> const& end, object const& value)
178 {
179 if (assign_slice(
180 target.ptr(), begin.get(), end.get(), value.ptr()) == -1
181 )
182 {
183 throw_error_already_set();
184 }
185 }
186
187 BOOST_PYTHON_DECL void delslice(object const& target, handle<> const& begin, handle<> const& end)
188 {
189 if (assign_slice(
190 target.ptr(), begin.get(), end.get(), 0) == -1
191 )
192 {
193 throw_error_already_set();
194 }
195 }
196
197 }}} // namespace boost::python::api