Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Pycapsule #493

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 27, 2011
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CXX/Python2/Exception.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,16 @@ namespace Py
}
};

class NotImplementedError: public StandardError
{
public:
NotImplementedError (const std::string& reason)
: StandardError()
{
PyErr_SetString (Py::_Exc_NotImplementedError(), reason.c_str());
}
};

class SystemError: public StandardError
{
public:
Expand Down
12 changes: 10 additions & 2 deletions CXX/Python2/ExtensionModule.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,19 @@ namespace Py
{
MethodDefExt<T> *method_def = (*i).second;

static PyObject *self = PyCObject_FromVoidPtr( this, do_not_dealloc );
#if PY_VERSION_HEX < 0x02070000
static PyObject *self = PyCObject_FromVoidPtr( this, do_not_dealloc );
#else
static PyObject *self = PyCapsule_New( this, NULL, NULL );
#endif

Tuple args( 2 );
args[0] = Object( self );
args[1] = Object( PyCObject_FromVoidPtr( method_def, do_not_dealloc ) );
#if PY_VERSION_HEX < 0x02070000
args[1] = Object( PyCObject_FromVoidPtr( method_def, do_not_dealloc ) );
#else
args[1] = Object( PyCapsule_New( method_def, NULL, NULL ) );
#endif

PyObject *func = PyCFunction_New
(
Expand Down
36 changes: 28 additions & 8 deletions CXX/Python2/ExtensionOldType.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ namespace Py
return this;
}

Object self()
{
return asObject( this );
}

protected:
explicit PythonExtension()
: PythonExtensionBase()
Expand Down Expand Up @@ -173,8 +178,11 @@ namespace Py
Tuple self( 2 );

self[0] = Object( this );
self[1] = Object( PyCObject_FromVoidPtr( method_def, do_not_dealloc ), true );

#if PY_VERSION_HEX < 0x02070000
self[1] = Object( PyCObject_FromVoidPtr( method_def, do_not_dealloc ), true );
#else
self[1] = Object( PyCapsule_New( method_def, NULL, NULL ), true );
#endif
PyObject *func = PyCFunction_New( &method_def->ext_meth_def, self.ptr() );

return Object(func, true);
Expand Down Expand Up @@ -230,8 +238,12 @@ namespace Py

PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
T *self = static_cast<T *>( self_in_cobject );
MethodDefExt<T> *meth_def = reinterpret_cast<MethodDefExt<T> *>(
PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ) );
#if PY_VERSION_HEX < 0x02070000
void *capsule = PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() );
#else
void *capsule = PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL );
#endif
MethodDefExt<T> *meth_def = reinterpret_cast<MethodDefExt<T> *>( capsule );
Object result;

// Adding try & catch in case of STL debug-mode exceptions.
Expand Down Expand Up @@ -266,8 +278,12 @@ namespace Py
PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
T *self = static_cast<T *>( self_in_cobject );

MethodDefExt<T> *meth_def = reinterpret_cast<MethodDefExt<T> *>(
PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ) );
#if PY_VERSION_HEX < 0x02070000
void *capsule = PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() );
#else
void *capsule = PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL );
#endif
MethodDefExt<T> *meth_def = reinterpret_cast<MethodDefExt<T> *>( capsule );
Tuple args( _args );

Object result;
Expand Down Expand Up @@ -303,8 +319,12 @@ namespace Py
PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
T *self = static_cast<T *>( self_in_cobject );

MethodDefExt<T> *meth_def = reinterpret_cast<MethodDefExt<T> *>(
PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() ) );
#if PY_VERSION_HEX < 0x02070000
void *capsule = PyCObject_AsVoidPtr( self_and_name_tuple[1].ptr() );
#else
void *capsule = PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL );
#endif
MethodDefExt<T> *meth_def = reinterpret_cast<MethodDefExt<T> *>( capsule );

Tuple args( _args );

