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