Library of Assembled Shared Sources
pyobject_plus.inl
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2024 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43namespace lass
44{
45namespace python
46{
47
48// --- impl ----------------------------------------------------------------------------------------
49
50namespace impl
51{
52
53/** @internal
54 */
55template <typename T, PyCFunction dispatcher> struct FunctionTypeDispatcher
56{
57 static PyObject* fun(PyObject* self, PyObject* args) { return dispatcher(self,args); }
58 typedef PyCFunction OverloadType;
59};
60/** @internal
61 */
62template <PyCFunction DispatcherAddress> struct FunctionTypeDispatcher<lass::python::impl::UnarySlot ,DispatcherAddress>
63{
64 static PyObject* fun(PyObject* iSelf)
65 {
66 TPyObjPtr args(PyTuple_New(0));
67 return DispatcherAddress(iSelf, args.get());
68 }
69};
70/** @internal
71 */
72template <PyCFunction DispatcherAddress> struct FunctionTypeDispatcher<lass::python::impl::BinarySlot ,DispatcherAddress>
73{
74 static PyObject* fun(PyObject* iSelf, PyObject* iOther)
75 {
76 TPyObjPtr args(Py_BuildValue("(O)", iOther));
77 return DispatcherAddress(iSelf, args.get());
78 }
79};
80/** @internal
81 */
82template <PyCFunction DispatcherAddress> struct FunctionTypeDispatcher<lass::python::impl::TernarySlot ,DispatcherAddress>
83{
84 static PyObject* fun(PyObject* iSelf, PyObject* iOther, PyObject* iThird)
85 {
86 TPyObjPtr args(Py_BuildValue("(O,O)", iOther, iThird));
87 PyObject* result = DispatcherAddress(iSelf, args.get());
88 if (!result && PyErr_ExceptionMatches(PyExc_TypeError) && iThird == Py_None)
89 {
90 // try as a binary function
91 PyErr_Clear();
92 TPyObjPtr args2(Py_BuildValue("(O)", iOther));
93 return DispatcherAddress(iSelf, args2.get());
94 }
95 return result;
96 }
97};
98/** @internal
99*/
100template <PyCFunction DispatcherAddress> struct FunctionTypeDispatcher<lass::python::impl::SsizeArgSlot ,DispatcherAddress>
101{
102 static PyObject* fun(PyObject* iSelf, Py_ssize_t iSize)
103 {
104 TPyObjPtr args(Py_BuildValue("(n)", iSize));
105 return DispatcherAddress(iSelf,args.get());
106 }
107};
108/** @internal
109*/
110template <PyCFunction DispatcherAddress> struct FunctionTypeDispatcher<lass::python::impl::SsizeSsizeArgSlot ,DispatcherAddress>
111{
112 static PyObject* fun(PyObject* iSelf, Py_ssize_t iSize, Py_ssize_t iSize2)
113 {
114 TPyObjPtr args(Py_BuildValue("(n,n)", iSize, iSize2));
115 return DispatcherAddress(iSelf,args.get());
116 }
117};
118/** @internal
119 */
120template <PyCFunction DispatcherAddress> struct FunctionTypeDispatcher<lass::python::impl::LenSlot ,DispatcherAddress>
121{
122 static Py_ssize_t fun(PyObject* iSelf)
123 {
124 TPyObjPtr args(Py_BuildValue("()"));
125 TPyObjPtr temp(DispatcherAddress(iSelf,args.get()));
126 if (!temp)
127 return -1;
128 Py_ssize_t result;
129 if (pyGetSimpleObject(temp.get(), result) != 0)
130 return -1;
131 return result;
132 }
133};
134/** @internal
135 */
136template <PyCFunction DispatcherAddress> struct FunctionTypeDispatcher<lass::python::impl::SsizeObjArgSlot ,DispatcherAddress>
137{
138 static int fun(PyObject * iSelf, Py_ssize_t iSize, PyObject * iOther)
139 {
140 TPyObjPtr args(Py_BuildValue("(n,O)",iSize,iOther));
141 TPyObjPtr temp(DispatcherAddress(iSelf,args.get()));
142 return temp ? 0 : -1;
143 }
144};
145/** @internal
146 */
147template <PyCFunction DispatcherAddress> struct FunctionTypeDispatcher<lass::python::impl::SsizeSsizeObjArgSlot ,DispatcherAddress>
148{
149 static int fun(PyObject * iSelf, Py_ssize_t iSize, Py_ssize_t iSize2, PyObject * iOther)
150 {
151 TPyObjPtr args(Py_BuildValue("(n,n,O)",iSize,iSize2,iOther));
152 TPyObjPtr temp(DispatcherAddress(iSelf,args.get()));
153 return temp ? 0 : -1;
154 }
155};
156/** @internal
157 */
158template <PyCFunction DispatcherAddress> struct FunctionTypeDispatcher<lass::python::impl::ObjObjSlot ,DispatcherAddress>
159{
160 static int fun(PyObject * iSelf, PyObject * iOther)
161 {
162 TPyObjPtr args(Py_BuildValue("(O)",iOther));
163 TPyObjPtr temp(DispatcherAddress(iSelf,args.get()));
164 if (!temp)
165 return -1;
166 int result;
167 if (pyGetSimpleObject(temp.get(), result) != 0)
168 return -1;
169 return result;
170 }
171};
172
173/** @internal
174 */
175template <PyCFunction DispatcherAddress> struct FunctionTypeDispatcher<lass::python::impl::ObjObjArgSlot, DispatcherAddress>
176{
177 static int fun(PyObject* self, PyObject* key, PyObject* value)
178 {
179 // value can be NULL in case of __delitem__: del dct[x] is in fact
180 // implemented by calling mp_ass_subscript with NULL as value.
181 // However, we can't translate NULL back into a valid PyObject*, so
182 // we'll just omit the second argument.
183
184 TPyObjPtr args(value
185 ? Py_BuildValue("(O,O)", key, value)
186 : Py_BuildValue("(O)", key));
187 TPyObjPtr temp(DispatcherAddress(self, args.get()));
188 if (temp)
189 {
190 LASS_ASSERT(!PyErr_Occurred());
191 return 0;
192 }
193 if (!PyErr_Occurred())
194 {
195 PyErr_SetString(PyExc_AssertionError, "ObjObjArgSlot: expected return value or exception.");
196 }
197 return -1;
198 }
199};
200/** @internal
201*/
202template <PyCFunction DispatcherAddress> struct FunctionTypeDispatcher<lass::python::impl::IterSlot ,DispatcherAddress>
203{
204 static PyObject* fun(PyObject* iSelf)
205 {
206 TPyObjPtr args(PyTuple_New(0));
207 return DispatcherAddress(iSelf, args.get());
208 }
209};
210/** @internal
211*/
212template <PyCFunction DispatcherAddress> struct FunctionTypeDispatcher<lass::python::impl::IterNextSlot ,DispatcherAddress>
213{
214 static PyObject* fun(PyObject* iSelf)
215 {
216 TPyObjPtr args(PyTuple_New(0));
217 return DispatcherAddress(iSelf, args.get());
218 }
219};
220/** @internal
221 */
222template <PyCFunction DispatcherAddress> struct FunctionTypeDispatcher<lass::python::impl::ArgKwSlot ,DispatcherAddress>
223{
224 static PyObject* fun(PyObject* iSelf, PyObject* iArgs, PyObject* iKw)
225 {
226 if (iKw)
227 {
228 if (!PyDict_CheckExact(iKw))
229 {
230 PyErr_BadInternalCall();
231 return 0;
232 }
233 if (PyDict_Size(iKw) != 0)
234 {
235 PyErr_SetString(PyExc_TypeError, "function takes no keyword arguments");
236 return 0;
237 }
238 }
239 return DispatcherAddress(iSelf, iArgs);
240 }
241};
242/** @internal
243 */
244template <PyCFunction DispatcherAddress> struct FunctionTypeDispatcher<lass::python::impl::InquirySlot ,DispatcherAddress>
245{
246 static int fun(PyObject* iSelf)
247 {
248 TPyObjPtr args(Py_BuildValue("()"));
249 TPyObjPtr temp(DispatcherAddress(iSelf,args.get()));
250 if (!temp)
251 return -1;
252 int result;
253 if (pyGetSimpleObject(temp.get(), result) != 0)
254 return -1;
255 return result;
256 }
257};
258
259/////////////////////////////////////////////
260
261}
262}
263}
264
265// EOF
PyObjectPtr< PyObject >::Type TPyObjPtr
PyObjectPtr to a PyObject.
Comprehensive C++ to Python binding library.
Library for Assembled Shared Sources.
Definition config.h:53