Skip to content

Commit 0cee09d

Browse files
committed
Upgrade PyCXX to version 6.2.4 and pull in all of the changes from the matplotlib-py3 branch.
1 parent 8380feb commit 0cee09d

17 files changed

+782
-161
lines changed

CXX/Python2/Exception.hxx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,16 @@ namespace Py
163163
}
164164
};
165165

166+
class NotImplementedError: public StandardError
167+
{
168+
public:
169+
NotImplementedError (const std::string& reason)
170+
: StandardError()
171+
{
172+
PyErr_SetString (Py::_Exc_NotImplementedError(), reason.c_str());
173+
}
174+
};
175+
166176
class SystemError: public StandardError
167177
{
168178
public:

CXX/Python2/ExtensionOldType.hxx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ namespace Py
7474
return this;
7575
}
7676

77+
Object self()
78+
{
79+
return asObject( this );
80+
}
81+
7782
protected:
7883
explicit PythonExtension()
7984
: PythonExtensionBase()

CXX/Python2/ExtensionType.hxx

Lines changed: 66 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -45,44 +45,67 @@
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

84105
namespace 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

CXX/Python2/ExtensionTypeBase.hxx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,40 @@ namespace Py
131131
virtual Py_ssize_t buffer_getwritebuffer( Py_ssize_t, void** );
132132
virtual Py_ssize_t buffer_getsegcount( Py_ssize_t* );
133133

134+
public:
135+
// helper functions to call function fn_name with 0 to 9 args
136+
Object callOnSelf( const std::string &fn_name );
137+
Object callOnSelf( const std::string &fn_name,
138+
const Object &arg1 );
139+
Object callOnSelf( const std::string &fn_name,
140+
const Object &arg1, const Object &arg2 );
141+
Object callOnSelf( const std::string &fn_name,
142+
const Object &arg1, const Object &arg2, const Object &arg3 );
143+
Object callOnSelf( const std::string &fn_name,
144+
const Object &arg1, const Object &arg2, const Object &arg3,
145+
const Object &arg4 );
146+
Object callOnSelf( const std::string &fn_name,
147+
const Object &arg1, const Object &arg2, const Object &arg3,
148+
const Object &arg4, const Object &arg5 );
149+
Object callOnSelf( const std::string &fn_name,
150+
const Object &arg1, const Object &arg2, const Object &arg3,
151+
const Object &arg4, const Object &arg5, const Object &arg6 );
152+
Object callOnSelf( const std::string &fn_name,
153+
const Object &arg1, const Object &arg2, const Object &arg3,
154+
const Object &arg4, const Object &arg5, const Object &arg6,
155+
const Object &arg7 );
156+
Object callOnSelf( const std::string &fn_name,
157+
const Object &arg1, const Object &arg2, const Object &arg3,
158+
const Object &arg4, const Object &arg5, const Object &arg6,
159+
const Object &arg7, const Object &arg8 );
160+
Object callOnSelf( const std::string &fn_name,
161+
const Object &arg1, const Object &arg2, const Object &arg3,
162+
const Object &arg4, const Object &arg5, const Object &arg6,
163+
const Object &arg7, const Object &arg8, const Object &arg9 );
164+
134165
public:
135166
virtual PyObject *selfPtr() = 0;
167+
virtual Object self() = 0;
136168

137169
private:
138170
void missing_method( void );

0 commit comments

Comments
 (0)