aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHugo Parente Lima <hugo.pl@gmail.com>2011-08-04 16:10:34 -0300
committerHugo Parente Lima <hugo.pl@gmail.com>2012-03-08 16:17:13 -0300
commit784a4bbb707d132b26bcb177521745575dc0823f (patch)
treef637ef4134445b1cfdd0c33878b7a1ce46f02145
parent8b1ddcd3ef711bab70bb7cdebc26558a26f42df9 (diff)
Implements PSEP-0106 and fixes bug 902 - "Expose Shiboken functionality through a Python module".
-rw-r--r--CMakeLists.txt1
-rw-r--r--generator/cppgenerator.cpp11
-rw-r--r--generator/headergenerator.cpp32
-rw-r--r--libshiboken/basewrapper.cpp96
-rw-r--r--libshiboken/basewrapper.h27
-rw-r--r--libshiboken/basewrapper_p.h13
-rw-r--r--shibokenmodule/CMakeLists.txt32
-rw-r--r--shibokenmodule/nothing.h0
-rw-r--r--shibokenmodule/shibokenmodule.txt.in16
-rw-r--r--shibokenmodule/typesystem_shiboken.xml73
-rw-r--r--tests/CMakeLists.txt12
-rw-r--r--tests/libsample/objecttype.cpp6
-rw-r--r--tests/libsample/objecttype.h1
-rw-r--r--tests/samplebinding/typesystem_sample.xml6
-rw-r--r--tests/shibokenmodule/module_test.py70
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&lt;void*> ptrs = Shiboken::Object::cppPointers((SbkObject*)%1);
+ %PYARG_0 = PyTuple_New(ptrs.size());
+ for (std::size_t i = 0; i &lt; 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()