Expand Down
99 changes: 66 additions & 33 deletions CXX/Python2/ExtensionType.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -45,44 +45,67 @@
#define PYCXX_NOARGS_METHOD_DECL( CLS, NAME ) \
static PyObject *PYCXX_NOARGS_METHOD_NAME( NAME )( PyObject *_self, PyObject *, PyObject * ) \
{ \
Py::PythonClassInstance *self_python = reinterpret_cast< Py::PythonClassInstance * >( _self ); \
CLS *self = reinterpret_cast< CLS * >( self_python->m_pycxx_object ); \
Py::Object r( (self->NAME)() ); \
return Py::new_reference_to( r.ptr() ); \
try \
{ \
Py::PythonClassInstance *self_python = reinterpret_cast< Py::PythonClassInstance * >( _self ); \
CLS *self = reinterpret_cast< CLS * >( self_python->m_pycxx_object ); \
Py::Object r( (self->NAME)() ); \
return Py::new_reference_to( r.ptr() ); \
} \
catch( Py::Exception & ) \
{ \
return 0; \
} \
}
#define PYCXX_VARARGS_METHOD_DECL( CLS, NAME ) \
static PyObject *PYCXX_VARARGS_METHOD_NAME( NAME )( PyObject *_self, PyObject *_a, PyObject * ) \
{ \
Py::PythonClassInstance *self_python = reinterpret_cast< Py::PythonClassInstance * >( _self ); \
CLS *self = reinterpret_cast< CLS * >( self_python->m_pycxx_object ); \
Py::Tuple a( _a ); \
Py::Object r( (self->NAME)( a ) ); \
return Py::new_reference_to( r.ptr() ); \
try \
{ \
Py::PythonClassInstance *self_python = reinterpret_cast< Py::PythonClassInstance * >( _self ); \
CLS *self = reinterpret_cast< CLS * >( self_python->m_pycxx_object ); \
Py::Tuple a( _a ); \
Py::Object r( (self->NAME)( a ) ); \
return Py::new_reference_to( r.ptr() ); \
} \
catch( Py::Exception & ) \
{ \
return 0; \
} \
}
#define PYCXX_KEYWORDS_METHOD_DECL( CLS, NAME ) \
static PyObject *PYCXX_KEYWORDS_METHOD_NAME( NAME )( PyObject *_self, PyObject *_a, PyObject *_k ) \
{ \
Py::PythonClassInstance *self_python = reinterpret_cast< Py::PythonClassInstance * >( _self ); \
CLS *self = reinterpret_cast< CLS * >( self_python->m_pycxx_object ); \
Py::Tuple a( _a ); \
Py::Dict k; \
if( _k != NULL ) \
k = _k; \
Py::Object r( (self->NAME)( a, k ) ); \
return Py::new_reference_to( r.ptr() ); \
try \
{ \
Py::PythonClassInstance *self_python = reinterpret_cast< Py::PythonClassInstance * >( _self ); \
CLS *self = reinterpret_cast< CLS * >( self_python->m_pycxx_object ); \
Py::Tuple a( _a ); \
Py::Dict k; \
if( _k != NULL ) \
k = _k; \
Py::Object r( (self->NAME)( a, k ) ); \
return Py::new_reference_to( r.ptr() ); \
} \
catch( Py::Exception & ) \
{ \
return 0; \
} \
}

// need to support METH_STATIC and METH_CLASS

