55
66namespace Py
77{
8-
98// ================================================================================
109//
1110// Implementation of MethodTable
@@ -146,6 +145,8 @@ extern "C"
146145 static PyObject* str_handler (PyObject*);
147146 static long hash_handler (PyObject*);
148147 static PyObject* call_handler (PyObject*, PyObject*, PyObject*);
148+ static PyObject* iter_handler (PyObject*);
149+ static PyObject* iternext_handler (PyObject*);
149150
150151 // Sequence methods
151152 static int sequence_length_handler (PyObject*);
@@ -201,6 +202,7 @@ void PythonType::supportSequenceType()
201202 if ( !sequence_table )
202203 {
203204 sequence_table = new PySequenceMethods;
205+ memset ( sequence_table, 0 , sizeof ( PySequenceMethods ) ); // ensure new fields are 0
204206 table->tp_as_sequence = sequence_table;
205207 sequence_table->sq_length = sequence_length_handler;
206208 sequence_table->sq_concat = sequence_concat_handler;
@@ -218,6 +220,7 @@ void PythonType::supportMappingType()
218220 if ( !mapping_table )
219221 {
220222 mapping_table = new PyMappingMethods;
223+ memset ( mapping_table, 0 , sizeof ( PyMappingMethods ) ); // ensure new fields are 0
221224 table->tp_as_mapping = mapping_table;
222225 mapping_table->mp_length = mapping_length_handler;
223226 mapping_table->mp_subscript = mapping_subscript_handler;
@@ -230,6 +233,7 @@ void PythonType::supportNumberType()
230233 if ( !number_table )
231234 {
232235 number_table = new PyNumberMethods;
236+ memset ( number_table, 0 , sizeof ( PyNumberMethods ) ); // ensure new fields are 0
233237 table->tp_as_number = number_table;
234238 number_table->nb_add = number_add_handler;
235239 number_table->nb_subtract = number_subtract_handler;
@@ -262,6 +266,7 @@ void PythonType::supportBufferType()
262266 if ( !buffer_table )
263267 {
264268 buffer_table = new PyBufferProcs;
269+ memset ( buffer_table, 0 , sizeof ( PyBufferProcs ) ); // ensure new fields are 0
265270 table->tp_as_buffer = buffer_table;
266271 buffer_table->bf_getreadbuffer = buffer_getreadbuffer_handler;
267272 buffer_table->bf_getwritebuffer = buffer_getwritebuffer_handler;
@@ -279,6 +284,7 @@ PythonType::PythonType( size_t basic_size, int itemsize, const char *default_nam
279284 , number_table( NULL )
280285 , buffer_table( NULL )
281286 {
287+ memset ( table, 0 , sizeof ( PyTypeObject ) ); // ensure new fields are 0
282288 *reinterpret_cast <PyObject*>( table ) = py_object_initializer;
283289 table->ob_type = _Type_Type ();
284290 table->ob_size = 0 ;
@@ -300,7 +306,7 @@ PythonType::PythonType( size_t basic_size, int itemsize, const char *default_nam
300306 table->tp_getattro = 0 ;
301307 table->tp_setattro = 0 ;
302308 table->tp_as_buffer = 0 ;
303- table->tp_flags = 0L ;
309+ table->tp_flags = Py_TPFLAGS_DEFAULT ;
304310 table->tp_doc = 0 ;
305311#if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 0)
306312 // first use in 2.0
@@ -319,6 +325,12 @@ PythonType::PythonType( size_t basic_size, int itemsize, const char *default_nam
319325 table->tp_xxx8 = 0L ;
320326#endif
321327
328+ #if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 2)
329+ // first defined in 2.3
330+ table->tp_iter = 0L ;
331+ table->tp_iternext = 0L ;
332+ #endif
333+
322334#ifdef COUNT_ALLOCS
323335 table->tp_alloc = 0 ;
324336 table->tp_free = 0 ;
@@ -414,6 +426,12 @@ void PythonType::supportCall()
414426 table->tp_call = call_handler;
415427 }
416428
429+ void PythonType::supportIter ()
430+ {
431+ table->tp_iter = iter_handler;
432+ table->tp_iternext = iternext_handler;
433+ }
434+
417435// --------------------------------------------------------------------------------
418436//
419437// Handlers
@@ -553,6 +571,32 @@ extern "C" PyObject* call_handler( PyObject *self, PyObject *args, PyObject *kw
553571 }
554572 }
555573
574+ extern " C" PyObject* iter_handler ( PyObject *self )
575+ {
576+ try
577+ {
578+ PythonExtensionBase *p = static_cast <PythonExtensionBase *>( self );
579+ return new_reference_to ( p->iter () );
580+ }
581+ catch ( Py::Exception & )
582+ {
583+ return NULL ; // indicate error
584+ }
585+ }
586+
587+ extern " C" PyObject* iternext_handler ( PyObject *self )
588+ {
589+ try
590+ {
591+ PythonExtensionBase *p = static_cast <PythonExtensionBase *>( self );
592+ return p->iternext (); // might be a NULL ptr on end of iteration
593+ }
594+ catch ( Py::Exception & )
595+ {
596+ return NULL ; // indicate error
597+ }
598+ }
599+
556600
557601// Sequence methods
558602extern " C" int sequence_length_handler ( PyObject *self )
@@ -1028,11 +1072,7 @@ PythonExtensionBase::PythonExtensionBase()
10281072
10291073PythonExtensionBase::~PythonExtensionBase ()
10301074 {
1031- // JDH:
1032- // win32 appears to have a bug; when a class throws an
1033- // exception, the assert fails.
1034-
1035- // assert( ob_refcnt == 0 );
1075+ assert ( ob_refcnt == 0 );
10361076 }
10371077
10381078int PythonExtensionBase::print ( FILE *, int )
@@ -1062,6 +1102,12 @@ long PythonExtensionBase::hash()
10621102Py::Object PythonExtensionBase::call ( const Py::Object &, const Py::Object & )
10631103 { missing_method ( call ); return Py::Nothing (); }
10641104
1105+ Py::Object PythonExtensionBase::iter ()
1106+ { missing_method ( iter ); return Py::Nothing (); }
1107+
1108+ PyObject* PythonExtensionBase::iternext ()
1109+ { missing_method ( iternext ); return NULL ; }
1110+
10651111
10661112// Sequence methods
10671113int PythonExtensionBase::sequence_length ()
@@ -1272,6 +1318,15 @@ void ExtensionExceptionType::init( ExtensionModuleBase &module, const std::strin
12721318 set ( PyErr_NewException ( const_cast <char *>( module_name.c_str () ), NULL , NULL ), true );
12731319 }
12741320
1321+ void ExtensionExceptionType::init ( ExtensionModuleBase &module , const std::string& name, ExtensionExceptionType &parent)
1322+ {
1323+ std::string module_name ( module .fullName () );
1324+ module_name += " ." ;
1325+ module_name += name;
1326+
1327+ set ( PyErr_NewException ( const_cast <char *>( module_name.c_str () ), parent.ptr (), NULL ), true );
1328+ }
1329+
12751330ExtensionExceptionType::~ExtensionExceptionType ()
12761331 {
12771332 }
@@ -1281,5 +1336,14 @@ Exception::Exception( ExtensionExceptionType &exception, const std::string& reas
12811336 PyErr_SetString (exception.ptr (), reason.c_str ());
12821337 }
12831338
1339+ Exception::Exception ( ExtensionExceptionType &exception, Object &reason )
1340+ {
1341+ PyErr_SetObject (exception.ptr (), reason.ptr ());
1342+ }
1343+
1344+ Exception::Exception ( PyObject* exception, Object &reason )
1345+ {
1346+ PyErr_SetObject (exception, reason.ptr ());
1347+ }
12841348
12851349} // end of namespace Py
0 commit comments