45
45
#define PYCXX_NOARGS_METHOD_DECL ( CLS, NAME ) \
46
46
static PyObject *PYCXX_NOARGS_METHOD_NAME ( NAME )( PyObject *_self, PyObject *, PyObject * ) \
47
47
{ \
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
+ } \
52
59
}
53
60
#define PYCXX_VARARGS_METHOD_DECL ( CLS, NAME ) \
54
61
static PyObject *PYCXX_VARARGS_METHOD_NAME ( NAME )( PyObject *_self, PyObject *_a, PyObject * ) \
55
62
{ \
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
+ } \
61
75
}
62
76
#define PYCXX_KEYWORDS_METHOD_DECL ( CLS, NAME ) \
63
77
static PyObject *PYCXX_KEYWORDS_METHOD_NAME ( NAME )( PyObject *_self, PyObject *_a, PyObject *_k ) \
64
78
{ \
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
+ } \
73
94
}
74
95
75
96
// need to support METH_STATIC and METH_CLASS
76
97
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 )
83
104
84
105
namespace Py
85
106
{
107
+ extern PythonExtensionBase *getPythonExtensionBase ( PyObject *self );
108
+
86
109
struct PythonClassInstance
87
110
{
88
111
PyObject_HEAD
@@ -131,7 +154,7 @@ namespace Py
131
154
{
132
155
new_mt[ i ] = old_mt[ i ];
133
156
}
134
- delete old_mt;
157
+ delete[] old_mt;
135
158
m_methods_table = new_mt;
136
159
}
137
160
@@ -167,10 +190,8 @@ namespace Py
167
190
protected:
168
191
explicit PythonClass ( PythonClassInstance *self, Tuple &args, Dict &kwds )
169
192
: PythonExtensionBase()
170
- , m_self ( self )
193
+ , m_class_instance ( self )
171
194
{
172
- // we are a class
173
- behaviors ().supportClass ();
174
195
}
175
196
176
197
virtual ~PythonClass ()
@@ -203,6 +224,12 @@ namespace Py
203
224
p->set_tp_new ( extension_object_new );
204
225
p->set_tp_init ( extension_object_init );
205
226
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 ();
206
233
}
207
234
208
235
return *p;
@@ -238,7 +265,7 @@ namespace Py
238
265
PythonClassInstance *self = reinterpret_cast <PythonClassInstance *>( _self );
239
266
#ifdef PYCXX_DEBUG
240
267
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;
242
269
#endif
243
270
244
271
if ( self->m_pycxx_object == NULL )
@@ -268,9 +295,10 @@ namespace Py
268
295
PythonClassInstance *self = reinterpret_cast < PythonClassInstance * >( _self );
269
296
#ifdef PYCXX_DEBUG
270
297
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;
272
299
#endif
273
300
delete self->m_pycxx_object ;
301
+ _self->ob_type ->tp_free ( _self );
274
302
}
275
303
276
304
public:
@@ -295,14 +323,19 @@ namespace Py
295
323
return check ( ob.ptr () );
296
324
}
297
325
298
- PyObject *selfPtr ()
326
+ virtual PyObject *selfPtr ()
327
+ {
328
+ return reinterpret_cast <PyObject *>( m_class_instance );
329
+ }
330
+
331
+ virtual Object self ()
299
332
{
300
- return reinterpret_cast <PyObject *>( m_self );
333
+ return Object ( reinterpret_cast <PyObject *>( m_class_instance ) );
301
334
}
302
335
303
336
protected:
304
337
private:
305
- PythonClassInstance *m_self ;
338
+ PythonClassInstance *m_class_instance ;
306
339
307
340
private:
308
341
//
@@ -361,7 +394,7 @@ namespace Py
361
394
//
362
395
T *getCxxObject ( void )
363
396
{
364
- return static_cast < T *>( ptr () );
397
+ return dynamic_cast < T * >( getPythonExtensionBase ( ptr () ) );
365
398
}
366
399
};
367
400
} // Namespace Py
0 commit comments