diff options
author | Hugo Parente Lima <hugo.pl@gmail.com> | 2011-08-04 16:10:34 -0300 |
---|---|---|
committer | Hugo Parente Lima <hugo.pl@gmail.com> | 2012-03-08 16:17:13 -0300 |
commit | 784a4bbb707d132b26bcb177521745575dc0823f (patch) | |
tree | f637ef4134445b1cfdd0c33878b7a1ce46f02145 | |
parent | 8b1ddcd3ef711bab70bb7cdebc26558a26f42df9 (diff) |
Implements PSEP-0106 and fixes bug 902 - "Expose Shiboken functionality through a Python module".
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | generator/cppgenerator.cpp | 11 | ||||
-rw-r--r-- | generator/headergenerator.cpp | 32 | ||||
-rw-r--r-- | libshiboken/basewrapper.cpp | 96 | ||||
-rw-r--r-- | libshiboken/basewrapper.h | 27 | ||||
-rw-r--r-- | libshiboken/basewrapper_p.h | 13 | ||||
-rw-r--r-- | shibokenmodule/CMakeLists.txt | 32 | ||||
-rw-r--r-- | shibokenmodule/nothing.h | 0 | ||||
-rw-r--r-- | shibokenmodule/shibokenmodule.txt.in | 16 | ||||
-rw-r--r-- | shibokenmodule/typesystem_shiboken.xml | 73 | ||||
-rw-r--r-- | tests/CMakeLists.txt | 12 | ||||
-rw-r--r-- | tests/libsample/objecttype.cpp | 6 | ||||
-rw-r--r-- | tests/libsample/objecttype.h | 1 | ||||
-rw-r--r-- | tests/samplebinding/typesystem_sample.xml | 6 | ||||
-rw-r--r-- | tests/shibokenmodule/module_test.py | 70 |
15 files changed, 367 insertions, 29 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 911cd68d6..8c8a096c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,6 +88,7 @@ add_subdirectory(doc) # deps found, compile the generator. if (QT4_FOUND AND ApiExtractor_FOUND AND GeneratorRunner_FOUND AND PYTHONLIBS_FOUND AND PYTHONINTERP_FOUND) add_subdirectory(generator) + add_subdirectory(shibokenmodule) if (BUILD_TESTS) enable_testing() diff --git a/generator/cppgenerator.cpp b/generator/cppgenerator.cpp index a894c79e7..a746dbb92 100644 --- a/generator/cppgenerator.cpp +++ b/generator/cppgenerator.cpp @@ -3946,9 +3946,11 @@ void CppGenerator::finishGeneration() s << INDENT << "}" << endl << endl; } - s << INDENT << "// Create an array of wrapper types for the current module." << endl; - s << INDENT << "static PyTypeObject* cppApi[" << "SBK_" << moduleName() << "_IDX_COUNT" << "];" << endl; - s << INDENT << cppApiVariableName() << " = cppApi;" << endl << endl; + if (getMaxTypeIndex()) { + s << INDENT << "// Create an array of wrapper types for the current module." << endl; + s << INDENT << "static PyTypeObject* cppApi[" << "SBK_" << moduleName() << "_IDX_COUNT" << "];" << endl; + s << INDENT << cppApiVariableName() << " = cppApi;" << endl << endl; + } s << INDENT << "PyObject* module = Shiboken::Module::create(\"" << moduleName() << "\", "; s << moduleName() << "_methods);" << endl << endl; @@ -3995,7 +3997,8 @@ void CppGenerator::finishGeneration() foreach (QByteArray type, typeResolvers) s << INDENT << typeResolverString(type) << ';' << endl; - s << endl << INDENT << "Shiboken::Module::registerTypes(module, " << cppApiVariableName() << ");" << endl; + if (getMaxTypeIndex()) + s << endl << INDENT << "Shiboken::Module::registerTypes(module, " << cppApiVariableName() << ");" << endl; s << endl << INDENT << "if (PyErr_Occurred()) {" << endl; { diff --git a/generator/headergenerator.cpp b/generator/headergenerator.cpp index 7cbf6b2ea..1e2a5b8d7 100644 --- a/generator/headergenerator.cpp +++ b/generator/headergenerator.cpp @@ -345,22 +345,24 @@ void HeaderGenerator::finishGeneration() QTextStream protEnumsSurrogates(&protectedEnumSurrogates); Indentation indent(INDENT); - - macrosStream << "// Type indices" << endl; AbstractMetaEnumList globalEnums = this->globalEnums(); - foreach (const AbstractMetaClass* metaClass, classes()) { - writeTypeIndexDefine(macrosStream, metaClass); - lookForEnumsInClassesNotToBeGenerated(globalEnums, metaClass); - } - foreach (const AbstractMetaEnum* metaEnum, globalEnums) - writeTypeIndexDefineLine(macrosStream, metaEnum->typeEntry()); - macrosStream << "#define "; - macrosStream.setFieldWidth(60); - macrosStream << "SBK_"+moduleName()+"_IDX_COUNT"; - macrosStream.setFieldWidth(0); - macrosStream << ' ' << getMaxTypeIndex() << endl << endl; - macrosStream << "// This variable stores all python types exported by this module" << endl; - macrosStream << "extern PyTypeObject** " << cppApiVariableName() << ';' << endl << endl; + + if (getMaxTypeIndex()) { + macrosStream << "// Type indices" << endl; + foreach (const AbstractMetaClass* metaClass, classes()) { + writeTypeIndexDefine(macrosStream, metaClass); + lookForEnumsInClassesNotToBeGenerated(globalEnums, metaClass); + } + foreach (const AbstractMetaEnum* metaEnum, globalEnums) + writeTypeIndexDefineLine(macrosStream, metaEnum->typeEntry()); + macrosStream << "#define "; + macrosStream.setFieldWidth(60); + macrosStream << "SBK_"+moduleName()+"_IDX_COUNT"; + macrosStream.setFieldWidth(0); + macrosStream << ' ' << getMaxTypeIndex() << endl << endl; + macrosStream << "// This variable stores all python types exported by this module" << endl; + macrosStream << "extern PyTypeObject** " << cppApiVariableName() << ';' << endl << endl; + } macrosStream << "// Macros for type check" << endl; foreach (const AbstractMetaEnum* cppEnum, globalEnums) { diff --git a/libshiboken/basewrapper.cpp b/libshiboken/basewrapper.cpp index b5772e953..d41bfd15b 100644 --- a/libshiboken/basewrapper.cpp +++ b/libshiboken/basewrapper.cpp @@ -29,6 +29,8 @@ #include <string> #include <cstring> #include <cstddef> +#include <set> +#include <sstream> #include <algorithm> #include "threadstatesaver.h" @@ -180,7 +182,7 @@ void SbkDeallocWrapper(PyObject* pyObj) if (sbkObj->d->hasOwnership && sbkObj->d->validCppObject) { SbkObjectType* sbkType = reinterpret_cast<SbkObjectType*>(pyObj->ob_type); if (sbkType->d->is_multicpp) { - Shiboken::DtorCallerVisitor visitor(sbkObj); + Shiboken::DeallocVisitor visitor(sbkObj); Shiboken::walkThroughClassHierarchy(pyObj->ob_type, &visitor); } else { void* cptr = sbkObj->d->cptr[0]; @@ -387,8 +389,6 @@ void DtorCallerVisitor::visit(SbkObjectType* node) void DtorCallerVisitor::done() { - Shiboken::Object::deallocData(m_pyObj, true); - std::list<std::pair<void*, SbkObjectType*> >::const_iterator it = m_ptrs.begin(); for (; it != m_ptrs.end(); ++it) { Shiboken::ThreadStateSaver threadSaver; @@ -397,6 +397,12 @@ void DtorCallerVisitor::done() } } +void DeallocVisitor::done() +{ + Shiboken::Object::deallocData(m_pyObj, true); + DtorCallerVisitor::done(); +} + namespace Module { void init(); } void init() @@ -739,6 +745,27 @@ bool hasCppWrapper(SbkObject* pyObj) return pyObj->d->containsCppWrapper; } +bool wasCreatedByPython(SbkObject* pyObj) +{ + return pyObj->d->cppObjectCreated; +} + +void callCppDestructors(SbkObject* pyObj) +{ + SbkObjectType* sbkType = reinterpret_cast<SbkObjectType*>(pyObj->ob_type); + if (sbkType->d->is_multicpp) { + Shiboken::DtorCallerVisitor visitor(pyObj); + Shiboken::walkThroughClassHierarchy(pyObj->ob_type, &visitor); + } else { + Shiboken::ThreadStateSaver threadSaver; + threadSaver.save(); + sbkType->d->cpp_dtor(pyObj->d->cptr[0]); + } + delete[] pyObj->d->cptr; + pyObj->d->cptr = 0; + invalidate(pyObj); +} + bool hasOwnership(SbkObject* pyObj) { return pyObj->d->hasOwnership; @@ -860,6 +887,16 @@ void* cppPointer(SbkObject* pyObj, PyTypeObject* desiredType) return 0; } +std::vector<void*> cppPointers(SbkObject* pyObj) +{ + int n = getNumberOfCppBaseClasses(Py_TYPE(pyObj)); + std::vector<void*> ptrs(n); + for (int i = 0; i < n; ++i) + ptrs[i] = pyObj->d->cptr[i]; + return ptrs; +} + + bool setCppPointer(SbkObject* sbkObj, PyTypeObject* desiredType, void* cptr) { int idx = 0; @@ -1215,6 +1252,59 @@ void clearReferences(SbkObject* self) self->d->referredObjects = 0; } +std::string info(SbkObject* self) +{ + std::ostringstream s; + std::list<SbkObjectType*> bases = getCppBaseClasses(self->ob_type); + + s << "C++ address....... "; + std::list<SbkObjectType*>::const_iterator it = bases.begin(); + for (int i = 0; it != bases.end(); ++it, ++i) + s << ((PyTypeObject*)*it)->tp_name << "/" << self->d->cptr[i] << ' '; + s << "\n"; + + s << "hasOwnership...... " << bool(self->d->hasOwnership) << "\n" + "containsCppWrapper " << self->d->containsCppWrapper << "\n" + "validCppObject.... " << self->d->validCppObject << "\n" + "wasCreatedByPython " << self->d->cppObjectCreated << "\n"; + + + if (self->d->parentInfo && self->d->parentInfo->parent) { + s << "parent............ "; + Shiboken::AutoDecRef parent(PyObject_Str((PyObject*)self->d->parentInfo->parent)); + s << PyString_AS_STRING(parent.object()) << "\n"; + } + + if (self->d->parentInfo && self->d->parentInfo->children.size()) { + s << "children.......... "; + ChildrenList& children = self->d->parentInfo->children; + for (ChildrenList::const_iterator it = children.begin(); it != children.end(); ++it) { + Shiboken::AutoDecRef child(PyObject_Str((PyObject*)*it)); + s << PyString_AS_STRING(child.object()) << ' '; + } + s << '\n'; + } + + if (self->d->referredObjects && self->d->referredObjects->size()) { + Shiboken::RefCountMap& map = *self->d->referredObjects; + s << "referred objects.. "; + Shiboken::RefCountMap::const_iterator it = map.begin(); + for (; it != map.end(); ++it) { + if (it != map.begin()) + s << " "; + s << '"' << it->first << "\" => "; + std::list<PyObject*>::const_iterator j = it->second.begin(); + for (; j != it->second.end(); ++j) { + Shiboken::AutoDecRef obj(PyObject_Str(*j)); + s << PyString_AS_STRING(obj.object()) << ' '; + } + s << ' '; + } + s << '\n'; + } + return s.str(); +} + } // namespace Object } // namespace Shiboken diff --git a/libshiboken/basewrapper.h b/libshiboken/basewrapper.h index 3c6fa4f9e..334ac6caf 100644 --- a/libshiboken/basewrapper.h +++ b/libshiboken/basewrapper.h @@ -27,6 +27,7 @@ #include "python25compat.h" #include "bindingmanager.h" #include <list> +#include <vector> #include <map> #include <string> @@ -209,9 +210,15 @@ LIBSHIBOKEN_API void setTypeUserData(SbkObjectType* self, void* userData, namespace Object { /** + * Returns a string with information about the internal state of the instance object, useful for debug purposes. + */ +LIBSHIBOKEN_API std::string info(SbkObject* self); + +/** * Returns true if the object is an instance of a type created by the Shiboken generator. */ LIBSHIBOKEN_API bool checkType(PyObject* pyObj); + /** * Returns true if this object type is an instance of an user defined type derived from an Shiboken type. * \see Shiboken::ObjectType::isUserType @@ -247,9 +254,22 @@ LIBSHIBOKEN_API void setHasCppWrapper(SbkObject* pyObj, bool value); LIBSHIBOKEN_API bool hasCppWrapper(SbkObject* pyObj); /** + * Return true if the Python object was created by Python, false otherwise. + * \note This function was added to libshiboken only to be used by shiboken.wasCreatedByPython() + */ +LIBSHIBOKEN_API bool wasCreatedByPython(SbkObject* pyObj); + +/** + * Call the C++ object destructor and invalidates the Python object. + * \note This function was added to libshiboken only to be used by shiboken.delete() + */ +LIBSHIBOKEN_API void callCppDestructors(SbkObject* pyObj); + +/** * Return true if the Python is responsible for deleting the underlying C++ object. */ LIBSHIBOKEN_API bool hasOwnership(SbkObject* pyObj); + /** * Sets python as responsible to delete the underlying C++ object. * \note You this overload only when the PyObject can be a sequence and you want to @@ -257,6 +277,7 @@ LIBSHIBOKEN_API bool hasOwnership(SbkObject* pyObj); * \see getOwnership(SbkObject*) */ LIBSHIBOKEN_API void getOwnership(PyObject* pyObj); + /** * Sets python as responsible to delete the underlying C++ object. */ @@ -285,6 +306,12 @@ LIBSHIBOKEN_API bool hasParentInfo(SbkObject* pyObj); LIBSHIBOKEN_API void* cppPointer(SbkObject* pyObj, PyTypeObject* desiredType); /** + * Return a list with all C++ pointers held from a Python object. + * \note This function was added to libshiboken only to be used by shiboken.getCppPointer() + */ +LIBSHIBOKEN_API std::vector<void*> cppPointers(SbkObject* pyObj); + +/** * Set the C++ pointer of type \p desiredType of a Python object. */ LIBSHIBOKEN_API bool setCppPointer(SbkObject* sbkObj, PyTypeObject* desiredType, void* cptr); diff --git a/libshiboken/basewrapper_p.h b/libshiboken/basewrapper_p.h index 39b35f65d..35c9c83df 100644 --- a/libshiboken/basewrapper_p.h +++ b/libshiboken/basewrapper_p.h @@ -26,6 +26,8 @@ #include <Python.h> #include <list> #include <map> +#include <set> +#include <string> struct SbkObject; struct SbkObjectType; @@ -190,17 +192,26 @@ private: PyTypeObject* m_desiredType; }; +/// Call the destructor of each C++ object held by a Python object class DtorCallerVisitor : public HierarchyVisitor { public: DtorCallerVisitor(SbkObject* pyObj) : m_pyObj(pyObj) {} void visit(SbkObjectType* node); void done(); -private: +protected: std::list<std::pair<void*, SbkObjectType*> > m_ptrs; SbkObject* m_pyObj; }; +/// Dealloc of each C++ object held by a Python object, this implies a call to the C++ object destructor +class DeallocVisitor : public DtorCallerVisitor +{ +public: + DeallocVisitor(SbkObject* pyObj) : DtorCallerVisitor(pyObj) {} + void done(); +}; + /// \internal Internal function used to walk on classes inheritance trees. /** * Walk on class hierarchy using a DFS algorithm. diff --git a/shibokenmodule/CMakeLists.txt b/shibokenmodule/CMakeLists.txt new file mode 100644 index 000000000..6c97b478a --- /dev/null +++ b/shibokenmodule/CMakeLists.txt @@ -0,0 +1,32 @@ +project(shibokenmodule) + +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/shibokenmodule.txt.in" + "${CMAKE_CURRENT_BINARY_DIR}/shibokenmodule.txt" @ONLY) + + +set(sample_SRC +${CMAKE_CURRENT_BINARY_DIR}/shiboken/shiboken_module_wrapper.cpp +) + +add_custom_command(OUTPUT ${sample_SRC} +COMMAND ${GENERATORRUNNER_BINARY} --project-file=${CMAKE_CURRENT_BINARY_DIR}/shibokenmodule.txt ${GENERATOR_EXTRA_FLAGS} +WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +COMMENT "Running generator for 'shiboken'..." +) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR} + ${SBK_PYTHON_INCLUDE_DIR} + ${libshiboken_SOURCE_DIR}) +add_library(shibokenmodule MODULE ${sample_SRC}) +set_property(TARGET shibokenmodule PROPERTY PREFIX "") +set_property(TARGET shibokenmodule PROPERTY OUTPUT_NAME "shiboken") +if(WIN32) + set_property(TARGET shibokenmodule PROPERTY SUFFIX ".pyd") +endif() +target_link_libraries(shibokenmodule + ${SBK_PYTHON_LIBRARIES} + libshiboken) + +add_dependencies(shibokenmodule shiboken_generator) + diff --git a/shibokenmodule/nothing.h b/shibokenmodule/nothing.h new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/shibokenmodule/nothing.h diff --git a/shibokenmodule/shibokenmodule.txt.in b/shibokenmodule/shibokenmodule.txt.in new file mode 100644 index 000000000..6ef8c4d4c --- /dev/null +++ b/shibokenmodule/shibokenmodule.txt.in @@ -0,0 +1,16 @@ +[generator-project] + +generator-set = @generators_BINARY_DIR@/shiboken_generator@CMAKE_RELEASE_POSTFIX@@CMAKE_DEBUG_POSTFIX@@CMAKE_SHARED_LIBRARY_SUFFIX@ + +header-file = @CMAKE_CURRENT_SOURCE_DIR@/nothing.h +typesystem-file = @CMAKE_CURRENT_SOURCE_DIR@/typesystem_shiboken.xml + +output-directory = @CMAKE_CURRENT_BINARY_DIR@ + +# include-path = @libsample_SOURCE_DIR@ + +typesystem-path = @CMAKE_CURRENT_SOURCE_DIR@ + +avoid-protected-hack +#enable-parent-ctor-heuristic +#use-isnull-as-nb_nonzero diff --git a/shibokenmodule/typesystem_shiboken.xml b/shibokenmodule/typesystem_shiboken.xml new file mode 100644 index 000000000..20ca22031 --- /dev/null +++ b/shibokenmodule/typesystem_shiboken.xml @@ -0,0 +1,73 @@ +<?xml version="1.0" ?> +<typesystem package="shiboken"> + <primitive-type name="bool" /> + <primitive-type name="unsigned long" /> + <add-function signature="isValid(PyObject*)" return-type="bool"> + <inject-code> + %PYARG_0 = %CONVERTTOPYTHON[bool](Shiboken::Object::isValid(%1, false)); + </inject-code> + </add-function> + + <add-function signature="wrapInstance(unsigned long, PyType)" return-type="PyObject*"> + <inject-code> + if (Shiboken::ObjectType::checkType((PyTypeObject*)%2)) + %PYARG_0 = Shiboken::Object::newObject((SbkObjectType*)%2, (void*)%1, false, true); + else + PyErr_SetString(PyExc_TypeError, "You need a shiboken-based type."); + </inject-code> + </add-function> + + <add-function signature="getCppPointer(PyObject*)" return-type="PyObject*"> + <inject-code> + if (Shiboken::Object::checkType(%1)) { + std::vector<void*> ptrs = Shiboken::Object::cppPointers((SbkObject*)%1); + %PYARG_0 = PyTuple_New(ptrs.size()); + for (std::size_t i = 0; i < ptrs.size(); ++i) + PyTuple_SET_ITEM(%PYARG_0, i, PyLong_FromVoidPtr(ptrs[i])); + } else { + PyErr_SetString(PyExc_TypeError, "You need a shiboken-based type."); + } + </inject-code> + </add-function> + + <add-function signature="delete(PyObject*)"> + <inject-code> + if (Shiboken::Object::checkType(%1)) { + Shiboken::Object::callCppDestructors((SbkObject*)%1); + } else { + PyErr_SetString(PyExc_TypeError, "You need a shiboken-based type."); + } + </inject-code> + </add-function> + + <add-function signature="isOwnedByPython(PyObject*)" return-type="bool"> + <inject-code> + if (Shiboken::Object::checkType(%1)) { + %PYARG_0 = %CONVERTTOPYTHON[bool](Shiboken::Object::hasOwnership((SbkObject*)%1)); + } else { + PyErr_SetString(PyExc_TypeError, "You need a shiboken-based type."); + } + </inject-code> + </add-function> + + <add-function signature="wasCreatedByPython(PyObject*)" return-type="bool"> + <inject-code> + if (Shiboken::Object::checkType(%1)) { + %PYARG_0 = %CONVERTTOPYTHON[bool](Shiboken::Object::wasCreatedByPython((SbkObject*)%1)); + } else { + PyErr_SetString(PyExc_TypeError, "You need a shiboken-based type."); + } + </inject-code> + </add-function> + + <add-function signature="dump(PyObject*)" return-type="PyObject*"> + <inject-code> + if (!Shiboken::Object::checkType(%1)) { + %PYARG_0 = PyString_FromString("Ordinary Python type."); + } else { + std::string str = Shiboken::Object::info((SbkObject*)%1); + %PYARG_0 = PyString_FromString(str.c_str()); + } + </inject-code> + </add-function> +</typesystem> diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6d8e41489..1c728dd98 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -23,7 +23,8 @@ if(DEFINED MINIMAL_TESTS) else() file(GLOB TEST_FILES minimalbinding/*_test.py samplebinding/*_test.py - otherbinding/*_test.py) + otherbinding/*_test.py + shibokenmodule/*_test.py) endif() list(SORT TEST_FILES) @@ -38,7 +39,7 @@ if(CMAKE_VERSION VERSION_LESS 2.8) message("CMake version greater than 2.8 necessary to run tests") else() if(WIN32) - set(TEST_PYTHONPATH "${minimal_BINARY_DIR};${sample_BINARY_DIR};${other_BINARY_DIR}") + set(TEST_PYTHONPATH "${minimal_BINARY_DIR};${sample_BINARY_DIR};${other_BINARY_DIR};${shibokenmodule_BINARY_DIR}") set(TEST_LIBRARY_PATH "$ENV{PATH};${libminimal_BINARY_DIR};${libsample_BINARY_DIR};${libother_BINARY_DIR};${libshiboken_BINARY_DIR}") set(LIBRARY_PATH_VAR "PATH") string(REPLACE "\\" "/" TEST_PYTHONPATH "${TEST_PYTHONPATH}") @@ -46,14 +47,13 @@ else() string(REPLACE ";" "\\;" TEST_PYTHONPATH "${TEST_PYTHONPATH}") string(REPLACE ";" "\\;" TEST_LIBRARY_PATH "${TEST_LIBRARY_PATH}") else() - set(TEST_PYTHONPATH "${minimal_BINARY_DIR}:${sample_BINARY_DIR}:${other_BINARY_DIR}") + set(TEST_PYTHONPATH "${minimal_BINARY_DIR}:${sample_BINARY_DIR}:${other_BINARY_DIR}:${shibokenmodule_BINARY_DIR}") set(TEST_LIBRARY_PATH "$ENV{LD_LIBRARY_PATH}:${libminimal_BINARY_DIR}:${libsample_BINARY_DIR}:${libother_BINARY_DIR}:${libshiboken_BINARY_DIR}") set(LIBRARY_PATH_VAR "LD_LIBRARY_PATH") endif() - foreach(test_file ${TEST_FILES}) - string(REGEX MATCH "/([^/]+)binding/([^/]+)_test.py" tmp ${test_file}) - set(test_name "${CMAKE_MATCH_1}_${CMAKE_MATCH_2}") + string(REGEX MATCH "/([^/]+)(binding|module)/([^/]+)_test.py" tmp ${test_file}) + set(test_name "${CMAKE_MATCH_1}_${CMAKE_MATCH_3}") list(FIND test_blacklist ${test_name} expect_fail) add_test(${test_name} ${PYTHON_EXECUTABLE} ${test_file}) set_tests_properties(${test_name} PROPERTIES ENVIRONMENT "PYTHONPATH=${TEST_PYTHONPATH};${LIBRARY_PATH_VAR}=${TEST_LIBRARY_PATH}") diff --git a/tests/libsample/objecttype.cpp b/tests/libsample/objecttype.cpp index e4fce71e3..c253c610f 100644 --- a/tests/libsample/objecttype.cpp +++ b/tests/libsample/objecttype.cpp @@ -283,3 +283,9 @@ ObjectType* ObjectType::createChild(ObjectType* parent) { return new ObjectType(parent); } + +std::size_t ObjectType::createObjectType() +{ + void* addr = new ObjectType(); + return (std::size_t) addr; +} diff --git a/tests/libsample/objecttype.h b/tests/libsample/objecttype.h index f032a09f8..84812a8d6 100644 --- a/tests/libsample/objecttype.h +++ b/tests/libsample/objecttype.h @@ -106,6 +106,7 @@ public: virtual bool isPython() { return false; } void callVirtualCreateChild(); virtual ObjectType* createChild(ObjectType* parent); + static std::size_t createObjectType(); //return a parent from C++ ObjectType* getCppParent() { diff --git a/tests/samplebinding/typesystem_sample.xml b/tests/samplebinding/typesystem_sample.xml index 2fef355fc..09de7b948 100644 --- a/tests/samplebinding/typesystem_sample.xml +++ b/tests/samplebinding/typesystem_sample.xml @@ -16,6 +16,7 @@ <primitive-type name="unsigned char"/> <primitive-type name="long"/> <primitive-type name="unsigned long"/> + <primitive-type name="std::size_t" target-lang-api-name="PyLong"/> <primitive-type name="std::string"/> <primitive-type name="Complex" target-lang-api-name="PyComplex"> @@ -303,6 +304,11 @@ </object-type> <object-type name="ObjectView"> + <modify-function signature="ObjectView(ObjectModel*, ObjectType*)"> + <modify-argument index="1"> + <reference-count action="set" variable-name="setModel(ObjectModel*)1"/> + </modify-argument> + </modify-function> <modify-function signature="setModel(ObjectModel*)"> <modify-argument index="1"> <reference-count action="set"/> diff --git a/tests/shibokenmodule/module_test.py b/tests/shibokenmodule/module_test.py new file mode 100644 index 000000000..565e985aa --- /dev/null +++ b/tests/shibokenmodule/module_test.py @@ -0,0 +1,70 @@ +import shiboken +import unittest +from sample import * + +class MultipleInherited (ObjectType, Point): + def __init__(self): + ObjectType.__init__(self) + Point.__init__(self) + +class TestShiboken(unittest.TestCase): + def testIsValid(self): + self.assertTrue(shiboken.isValid(object())) + self.assertTrue(shiboken.isValid(None)) + + bb = BlackBox() + item = ObjectType() + ticket = bb.keepObjectType(item) + bb.disposeObjectType(ticket) + self.assertFalse(shiboken.isValid(item)) + + def testWrapInstance(self): + addr = ObjectType.createObjectType() + obj = shiboken.wrapInstance(addr, ObjectType) + self.assertFalse(shiboken.wasCreatedByPython(obj)) + obj.setObjectName("obj") + self.assertEqual(obj.objectName(), "obj") + self.assertEqual(addr, obj.identifier()) + self.assertFalse(shiboken.wasCreatedByPython(obj)) + + # avoid mem leak =] + bb = BlackBox() + self.assertTrue(shiboken.wasCreatedByPython(bb)) + bb.disposeObjectType(bb.keepObjectType(obj)) + + def testIsOwnedByPython(self): + obj = ObjectType() + self.assertTrue(shiboken.isOwnedByPython(obj)) + p = ObjectType() + obj.setParent(p) + self.assertFalse(shiboken.isOwnedByPython(obj)) + + def testDump(self): + """Just check if dump doesn't crash on certain use cases""" + p = ObjectType() + obj = ObjectType(p) + obj2 = ObjectType(obj) + obj3 = ObjectType(obj) + self.assertEqual(shiboken.dump(None), "Ordinary Python type.") + shiboken.dump(obj) + + model = ObjectModel(p) + v = ObjectView(model, p) + shiboken.dump(v) + + m = MultipleInherited() + shiboken.dump(m) + self.assertEqual(len(shiboken.getCppPointer(m)), 2) + + def testDelete(self): + obj = ObjectType() + child = ObjectType(obj) + self.assertTrue(shiboken.isValid(obj)) + self.assertTrue(shiboken.isValid(child)) + # Note: this test doesn't assure that the object dtor was really called + shiboken.delete(obj) + self.assertFalse(shiboken.isValid(obj)) + self.assertFalse(shiboken.isValid(child)) + +if __name__ == '__main__': + unittest.main() |