|
From: <md...@us...> - 2009-01-07 18:09:51
|
Revision: 6760
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6760&view=rev
Author: mdboom
Date: 2009-01-07 18:09:46 +0000 (Wed, 07 Jan 2009)
Log Message:
-----------
Upgrade CXX to 5.4.2
Modified Paths:
--------------
trunk/matplotlib/CXX/Config.hxx
trunk/matplotlib/CXX/Extensions.hxx
trunk/matplotlib/CXX/IndirectPythonInterface.cxx
trunk/matplotlib/CXX/IndirectPythonInterface.hxx
trunk/matplotlib/CXX/Objects.hxx
trunk/matplotlib/CXX/Version.hxx
trunk/matplotlib/CXX/WrapPython.h
trunk/matplotlib/CXX/cxx_extensions.cxx
Modified: trunk/matplotlib/CXX/Config.hxx
===================================================================
--- trunk/matplotlib/CXX/Config.hxx 2009-01-07 16:16:18 UTC (rev 6759)
+++ trunk/matplotlib/CXX/Config.hxx 2009-01-07 18:09:46 UTC (rev 6760)
@@ -115,4 +115,20 @@
typedef int Py_ssize_t;
#endif
+// hash_map container usage selection
+// 1) if PYCXX_USING_STD_MAP is defined PyCXX will be using std::map<> container
+// implementation only.
+// 2) if compilers are used other than MS Visual Studio (7.1+) or GCC 3.x
+// STANDARD_LIBRARY_HAS_HASH_MAP must be defined before compilation to
+// make PyCXX using hash_map container.
+#if !defined( PYCXX_USING_STD_MAP )
+ #if defined( _MSC_VER ) || defined( __INTEL_COMPILER ) || defined ( __ICC ) || (defined( __GNUC__ ) && ( __GNUC__ > 3 ))
+ # define PYCXX_USING_HASH_MAP
+ #else
+ # if defined( STANDARD_LIBRARY_HAS_HASH_MAP ) && !defined( PYCXX_USING_HASH_MAP )
+ # define PYCXX_USING_HASH_MAP
+ # endif
+ #endif
+#endif
+
#endif // __PyCXX_config_hh__
Modified: trunk/matplotlib/CXX/Extensions.hxx
===================================================================
--- trunk/matplotlib/CXX/Extensions.hxx 2009-01-07 16:16:18 UTC (rev 6759)
+++ trunk/matplotlib/CXX/Extensions.hxx 2009-01-07 18:09:46 UTC (rev 6760)
@@ -56,12 +56,112 @@
}
#include <vector>
+
+// std::map / hash_map selection and declarations ----------------------------
+#if !defined( PYCXX_USING_HASH_MAP )
+
#include <map>
+#else
+
+#if defined( __GNUC__) && !defined( _STLPORT_VERSION )
+ #include <ext/hash_map>
+#else
+ #include <hash_map>
+#endif
+#if defined( _STLPORT_VERSION )
+ #define __PYCXX_HASHMAP_NAMESPACE std
+ using namespace std;
+#elif defined ( _MSC_VER ) && !defined( __INTEL_COMPILER ) && !defined( __ICC ) && !defined( __ICL ) && !defined( __ECC )
+ #define __PYCXX_HASHMAP_NAMESPACE stdext
+ using namespace stdext;
+#elif defined( __INTEL_COMPILER ) || defined( __ICC ) || defined( __ICL ) || defined( __ECC )
+ #define __PYCXX_HASHMAP_NAMESPACE stdext
+ using namespace stdext;
+#elif defined( __GNUC__ )
+ #define __PYCXX_HASHMAP_NAMESPACE __gnu_cxx
+ using namespace __gnu_cxx;
+#else
+ #define __PYCXX_HASHMAP_NAMESPACE std
+ using namespace std;
+#endif
+
+class __pycxx_str_hash_func
+{
+public:
+ enum
+ {
+ // parameters for hash table
+ bucket_size = 4, // 0 < bucket_size
+ min_buckets = 8 // min_buckets = 2 ^^ N, 0 < N
+ };
+
+ // http://www.azillionmonkeys.com/qed/hash.html
+ size_t operator()( const std::string &str ) const
+ {
+ const unsigned char * data = reinterpret_cast<const unsigned char *>( str.c_str() );
+ int len = (int)str.length();
+ unsigned int hash = len;
+ unsigned int tmp;
+ int rem;
+
+ if (len <= 0 || data == NULL)
+ return 0;
+
+ rem = len & 3;
+ len >>= 2;
+
+ /* Main loop */
+ for (;len > 0; len--)
+ {
+ hash += (data[1] << 8) | data[0];
+ tmp = (((data[3] << 8) | data[2]) << 11) ^ hash;
+ hash = (hash << 16) ^ tmp;
+ data += 2*sizeof (unsigned short);
+ hash += hash >> 11;
+ }
+
+ /* Handle end cases */
+ switch (rem)
+ {
+ case 3: hash += (data[1] << 8) | data[0];
+ hash ^= hash << 16;
+ hash ^= data[sizeof (unsigned short)] << 18;
+ hash += hash >> 11;
+ break;
+ case 2: hash += (data[1] << 8) | data[0];
+ hash ^= hash << 11;
+ hash += hash >> 17;
+ break;
+ case 1: hash += *data;
+ hash ^= hash << 10;
+ hash += hash >> 1;
+ }
+
+ /* Force "avalanching" of final 127 bits */
+ hash ^= hash << 3;
+ hash += hash >> 5;
+ hash ^= hash << 4;
+ hash += hash >> 17;
+ hash ^= hash << 25;
+ hash += hash >> 6;
+
+ return hash;
+ }
+
+ bool operator()(const std::string &str_1, const std::string &str_2) const
+ {
+ // test if str_1 ordered before str_2
+ return str_1 < str_2;
+ }
+};
+#endif // PYCXX_USING_HASH_MAP
+// ----------------------------------------------------------------------
+
namespace Py
{
class ExtensionModuleBase;
-
+
// Make an Exception Type for use in raising custom exceptions
class ExtensionExceptionType : public Object
{
@@ -74,44 +174,44 @@
void init( ExtensionModuleBase &module, const std::string& name );
};
-
- class MethodTable
+
+ class MethodTable
{
public:
MethodTable();
virtual ~MethodTable();
-
+
void add(const char* method_name, PyCFunction f, const char* doc="", int flag=1);
PyMethodDef* table();
-
+
protected:
std::vector<PyMethodDef> t; // accumulator of PyMethodDef's
PyMethodDef *mt; // Actual method table produced when full
-
+
static PyMethodDef method (const char* method_name, PyCFunction f, int flags = 1, const char* doc="");
-
+
private:
//
// prevent the compiler generating these unwanted functions
//
MethodTable(const MethodTable& m); //unimplemented
void operator=(const MethodTable& m); //unimplemented
-
+
}; // end class MethodTable
-
+
extern "C"
{
typedef PyObject *(*method_varargs_call_handler_t)( PyObject *_self, PyObject *_args );
typedef PyObject *(*method_keyword_call_handler_t)( PyObject *_self, PyObject *_args, PyObject *_dict );
};
-
+
template<class T>
class MethodDefExt : public PyMethodDef
{
public:
typedef Object (T::*method_varargs_function_t)( const Tuple &args );
typedef Object (T::*method_keyword_function_t)( const Tuple &args, const Dict &kws );
-
+
MethodDefExt
(
const char *_name,
@@ -124,11 +224,11 @@
ext_meth_def.ml_meth = _handler;
ext_meth_def.ml_flags = METH_VARARGS;
ext_meth_def.ml_doc = const_cast<char *>(_doc);
-
+
ext_varargs_function = _function;
ext_keyword_function = NULL;
}
-
+
MethodDefExt
(
const char *_name,
@@ -141,57 +241,57 @@
ext_meth_def.ml_meth = method_varargs_call_handler_t( _handler );
ext_meth_def.ml_flags = METH_VARARGS|METH_KEYWORDS;
ext_meth_def.ml_doc = const_cast<char *>(_doc);
-
+
ext_varargs_function = NULL;
ext_keyword_function = _function;
}
-
+
~MethodDefExt()
{}
-
+
PyMethodDef ext_meth_def;
- method_varargs_function_t ext_varargs_function;
- method_keyword_function_t ext_keyword_function;
+ method_varargs_function_t ext_varargs_function;
+ method_keyword_function_t ext_keyword_function;
};
-
+
class ExtensionModuleBase
{
public:
ExtensionModuleBase( const char *name );
virtual ~ExtensionModuleBase();
-
+
Module module(void) const; // only valid after initialize() has been called
Dict moduleDictionary(void) const; // only valid after initialize() has been called
-
+
virtual Object invoke_method_keyword( const std::string &_name, const Tuple &_args, const Dict &_keywords ) = 0;
virtual Object invoke_method_varargs( const std::string &_name, const Tuple &_args ) = 0;
-
+
const std::string &name() const;
const std::string &fullName() const;
-
+
protected:
// Initialize the module
void initialize( const char *module_doc );
-
+
const std::string module_name;
const std::string full_module_name;
MethodTable method_table;
-
+
private:
-
+
//
// prevent the compiler generating these unwanted functions
//
ExtensionModuleBase( const ExtensionModuleBase & ); //unimplemented
void operator=( const ExtensionModuleBase & ); //unimplemented
-
+
};
-
+
extern "C" PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple, PyObject *_args, PyObject *_keywords );
extern "C" PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple, PyObject *_args );
extern "C" void do_not_dealloc( void * );
-
-
+
+
template<TEMPLATE_TYPENAME T>
class ExtensionModule : public ExtensionModuleBase
{
@@ -201,16 +301,21 @@
{}
virtual ~ExtensionModule()
{}
-
+
protected:
typedef Object (T::*method_varargs_function_t)( const Tuple &args );
typedef Object (T::*method_keyword_function_t)( const Tuple &args, const Dict &kws );
+
+#if defined( PYCXX_USING_HASH_MAP )
+ typedef __PYCXX_HASHMAP_NAMESPACE::hash_map<std::string, MethodDefExt<T> *, __pycxx_str_hash_func> method_map_t;
+#else
typedef std::map<std::string,MethodDefExt<T> *> method_map_t;
-
+#endif
+
static void add_varargs_method( const char *name, method_varargs_function_t function, const char *doc="" )
{
method_map_t &mm = methods();
-
+
MethodDefExt<T> *method_definition = new MethodDefExt<T>
(
name,
@@ -218,14 +323,14 @@
method_varargs_call_handler,
doc
);
-
+
mm[std::string( name )] = method_definition;
}
-
+
static void add_keyword_method( const char *name, method_keyword_function_t function, const char *doc="" )
{
method_map_t &mm = methods();
-
+
MethodDefExt<T> *method_definition = new MethodDefExt<T>
(
name,
@@ -233,7 +338,7 @@
method_keyword_call_handler,
doc
);
-
+
mm[std::string( name )] = method_definition;
}
@@ -241,46 +346,46 @@
{
ExtensionModuleBase::initialize( module_doc );
Dict dict( moduleDictionary() );
-
+
//
// put each of the methods into the modules dictionary
// so that we get called back at the function in T.
//
method_map_t &mm = methods();
- EXPLICIT_TYPENAME method_map_t::iterator i;
-
+ EXPLICIT_TYPENAME method_map_t::const_iterator i;
+
for( i=mm.begin(); i != mm.end(); ++i )
{
MethodDefExt<T> *method_definition = (*i).second;
-
+
static PyObject *self = PyCObject_FromVoidPtr( this, do_not_dealloc );
-
+
Tuple args( 2 );
args[0] = Object( self );
args[1] = String( (*i).first );
-
+
PyObject *func = PyCFunction_New
(
&method_definition->ext_meth_def,
new_reference_to( args )
);
-
+
dict[ (*i).first ] = Object( func );
}
}
-
+
protected: // Tom Malcolmson reports that derived classes need access to these
-
+
static method_map_t &methods(void)
{
static method_map_t *map_of_methods = NULL;
if( map_of_methods == NULL )
map_of_methods = new method_map_t;
-
+
return *map_of_methods;
}
-
-
+
+
// this invoke function must be called from within a try catch block
virtual Object invoke_method_keyword( const std::string &name, const Tuple &args, const Dict &keywords )
{
@@ -292,13 +397,13 @@
error_msg += name;
throw RuntimeError( error_msg );
}
-
+
// cast up to the derived class
T *self = static_cast<T *>(this);
-
+
return (self->*meth_def->ext_keyword_function)( args, keywords );
}
-
+
// this invoke function must be called from within a try catch block
virtual Object invoke_method_varargs( const std::string &name, const Tuple &args )
{
@@ -310,13 +415,13 @@
error_msg += name;
throw RuntimeError( error_msg );
}
-
+
// cast up to the derived class
T *self = static_cast<T *>(this);
-
+
return (self->*meth_def->ext_varargs_function)( args );
}
-
+
private:
//
// prevent the compiler generating these unwanted functions
@@ -324,17 +429,17 @@
ExtensionModule( const ExtensionModule<T> & ); //unimplemented
void operator=( const ExtensionModule<T> & ); //unimplemented
};
-
-
+
+
class PythonType
{
public:
- // if you define one sequence method you must define
+ // if you define one sequence method you must define
// all of them except the assigns
-
+
PythonType (size_t base_size, int itemsize, const char *default_name );
virtual ~PythonType ();
-
+
const char *getName () const;
const char *getDoc () const;
@@ -342,73 +447,76 @@
PythonType & name (const char* nam);
PythonType & doc (const char* d);
PythonType & dealloc(void (*f)(PyObject*));
-
+
PythonType & supportPrint(void);
PythonType & supportGetattr(void);
PythonType & supportSetattr(void);
PythonType & supportGetattro(void);
PythonType & supportSetattro(void);
PythonType & supportCompare(void);
+#if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 1)
+ PythonType & supportRichCompare(void);
+#endif
PythonType & supportRepr(void);
PythonType & supportStr(void);
PythonType & supportHash(void);
PythonType & supportCall(void);
PythonType & supportIter(void);
-
+
PythonType & supportSequenceType(void);
PythonType & supportMappingType(void);
PythonType & supportNumberType(void);
PythonType & supportBufferType(void);
-
+
protected:
PyTypeObject *table;
PySequenceMethods *sequence_table;
PyMappingMethods *mapping_table;
PyNumberMethods *number_table;
PyBufferProcs *buffer_table;
-
+
void init_sequence();
void init_mapping();
void init_number();
void init_buffer();
-
+
private:
//
// prevent the compiler generating these unwanted functions
//
PythonType (const PythonType& tb); // unimplemented
void operator=(const PythonType& t); // unimplemented
-
+
}; // end of PythonType
-
-
-
+
+
+
// Class PythonExtension is what you inherit from to create
// a new Python extension type. You give your class itself
// as the template paramter.
-
+
// There are two ways that extension objects can get destroyed.
// 1. Their reference count goes to zero
// 2. Someone does an explicit delete on a pointer.
- // In (1) the problem is to get the destructor called
+ // In (1) the problem is to get the destructor called
// We register a special deallocator in the Python type object
// (see behaviors()) to do this.
// In (2) there is no problem, the dtor gets called.
-
- // PythonExtension does not use the usual Python heap allocator,
+
+ // PythonExtension does not use the usual Python heap allocator,
// instead using new/delete. We do the setting of the type object
- // and reference count, usually done by PyObject_New, in the
+ // and reference count, usually done by PyObject_New, in the
// base class ctor.
-
+
// This special deallocator does a delete on the pointer.
-
-
+
+
class PythonExtensionBase : public PyObject
{
public:
PythonExtensionBase();
virtual ~PythonExtensionBase();
-
+
public:
virtual int print( FILE *, int );
virtual Object getattr( const char * ) = 0;
@@ -416,13 +524,14 @@
virtual Object getattro( const Object & );
virtual int setattro( const Object &, const Object & );
virtual int compare( const Object & );
+ virtual Object rich_compare( const Object &, int op );
virtual Object repr();
virtual Object str();
virtual long hash();
virtual Object call( const Object &, const Object & );
virtual Object iter();
virtual PyObject* iternext();
-
+
// Sequence methods
virtual int sequence_length();
virtual Object sequence_concat( const Object & );
@@ -431,12 +540,12 @@
virtual Object sequence_slice( Py_ssize_t, Py_ssize_t );
virtual int sequence_ass_item( Py_ssize_t, const Object & );
virtual int sequence_ass_slice( Py_ssize_t, Py_ssize_t, const Object & );
-
+
// Mapping
virtual int mapping_length();
virtual Object mapping_subscript( const Object & );
virtual int mapping_ass_subscript( const Object &, const Object & );
-
+
// Number
virtual int number_nonzero();
virtual Object number_negative();
@@ -460,38 +569,38 @@
virtual Object number_xor( const Object & );
virtual Object number_or( const Object & );
virtual Object number_power( const Object &, const Object & );
-
+
// Buffer
virtual Py_ssize_t buffer_getreadbuffer( Py_ssize_t, void** );
virtual Py_ssize_t buffer_getwritebuffer( Py_ssize_t, void** );
virtual Py_ssize_t buffer_getsegcount( Py_ssize_t* );
-
+
private:
void missing_method( void );
static PyObject *method_call_handler( PyObject *self, PyObject *args );
};
-
+
template<TEMPLATE_TYPENAME T>
- class PythonExtension: public PythonExtensionBase
+ class PythonExtension: public PythonExtensionBase
{
public:
- static PyTypeObject* type_object()
+ static PyTypeObject* type_object()
{
return behaviors().type_object();
}
-
+
static int check( PyObject *p )
{
// is p like me?
return p->ob_type == type_object();
}
-
+
static int check( const Object& ob )
{
return check( ob.ptr());
}
-
-
+
+
//
// every object needs getattr implemented
// to support methods
@@ -500,7 +609,7 @@
{
return getattr_methods( name );
}
-
+
protected:
explicit PythonExtension()
: PythonExtensionBase()
@@ -511,18 +620,18 @@
ob_refcnt = 1;
ob_type = type_object();
#endif
-
+
// every object must support getattr
behaviors().supportGetattr();
}
-
+
virtual ~PythonExtension()
- {}
-
+ {}
+
static PythonType &behaviors()
{
static PythonType* p;
- if( p == NULL )
+ if( p == NULL )
{
#if defined( _CPPRTTI ) || defined(__GNUG__)
const char *default_name = (typeid ( T )).name();
@@ -532,15 +641,20 @@
p = new PythonType( sizeof( T ), 0, default_name );
p->dealloc( extension_object_deallocator );
}
-
+
return *p;
}
-
-
+
+
typedef Object (T::*method_varargs_function_t)( const Tuple &args );
typedef Object (T::*method_keyword_function_t)( const Tuple &args, const Dict &kws );
+
+#if defined( PYCXX_USING_HASH_MAP )
+ typedef __PYCXX_HASHMAP_NAMESPACE::hash_map<std::string, MethodDefExt<T> *, __pycxx_str_hash_func> method_map_t;
+#else
typedef std::map<std::string,MethodDefExt<T> *> method_map_t;
-
+#endif
+
// support the default attributes, __name__, __doc__ and methods
virtual Object getattr_default( const char *_name )
{
@@ -576,39 +690,48 @@
virtual Object getattr_methods( const char *_name )
{
std::string name( _name );
-
+
method_map_t &mm = methods();
-
+
+ EXPLICIT_TYPENAME method_map_t::const_iterator i;
+
if( name == "__methods__" )
{
List methods;
-
- for( EXPLICIT_TYPENAME method_map_t::iterator i = mm.begin(); i != mm.end(); ++i )
+
+ for( i = mm.begin(); i != mm.end(); ++i )
methods.append( String( (*i).first ) );
-
+
return methods;
}
-
- // see if name exists
- if( mm.find( name ) == mm.end() )
+
+ // see if name exists and get entry with method
+ i = mm.find( name );
+ if( i == mm.end() )
throw AttributeError( name );
-
+
Tuple self( 2 );
-
+
self[0] = Object( this );
self[1] = String( name );
-
- MethodDefExt<T> *method_definition = mm[ name ];
-
+
+ MethodDefExt<T> *method_definition = i->second;
+
PyObject *func = PyCFunction_New( &method_definition->ext_meth_def, self.ptr() );
-
+
return Object(func, true);
}
-
+
static void add_varargs_method( const char *name, method_varargs_function_t function, const char *doc="" )
{
method_map_t &mm = methods();
-
+
+ // check that all methods added are unique
+ EXPLICIT_TYPENAME method_map_t::const_iterator i;
+ i = mm.find( name );
+ if( i != mm.end() )
+ throw AttributeError( name );
+
MethodDefExt<T> *method_definition = new MethodDefExt<T>
(
name,
@@ -616,14 +739,20 @@
method_varargs_call_handler,
doc
);
-
+
mm[std::string( name )] = method_definition;
}
-
+
static void add_keyword_method( const char *name, method_keyword_function_t function, const char *doc="" )
{
method_map_t &mm = methods();
-
+
+ // check that all methods added are unique
+ EXPLICIT_TYPENAME method_map_t::const_iterator i;
+ i = mm.find( name );
+ if( i != mm.end() )
+ throw AttributeError( name );
+
MethodDefExt<T> *method_definition = new MethodDefExt<T>
(
name,
@@ -631,45 +760,49 @@
method_keyword_call_handler,
doc
);
-
+
mm[std::string( name )] = method_definition;
}
-
+
private:
static method_map_t &methods(void)
{
static method_map_t *map_of_methods = NULL;
if( map_of_methods == NULL )
map_of_methods = new method_map_t;
-
+
return *map_of_methods;
}
-
+
static PyObject *method_keyword_call_handler( PyObject *_self_and_name_tuple, PyObject *_args, PyObject *_keywords )
{
try
{
Tuple self_and_name_tuple( _self_and_name_tuple );
-
+
PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
T *self = static_cast<T *>( self_in_cobject );
-
+
String name( self_and_name_tuple[1] );
-
+
method_map_t &mm = methods();
- MethodDefExt<T> *meth_def = mm[ name ];
- if( meth_def == NULL )
+
+ EXPLICIT_TYPENAME method_map_t::const_iterator i;
+ i = mm.find( name );
+ if( i == mm.end() )
return 0;
-
+
+ MethodDefExt<T> *meth_def = i->second;
+
Tuple args( _args );
// _keywords may be NULL so be careful about the way the dict is created
Dict keywords;
if( _keywords != NULL )
keywords = Dict( _keywords );
-
+
Object result( (self->*meth_def->ext_keyword_function)( args, keywords ) );
-
+
return new_reference_to( result.ptr() );
}
catch( Exception & )
@@ -677,27 +810,31 @@
return 0;
}
}
-
+
static PyObject *method_varargs_call_handler( PyObject *_self_and_name_tuple, PyObject *_args )
{
try
{
Tuple self_and_name_tuple( _self_and_name_tuple );
-
+
PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
T *self = static_cast<T *>( self_in_cobject );
-
+
String name( self_and_name_tuple[1] );
-
+
method_map_t &mm = methods();
- MethodDefExt<T> *meth_def = mm[ name ];
- if( meth_def == NULL )
+
+ EXPLICIT_TYPENAME method_map_t::const_iterator i;
+ i = mm.find( name );
+ if( i == mm.end() )
return 0;
-
+
+ MethodDefExt<T> *meth_def = i->second;
+
Tuple args( _args );
-
+
Object result;
-
+
// TMM: 7Jun'01 - Adding try & catch in case of STL debug-mode exceptions.
#ifdef _STLP_DEBUG
try
@@ -712,7 +849,7 @@
#else
result = (self->*meth_def->ext_varargs_function)( args );
#endif // _STLP_DEBUG
-
+
return new_reference_to( result.ptr() );
}
catch( Exception & )
@@ -720,19 +857,19 @@
return 0;
}
}
-
+
static void extension_object_deallocator ( PyObject* t )
{
delete (T *)( t );
}
-
+
//
// prevent the compiler generating these unwanted functions
//
explicit PythonExtension( const PythonExtension<T>& other );
void operator=( const PythonExtension<T>& rhs );
};
-
+
//
// ExtensionObject<T> is an Object that will accept only T's.
//
@@ -740,30 +877,30 @@
class ExtensionObject: public Object
{
public:
-
+
explicit ExtensionObject ( PyObject *pyob )
: Object( pyob )
{
validate();
}
-
+
ExtensionObject( const ExtensionObject<T>& other )
: Object( *other )
{
validate();
}
-
+
ExtensionObject( const Object& other )
: Object( *other )
{
validate();
}
-
+
ExtensionObject& operator= ( const Object& rhs )
{
return (*this = *rhs );
}
-
+
ExtensionObject& operator= ( PyObject* rhsp )
{
if( ptr() == rhsp )
@@ -771,12 +908,12 @@
set( rhsp );
return *this;
}
-
+
virtual bool accepts ( PyObject *pyob ) const
{
return ( pyob && T::check( pyob ));
- }
-
+ }
+
//
// Obtain a pointer to the PythonExtension object
//
@@ -785,7 +922,7 @@
return static_cast<T *>( ptr() );
}
};
-
+
} // Namespace Py
// End of CXX_Extensions.h
#endif
Modified: trunk/matplotlib/CXX/IndirectPythonInterface.cxx
===================================================================
--- trunk/matplotlib/CXX/IndirectPythonInterface.cxx 2009-01-07 16:16:18 UTC (rev 6759)
+++ trunk/matplotlib/CXX/IndirectPythonInterface.cxx 2009-01-07 18:09:46 UTC (rev 6760)
@@ -49,6 +49,7 @@
bool _Float_Check( PyObject *op ) { return (op)->ob_type == _Float_Type(); }
bool _Function_Check( PyObject *op ) { return (op)->ob_type == _Function_Type(); }
bool _Instance_Check( PyObject *op ) { return (op)->ob_type == _Instance_Type(); }
+bool _Boolean_Check( PyObject *op ) { return (op)->ob_type == _Bool_Type(); }
bool _Int_Check( PyObject *op ) { return (op)->ob_type == _Int_Type(); }
bool _List_Check( PyObject *o ) { return o->ob_type == _List_Type(); }
bool _Long_Check( PyObject *op ) { return (op)->ob_type == _Long_Type(); }
@@ -116,6 +117,9 @@
static PyObject *ptr__PyNone = NULL;
+static PyObject *ptr__PyFalse = NULL;
+static PyObject *ptr__PyTrue = NULL;
+
static PyTypeObject *ptr__Buffer_Type = NULL;
static PyTypeObject *ptr__CFunction_Type = NULL;
static PyTypeObject *ptr__Class_Type = NULL;
@@ -300,6 +304,9 @@
#endif
ptr__PyNone = GetPyObject_As_PyObjectPointer( "_Py_NoneStruct" );
+ ptr__PyFalse = GetPyObject_As_PyObjectPointer( "_Py_ZeroStruct" );
+ ptr__PyTrue = GetPyObject_As_PyObjectPointer( "_Py_TrueStruct" );
+
ptr__Buffer_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyBuffer_Type" );
ptr__CFunction_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyCFunction_Type" );
ptr__Class_Type = GetPyTypeObject_As_PyTypeObjectPointer( "PyClass_Type" );
@@ -385,6 +392,8 @@
//
PyObject * _None() { return ptr__PyNone; }
+PyObject * _False() { return ptr__PyFalse; }
+PyObject * _True() { return ptr__PyTrue; }
PyTypeObject * _Buffer_Type() { return ptr__Buffer_Type; }
PyTypeObject * _CFunction_Type(){ return ptr__CFunction_Type; }
@@ -396,6 +405,7 @@
PyTypeObject * _Float_Type() { return ptr__Float_Type; }
PyTypeObject * _Function_Type() { return ptr__Function_Type; }
PyTypeObject * _Instance_Type() { return ptr__Instance_Type; }
+PyTypeObject * _Bool_Type() { return ptr__Bool_Type; }
PyTypeObject * _Int_Type() { return ptr__Int_Type; }
PyTypeObject * _List_Type() { return ptr__List_Type; }
PyTypeObject * _Long_Type() { return ptr__Long_Type; }
@@ -526,6 +536,9 @@
//
PyObject * _None() { return &::_Py_NoneStruct; }
+PyObject * _False() { return Py_False; }
+PyObject * _True() { return Py_True; }
+
PyTypeObject * _Buffer_Type() { return &PyBuffer_Type; }
PyTypeObject * _CFunction_Type() { return &PyCFunction_Type; }
PyTypeObject * _Class_Type() { return &PyClass_Type; }
@@ -536,6 +549,7 @@
PyTypeObject * _Float_Type() { return &PyFloat_Type; }
PyTypeObject * _Function_Type() { return &PyFunction_Type; }
PyTypeObject * _Instance_Type() { return &PyInstance_Type; }
+PyTypeObject * _Bool_Type() { return &PyBool_Type; }
PyTypeObject * _Int_Type() { return &PyInt_Type; }
PyTypeObject * _List_Type() { return &PyList_Type; }
PyTypeObject * _Long_Type() { return &PyLong_Type; }
Modified: trunk/matplotlib/CXX/IndirectPythonInterface.hxx
===================================================================
--- trunk/matplotlib/CXX/IndirectPythonInterface.hxx 2009-01-07 16:16:18 UTC (rev 6759)
+++ trunk/matplotlib/CXX/IndirectPythonInterface.hxx 2009-01-07 18:09:46 UTC (rev 6760)
@@ -92,6 +92,8 @@
//
PyObject * _None();
+PyObject * _False();
+PyObject * _True();
//
// Wrap Type variables as function calls
@@ -132,6 +134,9 @@
PyTypeObject * _Function_Type();
bool _Function_Check( PyObject *op );
+PyTypeObject * _Bool_Type();
+bool _Boolean_Check( PyObject *op );
+
PyTypeObject * _Int_Type();
bool _Int_Check( PyObject *op );
Modified: trunk/matplotlib/CXX/Objects.hxx
===================================================================
--- trunk/matplotlib/CXX/Objects.hxx 2009-01-07 16:16:18 UTC (rev 6759)
+++ trunk/matplotlib/CXX/Objects.hxx 2009-01-07 18:09:46 UTC (rev 6760)
@@ -168,26 +168,7 @@
p = 0;
}
- void validate()
- {
- // release pointer if not the right type
- if (! accepts (p))
- {
- release ();
- if(PyErr_Occurred())
- { // Error message already set
- throw Exception();
- }
- // Better error message if RTTI available
-#if defined( _CPPRTTI ) || defined(__GNUG__)
- std::string s("CXX : Error creating object of type ");
- s += (typeid (*this)).name();
- throw TypeError (s);
-#else
- throw TypeError ("CXX: type error.");
-#endif
- }
- }
+ void validate();
public:
// Constructor acquires new ownership of pointer unless explicitly told not to.
@@ -315,7 +296,7 @@
bool isNone() const
{
- return p == Py_None;
+ return p == _None();
}
bool isCallable () const
@@ -397,18 +378,19 @@
// failed to link on Windows?
throw KeyError("delItem failed.");
}
- // Equality and comparison use PyObject_Compare
+ // Equality and comparison use PyObject_RichCompareBool
+
bool operator==(const Object& o2) const
{
- int k = PyObject_Compare (p, *o2);
+ int k = PyObject_RichCompareBool (p, *o2, Py_EQ);
if (PyErr_Occurred()) throw Exception();
- return k == 0;
+ return k != 0;
}
bool operator!=(const Object& o2) const
{
- int k = PyObject_Compare (p, *o2);
+ int k = PyObject_RichCompareBool (p, *o2, Py_NE);
if (PyErr_Occurred()) throw Exception();
return k != 0;
@@ -416,30 +398,30 @@
bool operator>=(const Object& o2) const
{
- int k = PyObject_Compare (p, *o2);
+ int k = PyObject_RichCompareBool (p, *o2, Py_GE);
if (PyErr_Occurred()) throw Exception();
- return k >= 0;
+ return k != 0;
}
bool operator<=(const Object& o2) const
{
- int k = PyObject_Compare (p, *o2);
+ int k = PyObject_RichCompareBool (p, *o2, Py_LE);
if (PyErr_Occurred()) throw Exception();
- return k <= 0;
+ return k != 0;
}
bool operator<(const Object& o2) const
{
- int k = PyObject_Compare (p, *o2);
+ int k = PyObject_RichCompareBool (p, *o2, Py_LT);
if (PyErr_Occurred()) throw Exception();
- return k < 0;
+ return k != 0;
}
bool operator>(const Object& o2) const
{
- int k = PyObject_Compare (p, *o2);
+ int k = PyObject_RichCompareBool (p, *o2, Py_GT);
if (PyErr_Occurred()) throw Exception();
- return k > 0;
+ return k != 0;
}
};
// End of class Object
@@ -463,6 +445,17 @@
return Object(Py::_None());
}
+ // Python special Boolean values
+ inline Object False()
+ {
+ return Object(Py::_False());
+ }
+
+ inline Object True()
+ {
+ return Object(Py::_True());
+ }
+
// TMM: 31May'01 - Added the #ifndef so I can exlude iostreams.
#ifndef CXX_NO_IOSTREAMS
std::ostream& operator<< (std::ostream& os, const Object& ob);
@@ -513,9 +506,68 @@
return Object(p, true);
}
+ // ===============================================
+ // class boolean
+ class Boolean: public Object
+ {
+ public:
+ // Constructor
+ Boolean (PyObject *pyob, bool owned = false): Object (pyob, owned)
+ {
+ validate();
+ }
+ Boolean (const Boolean& ob): Object(*ob)
+ {
+ validate();
+ }
+ // create from bool
+ Boolean (bool v=false)
+ {
+ set(PyBool_FromLong(v ? 1 : 0), true);
+ validate();
+ }
+ explicit Boolean (const Object& ob)
+ {
+ set(*ob, true);
+ validate();
+ }
+
+ // Assignment acquires new ownership of pointer
+
+ Boolean& operator= (const Object& rhs)
+ {
+ return (*this = *rhs);
+ }
+
+ Boolean& operator= (PyObject* rhsp)
+ {
+ if(ptr() == rhsp) return *this;
+ set (rhsp, true);
+ return *this;
+ }
+
+ // Membership
+ virtual bool accepts (PyObject *pyob) const
+ {
+ return pyob && Py::_Boolean_Check (pyob);
+ }
+
+ // convert to long
+ operator bool() const
+ {
+ return PyObject_IsTrue (ptr()) != 0;
+ }
+
+ Boolean& operator= (bool v)
+ {
+ set (PyBool_FromLong (v ? 1 : 0), true);
+ return *this;
+ }
+ };
+
// ===============================================
// class Int
class Int: public Object
@@ -538,19 +590,6 @@
validate();
}
-#ifdef HAVE_LONG_LONG
- // create from long long
- Int (PY_LONG_LONG v): Object(PyLong_FromLongLong(v), true)
- {
- validate();
- }
- // create from unsigned long long
- Int (unsigned PY_LONG_LONG v): Object(PyLong_FromUnsignedLongLong(v), true)
- {
- validate();
- }
-#endif
-
// create from int
Int (int v)
{
@@ -753,13 +792,13 @@
validate();
}
// create from long long
- explicit LongLong (long long v = 0L)
+ explicit LongLong (PY_LONG_LONG v = 0L)
: Object(PyLong_FromLongLong(v), true)
{
validate();
}
// create from unsigned long long
- explicit LongLong (unsigned long long v)
+ explicit LongLong (unsigned PY_LONG_LONG v)
: Object(PyLong_FromUnsignedLongLong(v), true)
{
validate();
@@ -778,7 +817,7 @@
}
// create from int
explicit LongLong (int v)
- : Object(PyLong_FromLongLong(static_cast<long long>(v)), true)
+ : Object(PyLong_FromLongLong(static_cast<PY_LONG_LONG>(v)), true)
{
validate();
}
@@ -809,12 +848,12 @@
return pyob && Py::_Long_Check (pyob);
}
// convert to long long
- operator long long() const
+ operator PY_LONG_LONG() const
{
return PyLong_AsLongLong (ptr());
}
// convert to unsigned long
- operator unsigned long long() const
+ operator unsigned PY_LONG_LONG() const
{
return PyLong_AsUnsignedLongLong (ptr());
}
@@ -839,13 +878,13 @@
return *this;
}
// assign from long long
- LongLong& operator= (long long v)
+ LongLong& operator= (PY_LONG_LONG v)
{
set(PyLong_FromLongLong (v), true);
return *this;
}
// assign from unsigned long long
- LongLong& operator= (unsigned long long v)
+ LongLong& operator= (unsigned PY_LONG_LONG v)
{
set(PyLong_FromUnsignedLongLong (v), true);
return *this;
@@ -1413,12 +1452,12 @@
bool eql (const iterator& other) const
{
- return (*seq == *other.seq) && (count == other.count);
+ return (seq->ptr() == other.seq->ptr()) && (count == other.count);
}
bool neq (const iterator& other) const
{
- return (*seq != *other.seq) || (count != other.count);
+ return (seq->ptr() != other.seq->ptr()) || (count != other.count);
}
bool lss (const iterator& other) const
@@ -1527,6 +1566,12 @@
const SeqBase<T>* seq;
sequence_index_type count;
+ private:
+ const_iterator (const SeqBase<T>* s, int where)
+ : seq( s )
+ , count( where )
+ {}
+
public:
~const_iterator ()
{}
@@ -1536,11 +1581,6 @@
, count( 0 )
{}
- const_iterator (const SeqBase<T>* s, int where)
- : seq( s )
- , count( where )
- {}
-
const_iterator(const const_iterator& other)
: seq( other.seq )
, count( other.count )
@@ -1571,12 +1611,12 @@
bool eql (const const_iterator& other) const
{
- return (*seq == *other.seq) && (count == other.count);
+ return (seq->ptr() == other.seq->ptr()) && (count == other.count);
}
bool neq (const const_iterator& other) const
{
- return (*seq != *other.seq) || (count != other.count);
+ return (seq->ptr() != other.seq->ptr()) || (count != other.count);
}
bool lss (const const_iterator& other) const
@@ -1662,7 +1702,7 @@
template <TEMPLATE_TYPENAME T> bool operator< (const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
template <TEMPLATE_TYPENAME T> bool operator> (const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
template <TEMPLATE_TYPENAME T> bool operator<=(const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
- template <TEMPLATE_TYPENAME T> bool operator>=(const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
+ template <TEMPLATE_TYPENAME T> bool operator>=(const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
extern bool operator==(const Sequence::iterator& left, const Sequence::iterator& right);
@@ -1677,7 +1717,7 @@
extern bool operator< (const Sequence::const_iterator& left, const Sequence::const_iterator& right);
extern bool operator> (const Sequence::const_iterator& left, const Sequence::const_iterator& right);
extern bool operator<=(const Sequence::const_iterator& left, const Sequence::const_iterator& right);
- extern bool operator>=(const Sequence::const_iterator& left, const Sequence::const_iterator& right);
+ extern bool operator>=(const Sequence::const_iterator& left, const Sequence::const_iterator& right);
// ==================================================
// class Char
@@ -1979,7 +2019,7 @@
set(PyTuple_New (limit), true);
validate();
-
+
for(sequence_index_type i=0; i < limit; i++)
{
if(PyTuple_SetItem (ptr(), i, new_reference_to(s[i])) == -1)
@@ -2476,39 +2516,6 @@
return List(PyMapping_Items(ptr()), true);
}
- // iterators for MapBase<T>
- // Added by TMM: 2Jul'01 - NOT COMPLETED
- // There is still a bug. I decided to stop, before fixing the bug, because
- // this can't be halfway efficient until Python gets built-in iterators.
- // My current soln is to iterate over the map by getting a copy of its keys
- // and iterating over that. Not a good solution.
-
- // The iterator holds a MapBase<T>* rather than a MapBase<T> because that's
- // how the sequence iterator is implemented and it works. But it does seem
- // odd to me - we are iterating over the map object, not the reference.
-
-#if 0 // here is the test code with which I found the (still existing) bug
- typedef cxx::Dict d_t;
- d_t d;
- cxx::String s1("blah");
- cxx::String s2("gorf");
- d[ "one" ] = s1;
- d[ "two" ] = s1;
- d[ "three" ] = s2;
- d[ "four" ] = s2;
-
- d_t::iterator it;
- it = d.begin(); // this (using the assignment operator) is causing
- // a problem; if I just use the copy ctor it works fine.
- for( ; it != d.end(); ++it )
- {
- d_t::value_type vt( *it );
- cxx::String rs = vt.second.repr();
- std::string ls = rs.operator std::string();
- fprintf( stderr, "%s\n", ls );
- }
-#endif // 0
-
class iterator
{
// : public forward_iterator_parent( std::pair<const T,T> ) {
@@ -2523,8 +2530,15 @@
//
MapBase<T>* map;
List keys; // for iterating over the map
- List::iterator pos; // index into the keys
+ int pos; // index into the keys
+ private:
+ iterator( MapBase<T>* m, List k, int p )
+ : map( m )
+ , keys( k )
+ , pos( p )
+ {}
+
public:
~iterator ()
{}
@@ -2538,7 +2552,7 @@
iterator (MapBase<T>* m, bool end = false )
: map( m )
, keys( m->keys() )
- , pos( end ? keys.end() : keys.begin() )
+ , pos( end ? keys.length() : 0 )
{}
iterator (const iterator& other)
@@ -2549,7 +2563,7 @@
reference operator*()
{
- Object key = *pos;
+ Object key = keys[ pos ];
return std::make_pair(key, mapref<T>(*map,key));
}
@@ -2565,11 +2579,11 @@
bool eql(const iterator& right) const
{
- return *map == *right.map && pos == right.pos;
+ return map->ptr() == right.map->ptr() && pos == right.pos;
}
bool neq( const iterator& right ) const
{
- return *map != *right.map || pos != right.pos;
+ return map->ptr() != right.map->ptr() || pos != right.pos;
}
// pointer operator->() {
@@ -2619,8 +2633,15 @@
friend class MapBase<T>;
const MapBase<T>* map;
List keys; // for iterating over the map
- List::iterator pos; // index into the keys
+ int pos; // index into the keys
+ private:
+ const_iterator( MapBase<T>* m, List k, int p )
+ : map( m )
+ , keys( k )
+ , pos( p )
+ {}
+
public:
~const_iterator ()
{}
@@ -2631,10 +2652,10 @@
, pos()
{}
- const_iterator (const MapBase<T>* m, List k, List::iterator p )
+ const_iterator (MapBase<T>* m, bool end = false )
: map( m )
- , keys( k )
- , pos( p )
+ , keys( m->keys() )
+ , pos( end ? keys.length() : 0 )
{}
const_iterator(const const_iterator& other)
@@ -2645,20 +2666,20 @@
bool eql(const const_iterator& right) const
{
- return *map == *right.map && pos == right.pos;
+ return map->ptr() == right.map->ptr() && pos == right.pos;
}
+
bool neq( const const_iterator& right ) const
{
- return *map != *right.map || pos != right.pos;
+ return map->ptr() != right.map->ptr() || pos != right.pos;
}
+ const_reference operator*()
+ {
+ Object key = keys[ pos ];
+ return std::make_pair( key, mapref<T>( *map, key ) );
+ }
- // const_reference operator*() {
- // Object key = *pos;
- // return std::make_pair( key, map->[key] );
- // GCC < 3 barfes on this line at the '['.
- // }
-
const_iterator& operator=(const const_iterator& other)
{
if (this == &other) return *this;
@@ -2684,12 +2705,12 @@
const_iterator begin () const
{
- return const_iterator(this, 0);
+ return const_iterator(this);
}
const_iterator end () const
{
- return const_iterator(this, length());
+ return const_iterator(this, true);
}
}; // end of MapBase<T>
@@ -2717,7 +2738,7 @@
{
validate();
}
- Dict (const Dict& ob): Mapping(ob)
+ Dict (const Object& ob): Mapping(ob)
{
validate();
}
Modified: trunk/matplotlib/CXX/Version.hxx
===================================================================
--- trunk/matplotlib/CXX/Version.hxx 2009-01-07 16:16:18 UTC (rev 6759)
+++ trunk/matplotlib/CXX/Version.hxx 2009-01-07 18:09:46 UTC (rev 6760)
@@ -40,7 +40,7 @@
#define PYCXX_VERSION_MAJOR 5
#define PYCXX_VERSION_MINOR 4
-#define PYCXX_VERSION_PATCH 0
+#define PYCXX_VERSION_PATCH 2
#define PYCXX_MAKEVERSION( major, minor, patch ) ((major<<16)|(minor<<8)|(patch))
#define PYCXX_VERSION PYCXX_MAKEVERSION( PYCXX_VERSION_MAJOR, PYCXX_VERSION_MINOR, PYCXX_VERSION_PATCH )
#endif
Modified: trunk/matplotlib/CXX/WrapPython.h
===================================================================
--- trunk/matplotlib/CXX/WrapPython.h 2009-01-07 16:16:18 UTC (rev 6759)
+++ trunk/matplotlib/CXX/WrapPython.h 2009-01-07 18:09:46 UTC (rev 6760)
@@ -46,5 +46,4 @@
#include <sys/time.h>
#endif
-
#endif
Modified: trunk/matplotlib/CXX/cxx_extensions.cxx
===================================================================
--- trunk/matplotlib/CXX/cxx_extensions.cxx 2009-01-07 16:16:18 UTC (rev 6759)
+++ trunk/matplotlib/CXX/cxx_extensions.cxx 2009-01-07 18:09:46 UTC (rev 6760)
@@ -39,15 +39,50 @@
#include <assert.h>
-namespace Py
+namespace Py
{
+
+void Object::validate()
+{
+ // release pointer if not the right type
+ if( !accepts( p ) )
+ {
+#if defined( _CPPRTTI ) || defined( __GNUG__ )
+ std::string s( "PyCXX: Error creating object of type " );
+ s += (typeid( *this )).name();
+
+ if( p != 0 )
+ {
+ String from_repr = repr();
+ s += " from ";
+ s += from_repr.as_std_string();
+ }
+ else
+ {
+ s += " from (nil)";
+ }
+#endif
+ release();
+ if( PyErr_Occurred() )
+ { // Error message already set
+ throw Exception();
+ }
+ // Better error message if RTTI available
+#if defined( _CPPRTTI ) || defined( __GNUG__ )
+ throw TypeError( s );
+#else
+ throw TypeError( "PyCXX: type error." );
+#endif
+ }
+}
+
//================================================================================
//
// Implementation of MethodTable
//
//================================================================================
-PyMethodDef MethodTable::method( const char* method_name, PyCFunction f, int flags, const char* doc )
+PyMethodDef MethodTable::method( const char* method_name, PyCFunction f, int flags, const char* doc )
{
PyMethodDef m;
m.ml_name = const_cast<char*>( method_name );
@@ -81,7 +116,7 @@
}
PyMethodDef* MethodTable::table()
-{
+{
if( !mt )
{
Py_ssize_t t1size = t.size();
@@ -177,6 +212,7 @@
static PyObject* getattro_handler (PyObject*, PyObject*);
static int setattro_handler (PyObject*, PyObject*, PyObject*);
static int compare_handler (PyObject*, PyObject*);
+ static PyObject* richcompare_handler (PyObject*, PyObject*, int op);
static PyObject* repr_handler (PyObject*);
static PyObject* str_handler (PyObject*);
static long hash_handler (PyObject*);
@@ -314,7 +350,7 @@
return *this;
}
-// if you define one sequence method you must define
+// if you define one sequence method you must define
// all of them except the assigns
PythonType::PythonType( size_t basic_size, int itemsize, const char *default_name )
@@ -455,6 +491,14 @@
return *this;
}
+#if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 1)
+PythonType & PythonType::supportRichCompare()
+{
+ table->tp_richcompare = richcompare_handler;
+ return *this;
+}
+#endif
+
PythonType & PythonType::supportRepr()
{
table->tp_repr = repr_handler;
@@ -569,6 +613,21 @@
}
}
+#if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 1)
+extern "C" PyObject* richcompare_handler( PyObject *self, PyObject *other, int op )
+{
+ try
+ {
+ PythonExtensionBase *p = static_cast<PythonExtensionBase *>( self );
+ return new_reference_to( p->rich_compare( Py::Object( other ), op ) );
+ }
+ catch( Py::Exception & )
+ {
+ return NULL; // indicate error
+ }
+}
+#endif
+
extern "C" PyObject* repr_handler( PyObject *self )
{
try
@@ -1143,6 +1202,11 @@
int PythonExtensionBase::compare( const Py::Object & )
{ missing_method( compare ); return -1; }
+#if PY_MAJOR_VERSION > 2 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 1)
+Py::Object PythonExtensionBase::rich_compare( const Py::Object &, int op )
+{ missing_method( rich_compare ); return Py::None(); }
+#endif
+
Py::Object PythonExtensionBase::repr()
{ missing_method( repr ); return Py::Nothing(); }
@@ -1377,7 +1441,7 @@
set( PyErr_NewException( const_cast<char *>( module_name.c_str() ), parent.ptr(), NULL ), true );
}
-
+
ExtensionExceptionType::~ExtensionExceptionType()
{
}
@@ -1395,6 +1459,6 @@
Exception::Exception( PyObject* exception, Object &reason )
{
PyErr_SetObject (exception, reason.ptr());
-}
+}
} // end of namespace Py
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|