4545#define PYCXX_NOARGS_METHOD_DECL ( CLS, NAME ) \
4646 static PyObject *PYCXX_NOARGS_METHOD_NAME ( NAME )( PyObject *_self, PyObject *, PyObject * ) \
4747 { \
48- Py::PythonClassInstance *self_python = reinterpret_cast < Py::PythonClassInstance * >( _self ); \
49- CLS *self = reinterpret_cast < CLS * >( self_python->m_pycxx_object ); \
50- Py::Object r ( (self->NAME )() ); \
51- return Py::new_reference_to ( r.ptr () ); \
48+ try \
49+ { \
50+ Py::PythonClassInstance *self_python = reinterpret_cast < Py::PythonClassInstance * >( _self ); \
51+ CLS *self = reinterpret_cast < CLS * >( self_python->m_pycxx_object ); \
52+ Py::Object r ( (self->NAME )() ); \
53+ return Py::new_reference_to ( r.ptr () ); \
54+ } \
55+ catch ( Py::Exception & ) \
56+ { \
57+ return 0 ; \
58+ } \
5259 }
5360#define PYCXX_VARARGS_METHOD_DECL ( CLS, NAME ) \
5461 static PyObject *PYCXX_VARARGS_METHOD_NAME ( NAME )( PyObject *_self, PyObject *_a, PyObject * ) \
5562 { \
56- Py::PythonClassInstance *self_python = reinterpret_cast < Py::PythonClassInstance * >( _self ); \
57- CLS *self = reinterpret_cast < CLS * >( self_python->m_pycxx_object ); \
58- Py::Tuple a ( _a ); \
59- Py::Object r ( (self->NAME )( a ) ); \
60- return Py::new_reference_to ( r.ptr () ); \
63+ try \
64+ { \
65+ Py::PythonClassInstance *self_python = reinterpret_cast < Py::PythonClassInstance * >( _self ); \
66+ CLS *self = reinterpret_cast < CLS * >( self_python->m_pycxx_object ); \
67+ Py::Tuple a ( _a ); \
68+ Py::Object r ( (self->NAME )( a ) ); \
69+ return Py::new_reference_to ( r.ptr () ); \
70+ } \
71+ catch ( Py::Exception & ) \
72+ { \
73+ return 0 ; \
74+ } \
6175 }
6276#define PYCXX_KEYWORDS_METHOD_DECL ( CLS, NAME ) \
6377 static PyObject *PYCXX_KEYWORDS_METHOD_NAME ( NAME )( PyObject *_self, PyObject *_a, PyObject *_k ) \
6478 { \
65- Py::PythonClassInstance *self_python = reinterpret_cast < Py::PythonClassInstance * >( _self ); \
66- CLS *self = reinterpret_cast < CLS * >( self_python->m_pycxx_object ); \
67- Py::Tuple a ( _a ); \
68- Py::Dict k; \
69- if ( _k != NULL ) \
70- k = _k; \
71- Py::Object r ( (self->NAME )( a, k ) ); \
72- return Py::new_reference_to ( r.ptr () ); \
79+ try \
80+ { \
81+ Py::PythonClassInstance *self_python = reinterpret_cast < Py::PythonClassInstance * >( _self ); \
82+ CLS *self = reinterpret_cast < CLS * >( self_python->m_pycxx_object ); \
83+ Py::Tuple a ( _a ); \
84+ Py::Dict k; \
85+ if ( _k != NULL ) \
86+ k = _k; \
87+ Py::Object r ( (self->NAME )( a, k ) ); \
88+ return Py::new_reference_to ( r.ptr () ); \
89+ } \
90+ catch ( Py::Exception & ) \
91+ { \
92+ return 0 ; \
93+ } \
7394 }
7495
7596// need to support METH_STATIC and METH_CLASS
7697
77- #define PYCXX_ADD_NOARGS_METHOD ( NAME, docs ) \
78- add_method ( #NAME , (PyCFunction)PYCXX_NOARGS_METHOD_NAME( NAME ), METH_NOARGS, docs )
79- #define PYCXX_ADD_VARARGS_METHOD ( NAME, docs ) \
80- add_method ( #NAME , (PyCFunction)PYCXX_VARARGS_METHOD_NAME( NAME ), METH_VARARGS, docs )
81- #define PYCXX_ADD_KEYWORDS_METHOD ( NAME, docs ) \
82- add_method ( #NAME , (PyCFunction)PYCXX_KEYWORDS_METHOD_NAME( NAME ), METH_VARARGS | METH_KEYWORDS, docs )
98+ #define PYCXX_ADD_NOARGS_METHOD ( PYNAME, NAME, docs ) \
99+ add_method ( #PYNAME , (PyCFunction)PYCXX_NOARGS_METHOD_NAME( NAME ), METH_NOARGS, docs )
100+ #define PYCXX_ADD_VARARGS_METHOD ( PYNAME, NAME, docs ) \
101+ add_method ( #PYNAME , (PyCFunction)PYCXX_VARARGS_METHOD_NAME( NAME ), METH_VARARGS, docs )
102+ #define PYCXX_ADD_KEYWORDS_METHOD ( PYNAME, NAME, docs ) \
103+ add_method ( #PYNAME , (PyCFunction)PYCXX_KEYWORDS_METHOD_NAME( NAME ), METH_VARARGS | METH_KEYWORDS, docs )
83104
84105namespace Py
85106{
107+ extern PythonExtensionBase *getPythonExtensionBase ( PyObject *self );
108+
86109 struct PythonClassInstance
87110 {
88111 PyObject_HEAD
@@ -131,7 +154,7 @@ namespace Py
131154 {
132155 new_mt[ i ] = old_mt[ i ];
133156 }
134- delete old_mt;
157+ delete[] old_mt;
135158 m_methods_table = new_mt;
136159 }
137160
@@ -167,10 +190,8 @@ namespace Py
167190 protected:
168191 explicit PythonClass ( PythonClassInstance *self, Tuple &args, Dict &kwds )
169192 : PythonExtensionBase()
170- , m_self ( self )
193+ , m_class_instance ( self )
171194 {
172- // we are a class
173- behaviors ().supportClass ();
174195 }
175196
176197 virtual ~PythonClass ()
@@ -203,6 +224,12 @@ namespace Py
203224 p->set_tp_new ( extension_object_new );
204225 p->set_tp_init ( extension_object_init );
205226 p->set_tp_dealloc ( extension_object_deallocator );
227+ // we are a class
228+ p->supportClass ();
229+
230+ // always support get and set attr
231+ p->supportGetattro ();
232+ p->supportSetattro ();
206233 }
207234
208235 return *p;
@@ -238,7 +265,7 @@ namespace Py
238265 PythonClassInstance *self = reinterpret_cast <PythonClassInstance *>( _self );
239266#ifdef PYCXX_DEBUG
240267 std::cout << " extension_object_init( self=0x" << std::hex << reinterpret_cast < unsigned int >( self ) << std::dec << " )" << std::endl;
241- std::cout << " self->cxx_object =0x" << std::hex << reinterpret_cast < unsigned int >( self->cxx_object ) << std::dec << std::endl;
268+ std::cout << " self->m_pycxx_object =0x" << std::hex << reinterpret_cast < unsigned int >( self->m_pycxx_object ) << std::dec << std::endl;
242269#endif
243270
244271 if ( self->m_pycxx_object == NULL )
@@ -268,9 +295,10 @@ namespace Py
268295 PythonClassInstance *self = reinterpret_cast < PythonClassInstance * >( _self );
269296#ifdef PYCXX_DEBUG
270297 std::cout << " extension_object_deallocator( self=0x" << std::hex << reinterpret_cast < unsigned int >( self ) << std::dec << " )" << std::endl;
271- std::cout << " self->cxx_object =0x" << std::hex << reinterpret_cast < unsigned int >( self->cxx_object ) << std::dec << std::endl;
298+ std::cout << " self->m_pycxx_object =0x" << std::hex << reinterpret_cast < unsigned int >( self->m_pycxx_object ) << std::dec << std::endl;
272299#endif
273300 delete self->m_pycxx_object ;
301+ _self->ob_type ->tp_free ( _self );
274302 }
275303
276304 public:
@@ -295,14 +323,19 @@ namespace Py
295323 return check ( ob.ptr () );
296324 }
297325
298- PyObject *selfPtr ()
326+ virtual PyObject *selfPtr ()
327+ {
328+ return reinterpret_cast <PyObject *>( m_class_instance );
329+ }
330+
331+ virtual Object self ()
299332 {
300- return reinterpret_cast <PyObject *>( m_self );
333+ return Object ( reinterpret_cast <PyObject *>( m_class_instance ) );
301334 }
302335
303336 protected:
304337 private:
305- PythonClassInstance *m_self ;
338+ PythonClassInstance *m_class_instance ;
306339
307340 private:
308341 //
@@ -361,7 +394,7 @@ namespace Py
361394 //
362395 T *getCxxObject ( void )
363396 {
364- return static_cast < T *>( ptr () );
397+ return dynamic_cast < T * >( getPythonExtensionBase ( ptr () ) );
365398 }
366399 };
367400} // Namespace Py
0 commit comments