#define PYCXX_ADD_NOARGS_METHOD( NAME, docs ) \
add_method( #NAME, (PyCFunction)PYCXX_NOARGS_METHOD_NAME( NAME ), METH_NOARGS, docs )
#define PYCXX_ADD_VARARGS_METHOD( NAME, docs ) \
add_method( #NAME, (PyCFunction)PYCXX_VARARGS_METHOD_NAME( NAME ), METH_VARARGS, docs )
#define PYCXX_ADD_KEYWORDS_METHOD( NAME, docs ) \
add_method( #NAME, (PyCFunction)PYCXX_KEYWORDS_METHOD_NAME( NAME ), METH_VARARGS | METH_KEYWORDS, docs )
#define PYCXX_ADD_NOARGS_METHOD( PYNAME, NAME, docs ) \
add_method( #PYNAME, (PyCFunction)PYCXX_NOARGS_METHOD_NAME( NAME ), METH_NOARGS, docs )
#define PYCXX_ADD_VARARGS_METHOD( PYNAME, NAME, docs ) \
add_method( #PYNAME, (PyCFunction)PYCXX_VARARGS_METHOD_NAME( NAME ), METH_VARARGS, docs )
#define PYCXX_ADD_KEYWORDS_METHOD( PYNAME, NAME, docs ) \
add_method( #PYNAME, (PyCFunction)PYCXX_KEYWORDS_METHOD_NAME( NAME ), METH_VARARGS | METH_KEYWORDS, docs )

namespace Py
{
extern PythonExtensionBase *getPythonExtensionBase( PyObject *self );

struct PythonClassInstance
{
PyObject_HEAD
Expand Down Expand Up @@ -131,7 +154,7 @@ namespace Py
{
new_mt[ i ] = old_mt[ i ];
}
delete old_mt;
delete[] old_mt;
m_methods_table = new_mt;
}

Expand Down Expand Up @@ -167,10 +190,8 @@ namespace Py
protected:
explicit PythonClass( PythonClassInstance *self, Tuple &args, Dict &kwds )
: PythonExtensionBase()
, m_self( self )
, m_class_instance( self )
{
// we are a class
behaviors().supportClass();
}

virtual ~PythonClass()
Expand Down Expand Up @@ -203,6 +224,12 @@ namespace Py
p->set_tp_new( extension_object_new );
p->set_tp_init( extension_object_init );
p->set_tp_dealloc( extension_object_deallocator );
// we are a class
p->supportClass();

// always support get and set attr
p->supportGetattro();
p->supportSetattro();
}

return *p;
Expand Down Expand Up @@ -238,7 +265,7 @@ namespace Py
PythonClassInstance *self = reinterpret_cast<PythonClassInstance *>( _self );
#ifdef PYCXX_DEBUG
std::cout << "extension_object_init( self=0x" << std::hex << reinterpret_cast< unsigned int >( self ) << std::dec << " )" << std::endl;
std::cout << " self->cxx_object=0x" << std::hex << reinterpret_cast< unsigned int >( self->cxx_object ) << std::dec << std::endl;
std::cout << " self->m_pycxx_object=0x" << std::hex << reinterpret_cast< unsigned int >( self->m_pycxx_object ) << std::dec << std::endl;
#endif

if( self->m_pycxx_object == NULL )
Expand Down Expand Up @@ -268,9 +295,10 @@ namespace Py
PythonClassInstance *self = reinterpret_cast< PythonClassInstance * >( _self );
#ifdef PYCXX_DEBUG
std::cout << "extension_object_deallocator( self=0x" << std::hex << reinterpret_cast< unsigned int >( self ) << std::dec << " )" << std::endl;
std::cout << " self->cxx_object=0x" << std::hex << reinterpret_cast< unsigned int >( self->cxx_object ) << std::dec << std::endl;
std::cout << " self->m_pycxx_object=0x" << std::hex << reinterpret_cast< unsigned int >( self->m_pycxx_object ) << std::dec << std::endl;
#endif
delete self->m_pycxx_object;
_self->ob_type->tp_free( _self );
}

public:
Expand All @@ -295,14 +323,19 @@ namespace Py
return check( ob.ptr() );
}

PyObject *selfPtr()
virtual PyObject *selfPtr()
{
return reinterpret_cast<PyObject *>( m_class_instance );
}

virtual Object self()
{
return reinterpret_cast<PyObject *>( m_self );
return Object( reinterpret_cast<PyObject *>( m_class_instance ) );
}

protected:
private:
PythonClassInstance *m_self;
PythonClassInstance *m_class_instance;

private:
//
Expand Down Expand Up @@ -361,7 +394,7 @@ namespace Py
//
T *getCxxObject( void )
{
return static_cast<T *>( ptr() );
return dynamic_cast< T * >( getPythonExtensionBase( ptr() ) );
}
};
} // Namespace Py
Expand Down
32 changes: 32 additions & 0 deletions CXX/Python2/ExtensionTypeBase.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,40 @@ namespace Py
virtual Py_ssize_t buffer_getwritebuffer( Py_ssize_t, void** );
virtual Py_ssize_t buffer_getsegcount( Py_ssize_t* );

public:
// helper functions to call function fn_name with 0 to 9 args
Object callOnSelf( const std::string &fn_name );
Object callOnSelf( const std::string &fn_name,
const Object &arg1 );
Object callOnSelf( const std::string &fn_name,
const Object &arg1, const Object &arg2 );
Object callOnSelf( const std::string &fn_name,
const Object &arg1, const Object &arg2, const Object &arg3 );
Object callOnSelf( const std::string &fn_name,
const Object &arg1, const Object &arg2, const Object &arg3,
const Object &arg4 );
Object callOnSelf( const std::string &fn_name,
const Object &arg1, const Object &arg2, const Object &arg3,
const Object &arg4, const Object &arg5 );
Object callOnSelf( const std::string &fn_name,
const Object &arg1, const Object &arg2, const Object &arg3,
const Object &arg4, const Object &arg5, const Object &arg6 );
Object callOnSelf( const std::string &fn_name,
const Object &arg1, const Object &arg2, const Object &arg3,
const Object &arg4, const Object &arg5, const Object &arg6,
const Object &arg7 );
Object callOnSelf( const std::string &fn_name,
const Object &arg1, const Object &arg2, const Object &arg3,
const Object &arg4, const Object &arg5, const Object &arg6,
const Object &arg7, const Object &arg8 );
Object callOnSelf( const std::string &fn_name,
const Object &arg1, const Object &arg2, const Object &arg3,
const Object &arg4, const Object &arg5, const Object &arg6,
const Object &arg7, const Object &arg8, const Object &arg9 );

public:
virtual PyObject *selfPtr() = 0;
virtual Object self() = 0;

private:
void missing_method( void );
Expand Down
10 changes: 10 additions & 0 deletions CXX/Python2/IndirectPythonInterface.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ namespace Py
bool _Buffer_Check( PyObject *op ) { return (op)->ob_type == _Buffer_Type(); }
bool _CFunction_Check( PyObject *op ) { return (op)->ob_type == _CFunction_Type(); }
bool _Class_Check( PyObject *op ) { return (op)->ob_type == _Class_Type(); }
#if PY_VERSION_HEX < 0x02070000
bool _CObject_Check( PyObject *op ) { return (op)->ob_type == _CObject_Type(); }
#endif
bool _Complex_Check( PyObject *op ) { return (op)->ob_type == _Complex_Type(); }
bool _Dict_Check( PyObject *op ) { return (op)->ob_type == _Dict_Type(); }
bool _File_Check( PyObject *op ) { return (op)->ob_type == _File_Type(); }
Expand Down Expand Up @@ -123,7 +125,9 @@ static PyObject *ptr__PyTrue = NULL;
static PyTypeObject *ptr__Buffer_Type = NULL;
static PyTypeObject *ptr__CFunction_Type = NULL;
static PyTypeObject *ptr__Class_Type = NULL;
#if PY_VERSION_HEX < 0x02070000
static PyTypeObject *ptr__CObject_Type = NULL;
#endif
static PyTypeObject *ptr__Complex_Type = NULL;
static PyTypeObject *ptr__Dict_Type = NULL;
static PyTypeObject *ptr__File_Type = NULL;
Expand Down Expand Up @@ -310,7 +314,9 @@ bool InitialisePythonIndirectInterface()
ptr__Buffer_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyBuffer_Type" );
ptr__CFunction_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyCFunction_Type" );
ptr__Class_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyClass_Type" );
#if PY_VERSION_HEX < 0x02070000
ptr__CObject_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyCObject_Type" );
#endif
ptr__Complex_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyComplex_Type" );
ptr__Dict_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyDict_Type" );
ptr__File_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyFile_Type" );
Expand Down Expand Up @@ -398,7 +404,9 @@ PyObject * _True() { return ptr__PyTrue; }
PyTypeObject * _Buffer_Type() { return ptr__Buffer_Type; }
PyTypeObject * _CFunction_Type(){ return ptr__CFunction_Type; }
PyTypeObject * _Class_Type() { return ptr__Class_Type; }
#if PY_VERSION_HEX < 0x02070000
PyTypeObject * _CObject_Type() { return ptr__CObject_Type; }
#endif
PyTypeObject * _Complex_Type() { return ptr__Complex_Type; }
PyTypeObject * _Dict_Type() { return ptr__Dict_Type; }
PyTypeObject * _File_Type() { return ptr__File_Type; }
Expand Down Expand Up @@ -542,7 +550,9 @@ PyObject * _True() { return Py_True; }
PyTypeObject * _Buffer_Type() { return &PyBuffer_Type; }
PyTypeObject * _CFunction_Type() { return &PyCFunction_Type; }
PyTypeObject * _Class_Type() { return &PyClass_Type; }
#if PY_VERSION_HEX < 0x02070000
PyTypeObject * _CObject_Type() { return &PyCObject_Type; }
#endif
PyTypeObject * _Complex_Type() { return &PyComplex_Type; }
PyTypeObject * _Dict_Type() { return &PyDict_Type; }
PyTypeObject * _File_Type() { return &PyFile_Type; }
Expand Down
2 changes: 2 additions & 0 deletions CXX/Python2/IndirectPythonInterface.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,10 @@ bool _Instance_Check( PyObject *op );
PyTypeObject * _Method_Type();
bool _Method_Check( PyObject *op );

#if PY_VERSION_HEX < 0x02070000
PyTypeObject * _CObject_Type();
bool _CObject_Check( PyObject *op );
#endif

PyTypeObject * _Complex_Type();
bool _Complex_Check( PyObject *op );
Expand Down
Loading