1 /****************************************************************************
2 **
3 ** Copyright (C) 2019 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt for Python.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #ifndef BASEWRAPPER_H
41 #define BASEWRAPPER_H
42 
43 #include "sbkpython.h"
44 #include "shibokenmacros.h"
45 
46 #include <vector>
47 #include <string>
48 
49 extern "C"
50 {
51 
52 struct SbkConverter;
53 struct SbkObjectPrivate;
54 
55 /// Base Python object for all the wrapped C++ classes.
56 struct LIBSHIBOKEN_API SbkObject
57 {
58     PyObject_HEAD
59     /// Instance dictionary.
60     PyObject *ob_dict;
61     /// List of weak references
62     PyObject *weakreflist;
63     SbkObjectPrivate *d;
64 };
65 
66 
67 /// PYSIDE-939: A general replacement for object_dealloc.
68 LIBSHIBOKEN_API void Sbk_object_dealloc(PyObject *self);
69 
70 /// Dealloc the python object \p pyObj and the C++ object represented by it.
71 LIBSHIBOKEN_API void SbkDeallocWrapper(PyObject *pyObj);
72 LIBSHIBOKEN_API void SbkDeallocQAppWrapper(PyObject *pyObj);
73 LIBSHIBOKEN_API void SbkDeallocWrapperWithPrivateDtor(PyObject *self);
74 
75 struct SbkObjectType;
76 
77 /// Function signature for the multiple inheritance information initializers that should be provided by classes with multiple inheritance.
78 typedef int *(*MultipleInheritanceInitFunction)(const void *);
79 
80 /**
81  *   Special cast function is used to correctly cast an object when it's
82  *   part of a multiple inheritance hierarchy.
83  *   The implementation of this function is auto generated by the generator and you don't need to care about it.
84  */
85 typedef void *(*SpecialCastFunction)(void *, SbkObjectType *);
86 typedef SbkObjectType *(*TypeDiscoveryFunc)(void *, SbkObjectType *);
87 typedef void *(*TypeDiscoveryFuncV2)(void *, SbkObjectType *);
88 
89 // Used in userdata dealloc function
90 typedef void (*DeleteUserDataFunc)(void *);
91 
92 typedef void (*ObjectDestructor)(void *);
93 
94 typedef void (*SubTypeInitHook)(SbkObjectType *, PyObject *, PyObject *);
95 
96 // PYSIDE-1019: Set the function to select the current feature.
97 typedef PyObject *(*SelectableFeatureHook)(PyTypeObject *);
98 LIBSHIBOKEN_API void initSelectableFeature(SelectableFeatureHook func);
99 
100 // PYSIDE-1019: Get access to PySide reserved bits.
101 LIBSHIBOKEN_API int SbkObjectType_GetReserved(PyTypeObject *type);
102 LIBSHIBOKEN_API void SbkObjectType_SetReserved(PyTypeObject *type, int value);
103 
104 // PYSIDE-1019: Get access to PySide property strings.
105 LIBSHIBOKEN_API const char **SbkObjectType_GetPropertyStrings(PyTypeObject *type);
106 LIBSHIBOKEN_API void SbkObjectType_SetPropertyStrings(PyTypeObject *type, const char **strings);
107 
108 
109 extern LIBSHIBOKEN_API PyTypeObject *SbkObjectType_TypeF(void);
110 extern LIBSHIBOKEN_API SbkObjectType *SbkObject_TypeF(void);
111 
112 
113 struct SbkObjectTypePrivate;
114 /// PyTypeObject extended with C++ multiple inheritance information.
115 struct LIBSHIBOKEN_API SbkObjectType
116 {
117     PyTypeObject type;
118 };
119 
120 LIBSHIBOKEN_API PyObject *SbkObjectTpNew(PyTypeObject *subtype, PyObject *, PyObject *);
121 // the special case of a switchable singleton
122 LIBSHIBOKEN_API PyObject *SbkQAppTpNew(PyTypeObject *subtype, PyObject *args, PyObject *kwds);
123 
124 /**
125  *  PYSIDE-832: Use object_dealloc instead of nullptr.
126  *
127  *  When moving to heaptypes, we were struck by a special default behavior of
128  *  PyType_FromSpecWithBases that inserts subtype_dealloc when tp_dealloc is
129  *  nullptr. But the default before conversion to heaptypes was to assign
130  *  object_dealloc. This seems to be a bug in the Limited API.
131  */
132 /// PYSIDE-939: Replaced by Sbk_object_dealloc.
133 LIBSHIBOKEN_API PyObject *SbkDummyNew(PyTypeObject *type, PyObject *, PyObject *);
134 
135 /// PYSIDE-1286: Generate correct __module__ and __qualname__
136 LIBSHIBOKEN_API PyObject *SbkType_FromSpec(PyType_Spec *);
137 LIBSHIBOKEN_API PyObject *SbkType_FromSpecWithBases(PyType_Spec *, PyObject *);
138 
139 /// PYSIDE-74: Fallback used in all types now.
140 LIBSHIBOKEN_API PyObject *FallbackRichCompare(PyObject *self, PyObject *other, int op);
141 
142 } // extern "C"
143 
144 namespace Shiboken
145 {
146 
147 /**
148 *   Init shiboken library.
149 */
150 LIBSHIBOKEN_API void init();
151 
152 
153 /// Delete the class T allocated on \p cptr.
154 template<typename T>
callCppDestructor(void * cptr)155 void callCppDestructor(void *cptr)
156 {
157     delete reinterpret_cast<T *>(cptr);
158 }
159 
160 // setErrorAboutWrongArguments now gets overload info from the signature module.
161 LIBSHIBOKEN_API void setErrorAboutWrongArguments(PyObject *args, const char *funcName);
162 
163 namespace ObjectType {
164 
165 /**
166 *   Returns true if the object is an instance of a type created by the Shiboken generator.
167 */
168 LIBSHIBOKEN_API bool checkType(PyTypeObject *pyObj);
169 
170 /**
171 *   Returns true if this object is an instance of an user defined type derived from an Shiboken type.
172 */
173 LIBSHIBOKEN_API bool isUserType(PyTypeObject *pyObj);
174 
175 /**
176 *   Returns true if the constructor of \p ctorType can be called for a instance of type \p myType.
177 *   \note This function set a python error when returning false.
178 */
179 LIBSHIBOKEN_API bool canCallConstructor(PyTypeObject *myType, PyTypeObject *ctorType);
180 
181 /**
182  *  Tells if the \p type represents an object of a class with multiple inheritance in C++.
183  *  When this occurs, the C++ pointer held by the Python wrapper will need to be cast when
184  *  passed as a parameter that expects a type of its ancestry.
185  *  \returns    true if a call to ObjectType::cast() is needed to obtain the correct
186  *              C++ pointer for Python objects of type \p type.
187  */
188 LIBSHIBOKEN_API bool hasCast(SbkObjectType *type);
189 /**
190  *  Cast the C++ pointer held by a Python object \p obj of type \p sourceType,
191  *  to a C++ pointer of a C++ class indicated by type \p targetType.
192  *  \returns    The cast C++ pointer.
193  */
194 LIBSHIBOKEN_API void *cast(SbkObjectType *sourceType, SbkObject *obj, PyTypeObject *targetType);
195 /// Set the C++ cast function for \p type.
196 LIBSHIBOKEN_API void setCastFunction(SbkObjectType *type, SpecialCastFunction func);
197 
198 LIBSHIBOKEN_API void setOriginalName(SbkObjectType *self, const char *name);
199 LIBSHIBOKEN_API const char *getOriginalName(SbkObjectType *self);
200 
201 LIBSHIBOKEN_API void setTypeDiscoveryFunctionV2(SbkObjectType *self, TypeDiscoveryFuncV2 func);
202 LIBSHIBOKEN_API void copyMultipleInheritance(SbkObjectType *self, SbkObjectType *other);
203 LIBSHIBOKEN_API void setMultipleInheritanceFunction(SbkObjectType *self, MultipleInheritanceInitFunction func);
204 LIBSHIBOKEN_API MultipleInheritanceInitFunction getMultipleInheritanceFunction(SbkObjectType *self);
205 
206 LIBSHIBOKEN_API void setDestructorFunction(SbkObjectType *self, ObjectDestructor func);
207 
208 LIBSHIBOKEN_API void initPrivateData(SbkObjectType *self);
209 
210 enum WrapperFlags
211 {
212     InnerClass = 0x1,
213     DeleteInMainThread = 0x2
214 };
215 
216 /**
217  *  Initializes a Shiboken wrapper type and adds it to the module,
218  *  or to the enclosing class if the type is an inner class.
219  *  This function also calls initPrivateData and setDestructorFunction.
220  *  \param enclosingObject  The module or enclosing class to where the new \p type will be added.
221  *  \param typeName         Name by which the type will be known in Python.
222  *  \param originalName     Original C++ name of the type.
223  *  \param type             The new type to be initialized and added to the module.
224  *  \param cppObjDtor       Memory deallocation function for the C++ object held by \p type.
225  *                          Should not be used if the underlying C++ class has a private destructor.
226  *  \param baseType         Base type from whom the new \p type inherits.
227  *  \param baseTypes        Other base types from whom the new \p type inherits.
228  *  \param isInnerClass     Tells if the new \p type is an inner class (the default is that it isn't).
229  *                          If false then the \p enclosingObject is a module, otherwise it is another
230  *                          wrapper type.
231  *  \returns                true if the initialization went fine, false otherwise.
232  */
233 LIBSHIBOKEN_API SbkObjectType *introduceWrapperType(PyObject *enclosingObject,
234                                                     const char *typeName,
235                                                     const char *originalName,
236                                                     PyType_Spec *typeSpec,
237                                                     ObjectDestructor cppObjDtor,
238                                                     SbkObjectType *baseType,
239                                                     PyObject *baseTypes,
240                                                     unsigned wrapperFlags = 0);
241 
242 /**
243  *  Set the subtype init hook for a type.
244  *
245  *  This hook will be invoked every time the user creates a sub-type inherited from a Shiboken based type.
246  *  The hook gets 3 params, they are: The new type being created, args and kwds. The last two are the very
247  *  same got from tp_new.
248  */
249 LIBSHIBOKEN_API void setSubTypeInitHook(SbkObjectType *self, SubTypeInitHook func);
250 
251 /**
252  *  Get the user data previously set by Shiboken::Object::setTypeUserData
253  */
254 LIBSHIBOKEN_API void *getTypeUserData(SbkObjectType *self);
255 LIBSHIBOKEN_API void setTypeUserData(SbkObjectType *self, void *userData, DeleteUserDataFunc d_func);
256 
257 /**
258  * Return an instance of SbkObjectType for a C++ type name as determined by
259  * typeinfo().name().
260  * \param typeName Type name
261  * \since 5.12
262  */
263 LIBSHIBOKEN_API SbkObjectType *typeForTypeName(const char *typeName);
264 
265 /**
266  *  Returns whether SbkObjectType has a special cast function (multiple inheritance)
267  * \param sbkType Sbk type
268  * \since 5.12
269  */
270 LIBSHIBOKEN_API bool hasSpecialCastFunction(SbkObjectType *sbkType);
271 }
272 
273 namespace Object {
274 
275 /**
276  *  Returns a string with information about the internal state of the instance object, useful for debug purposes.
277  */
278 LIBSHIBOKEN_API std::string info(SbkObject *self);
279 
280 /**
281 *   Returns true if the object is an instance of a type created by the Shiboken generator.
282 */
283 LIBSHIBOKEN_API bool checkType(PyObject *pyObj);
284 
285 /**
286  *  Returns true if this object type is an instance of an user defined type derived from an Shiboken type.
287  *  \see Shiboken::ObjectType::isUserType
288  */
289 LIBSHIBOKEN_API bool isUserType(PyObject *pyObj);
290 
291 /**
292  *  Generic function used to make ObjectType hashable, the C++ pointer is used as hash value.
293  */
294 LIBSHIBOKEN_API Py_hash_t hash(PyObject *pyObj);
295 
296 /**
297  * Find a child of given wrapper having same address having the specified type.
298  */
299 LIBSHIBOKEN_API SbkObject *findColocatedChild(SbkObject *wrapper,
300                                               const SbkObjectType *instanceType);
301 
302 /**
303  *  Bind a C++ object to Python.
304  * \param instanceType equivalent Python type for the C++ object.
305  * \param hasOwnership if true, Python will try to delete the underlying C++ object when there's no more refs.
306  * \param isExactType if false, Shiboken will use some heuristics to detect the correct Python type of this C++
307  *                    object, in any case you must provide \p instanceType, it'll be used as search starting point
308  *                    and as fallback.
309  * \param typeName    If non-null, this will be used as helper to find the correct Python type for this object.
310  */
311 LIBSHIBOKEN_API PyObject *newObject(SbkObjectType *instanceType,
312                                     void *cptr,
313                                     bool hasOwnership = true,
314                                     bool isExactType = false,
315                                     const char *typeName = nullptr);
316 
317 /**
318  *  Changes the valid flag of a PyObject, invalid objects will raise an exception when someone tries to access it.
319  */
320 LIBSHIBOKEN_API void setValidCpp(SbkObject *pyObj, bool value);
321 /**
322  *  Tells shiboken the Python object \p pyObj has a C++ wrapper used to intercept virtual method calls.
323  */
324 LIBSHIBOKEN_API void setHasCppWrapper(SbkObject *pyObj, bool value);
325 /**
326  *  Return true if the Python object \p pyObj has a C++ wrapper used to intercept virtual method calls.
327  */
328 LIBSHIBOKEN_API bool hasCppWrapper(SbkObject *pyObj);
329 
330 /**
331  *  Return true if the Python object was created by Python, false otherwise.
332  *  \note This function was added to libshiboken only to be used by shiboken.wasCreatedByPython()
333  */
334 LIBSHIBOKEN_API bool wasCreatedByPython(SbkObject *pyObj);
335 
336 /**
337  *  Call the C++ object destructor and invalidates the Python object.
338  *  \note This function was added to libshiboken only to be used by shiboken.delete()
339  */
340 LIBSHIBOKEN_API void callCppDestructors(SbkObject *pyObj);
341 
342 /**
343  *  Return true if the Python is responsible for deleting the underlying C++ object.
344  */
345 LIBSHIBOKEN_API bool hasOwnership(SbkObject *pyObj);
346 
347 /**
348  *  Sets python as responsible to delete the underlying C++ object.
349  *  \note You this overload only when the PyObject can be a sequence and you want to
350  *  call this function for every item in the sequence.
351  *  \see getOwnership(SbkObject *)
352  */
353 LIBSHIBOKEN_API void getOwnership(PyObject *pyObj);
354 
355 /**
356  *  Sets python as responsible to delete the underlying C++ object.
357  */
358 LIBSHIBOKEN_API void getOwnership(SbkObject *pyObj);
359 
360 /**
361  *  Release the ownership, so Python will not delete the underlying C++ object.
362  *  \note You this overload only when the PyObject can be a sequence and you want to
363  *  call this function for every item in the sequence.
364  *  \see releaseOwnership(SbkObject *)
365  */
366 LIBSHIBOKEN_API void releaseOwnership(PyObject *pyObj);
367 /**
368  *  Release the ownership, so Python will not delete the underlying C++ object.
369  */
370 LIBSHIBOKEN_API void releaseOwnership(SbkObject *pyObj);
371 
372 /**
373  *   Get the C++ pointer of type \p desiredType from a Python object.
374  */
375 LIBSHIBOKEN_API void *cppPointer(SbkObject *pyObj, PyTypeObject *desiredType);
376 
377 /**
378  *   Return a list with all C++ pointers held from a Python object.
379  *   \note This function was added to libshiboken only to be used by shiboken.getCppPointer()
380  */
381 LIBSHIBOKEN_API std::vector<void *>cppPointers(SbkObject *pyObj);
382 
383 /**
384  *   Set the C++ pointer of type \p desiredType of a Python object.
385  */
386 LIBSHIBOKEN_API bool setCppPointer(SbkObject *sbkObj, PyTypeObject *desiredType, void *cptr);
387 
388 /**
389  * Returns false and sets a Python RuntimeError if the Python wrapper is not marked as valid.
390  */
391 LIBSHIBOKEN_API bool isValid(PyObject *pyObj);
392 
393 /**
394  * Returns false if the Python wrapper is not marked as valid.
395  * \param pyObj the object.
396  * \param throwPyError sets a Python RuntimeError when the object isn't valid.
397  */
398 LIBSHIBOKEN_API bool isValid(SbkObject *pyObj, bool throwPyError = true);
399 
400 /**
401  * Returns false if the Python wrapper is not marked as valid.
402  * \param pyObj the object.
403  * \param throwPyError sets a Python RuntimeError when the object isn't valid.
404  */
405 LIBSHIBOKEN_API bool isValid(PyObject *pyObj, bool throwPyError);
406 
407 /**
408 *   Set the parent of \p child to \p parent.
409 *   When an object dies, all their children, grandchildren, etc, are tagged as invalid.
410 *   \param parent the parent object, if null, the child will have no parents.
411 *   \param child the child.
412 */
413 LIBSHIBOKEN_API void setParent(PyObject *parent, PyObject *child);
414 
415 /**
416 *   Remove this child from their parent, if any.
417 *   \param child the child.
418 */
419 LIBSHIBOKEN_API void removeParent(SbkObject *child, bool giveOwnershipBack = true, bool keepReferenc = false);
420 
421 /**
422  * Mark the object as invalid
423  */
424 LIBSHIBOKEN_API void invalidate(SbkObject *self);
425 
426 /**
427  * Help function can be used to invalidate a sequence of object
428  **/
429 LIBSHIBOKEN_API void invalidate(PyObject *pyobj);
430 
431 /**
432  * Make the object valid again
433  */
434 LIBSHIBOKEN_API void makeValid(SbkObject *self);
435 
436 /**
437  * Destroy any data in Shiboken structure and c++ pointer if the pyboject has the ownership
438  */
439 LIBSHIBOKEN_API void destroy(SbkObject *self, void *cppData);
440 
441 /**
442  *  Set user data on type of \p wrapper.
443  *  \param wrapper instance object, the user data will be set on his type
444  *  \param userData the user data
445  *  \param d_func a function used to delete the user data
446  */
447 LIBSHIBOKEN_API void setTypeUserData(SbkObject *wrapper, void *userData, DeleteUserDataFunc d_func);
448 /**
449  *  Get the user data previously set by Shiboken::Object::setTypeUserData
450  */
451 LIBSHIBOKEN_API void *getTypeUserData(SbkObject *wrapper);
452 
453 /**
454  *   Increments the reference count of the referred Python object.
455  *   A previous Python object in the same position identified by the 'key' parameter
456  *   will have its reference counter decremented automatically when replaced.
457  *   All the kept references should be decremented when the Python wrapper indicated by
458  *   'self' dies.
459  *   No checking is done for any of the passed arguments, since it is meant to be used
460  *   by generated code it is supposed that the generator is correct.
461  *   \param self            the wrapper instance that keeps references to other objects.
462  *   \param key             a key that identifies the C++ method signature and argument where the referred Object came from.
463  *   \param referredObject  the object whose reference is used by the self object.
464  */
465 LIBSHIBOKEN_API void keepReference(SbkObject *self, const char *key, PyObject *referredObject, bool append = false);
466 
467 /**
468  *   Removes any reference previously added by keepReference function
469  *   \param self            the wrapper instance that keeps references to other objects.
470  *   \param key             a key that identifies the C++ method signature and argument from where the referred Object came.
471  *   \param referredObject  the object whose reference is used by the self object.
472  */
473 LIBSHIBOKEN_API void removeReference(SbkObject *self, const char *key, PyObject *referredObject);
474 
475 } // namespace Object
476 
477 } // namespace Shiboken
478 
479 #endif // BASEWRAPPER_H
480