Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r53278 - sandbox-branches/bhy/py3k/libs/python/src/converter
From: divinekid_at_[hidden]
Date: 2009-05-26 05:59:44


Author: bhy
Date: 2009-05-26 05:59:43 EDT (Tue, 26 May 2009)
New Revision: 53278
URL: http://svn.boost.org/trac/boost/changeset/53278

Log:
get builtin_converters.cpp compiled under Python 3
Text files modified:
   sandbox-branches/bhy/py3k/libs/python/src/converter/builtin_converters.cpp | 114 +++++++++++++++++++++++++++++++++++----
   1 files changed, 101 insertions(+), 13 deletions(-)

Modified: sandbox-branches/bhy/py3k/libs/python/src/converter/builtin_converters.cpp
==============================================================================
--- sandbox-branches/bhy/py3k/libs/python/src/converter/builtin_converters.cpp (original)
+++ sandbox-branches/bhy/py3k/libs/python/src/converter/builtin_converters.cpp 2009-05-26 05:59:43 EDT (Tue, 26 May 2009)
@@ -37,12 +37,16 @@
 
 namespace
 {
+
   // An lvalue conversion function which extracts a char const* from a
   // Python String.
+ // Cannot have this lvalue conversion in Python 3.
+#if PY_VERSION_HEX < 0x03000000
   void* convert_to_cstring(PyObject* obj)
   {
       return PyString_Check(obj) ? PyString_AsString(obj) : 0;
   }
+#endif
 
   // Given a target type and a SlotPolicy describing how to perform a
   // given conversion, registers from_python converters which use the
@@ -90,6 +94,52 @@
       }
   };
 
+ // identity_unaryfunc/py_object_identity -- manufacture a unaryfunc
+ // "slot" which just returns its argument.
+ extern "C" PyObject* identity_unaryfunc(PyObject* x)
+ {
+ Py_INCREF(x);
+ return x;
+ }
+ unaryfunc py_object_identity = identity_unaryfunc;
+
+#if PY_VERSION_HEX >= 0x03000000
+ // As in Python 3 there is only one integer type, we can have much
+ // simplified logic.
+ // XXX(bhy) maybe the code will work with 2.6 or even 2.5?
+ struct int_rvalue_from_python_base
+ {
+ static unaryfunc* get_slot(PyObject* obj)
+ {
+ return PyLong_Check(obj) ? &py_object_identity : 0;
+ }
+ static PyTypeObject const* get_pytype() {return &PyLong_Type;}
+ };
+
+ template <class T>
+ struct signed_int_rvalue_from_python : int_rvalue_from_python_base
+ {
+ static T extract(PyObject* intermediate)
+ {
+ long x = PyLong_AsLong(intermediate);
+ if (PyErr_Occurred())
+ throw_error_already_set();
+ return numeric_cast<T>(x);
+ }
+ };
+
+ template <class T>
+ struct unsigned_int_rvalue_from_python : int_rvalue_from_python_base
+ {
+ static T extract(PyObject* intermediate)
+ {
+ long x = PyLong_AsUnsignedLong(intermediate);
+ if (PyErr_Occurred())
+ throw_error_already_set();
+ return numeric_cast<T>(x);
+ }
+ };
+#else // PY_VERSION_HEX >= 0x03000000
   // A SlotPolicy for extracting signed integer types from Python objects
   struct signed_int_rvalue_from_python_base
   {
@@ -116,16 +166,7 @@
           return numeric_cast<T>(x);
       }
   };
-
- // identity_unaryfunc/py_object_identity -- manufacture a unaryfunc
- // "slot" which just returns its argument.
- extern "C" PyObject* identity_unaryfunc(PyObject* x)
- {
- Py_INCREF(x);
- return x;
- }
- unaryfunc py_object_identity = identity_unaryfunc;
-
+
   // A SlotPolicy for extracting unsigned integer types from Python objects
   struct unsigned_int_rvalue_from_python_base
   {
@@ -152,6 +193,7 @@
               : PyInt_AS_LONG(intermediate));
       }
   };
+#endif // PY_VERSION_HEX >= 0x03000000
 
 // Checking Python's macro instead of Boost's - we don't seem to get
 // the config right all the time. Furthermore, Python's is defined
@@ -164,6 +206,9 @@
   {
       static unaryfunc* get_slot(PyObject* obj)
       {
+#if PY_VERSION_HEX >= 0x03000000
+ return PyLong_Check(obj) ? &py_object_identity : 0;
+#else
           PyNumberMethods* number_methods = obj->ob_type->tp_as_number;
           if (number_methods == 0)
               return 0;
@@ -176,19 +221,22 @@
               return &number_methods->nb_long;
           else
               return 0;
+#endif
       }
- static PyTypeObject const* get_pytype() { return &PyInt_Type;}
+ static PyTypeObject const* get_pytype() { return &PyLong_Type;}
   };
   
   struct long_long_rvalue_from_python : long_long_rvalue_from_python_base
   {
       static BOOST_PYTHON_LONG_LONG extract(PyObject* intermediate)
       {
+#if PY_VERSION_HEX < 0x03000000
           if (PyInt_Check(intermediate))
           {
               return PyInt_AS_LONG(intermediate);
           }
           else
+#endif
           {
               BOOST_PYTHON_LONG_LONG result = PyLong_AsLongLong(intermediate);
               
@@ -204,11 +252,13 @@
   {
       static unsigned BOOST_PYTHON_LONG_LONG extract(PyObject* intermediate)
       {
+#if PY_VERSION_HEX < 0x03000000
           if (PyInt_Check(intermediate))
           {
               return numeric_cast<unsigned BOOST_PYTHON_LONG_LONG>(PyInt_AS_LONG(intermediate));
           }
           else
+#endif
           {
               unsigned BOOST_PYTHON_LONG_LONG result = PyLong_AsUnsignedLongLong(intermediate);
               
@@ -226,7 +276,11 @@
   {
       static unaryfunc* get_slot(PyObject* obj)
       {
+#if PY_VERSION_HEX >= 0x03000000
+ return obj == Py_None || PyLong_Check(obj) ? &py_object_identity : 0;
+#else
           return obj == Py_None || PyInt_Check(obj) ? &py_object_identity : 0;
+#endif
       }
       
       static bool extract(PyObject* intermediate)
@@ -255,8 +309,10 @@
 
           // For integer types, return the tp_int conversion slot to avoid
           // creating a new object. We'll handle that below
+#if PY_VERSION_HEX < 0x03000000
           if (PyInt_Check(obj))
               return &number_methods->nb_int;
+#endif
 
           return (PyLong_Check(obj) || PyFloat_Check(obj))
               ? &number_methods->nb_float : 0;
@@ -264,11 +320,13 @@
       
       static double extract(PyObject* intermediate)
       {
+#if PY_VERSION_HEX < 0x03000000
           if (PyInt_Check(intermediate))
           {
               return PyInt_AS_LONG(intermediate);
           }
           else
+#endif
           {
               return PyFloat_AS_DOUBLE(intermediate);
           }
@@ -276,22 +334,36 @@
       static PyTypeObject const* get_pytype() { return &PyFloat_Type;}
   };
 
+ unaryfunc py_unicode_as_string_unaryfunc = PyUnicode_AsUTF8String;
+
   // A SlotPolicy for extracting C++ strings from Python objects.
   struct string_rvalue_from_python
   {
       // If the underlying object is "string-able" this will succeed
       static unaryfunc* get_slot(PyObject* obj)
       {
- return (PyString_Check(obj))
- ? &obj->ob_type->tp_str : 0;
+#if PY_VERSION_HEX >= 0x03000000
+ return (PyUnicode_Check(obj)) ? &py_unicode_as_string_unaryfunc : 0;
+#else
+ return (PyString_Check(obj)) ? &obj->ob_type->tp_str : 0;
+
+#endif
       };
 
       // Remember that this will be used to construct the result object
+#if PY_VERSION_HEX >= 0x03000000
+ static std::string extract(PyObject* intermediate)
+ {
+ return std::string(PyBytes_AsString(intermediate),PyBytes_Size(intermediate));
+ }
+ static PyTypeObject const* get_pytype() { return &PyUnicode_Type;}
+#else
       static std::string extract(PyObject* intermediate)
       {
           return std::string(PyString_AsString(intermediate),PyString_Size(intermediate));
       }
       static PyTypeObject const* get_pytype() { return &PyString_Type;}
+#endif
   };
 
 #if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
@@ -311,7 +383,11 @@
       {
           return PyUnicode_Check(obj)
               ? &py_object_identity
+#if PY_VERSION_HEX >= 0x03000000
+ : PyBytes_Check(obj)
+#else
             : PyString_Check(obj)
+#endif
               ? &py_encode_string
             : 0;
       };
@@ -354,10 +430,12 @@
                   PyComplex_RealAsDouble(intermediate)
                   , PyComplex_ImagAsDouble(intermediate));
           }
+#if PY_VERSION_HEX < 0x03000000
           else if (PyInt_Check(intermediate))
           {
               return PyInt_AS_LONG(intermediate);
           }
+#endif
           else
           {
               return PyFloat_AS_DOUBLE(intermediate);
@@ -369,12 +447,20 @@
 
 BOOST_PYTHON_DECL PyObject* do_return_to_python(char x)
 {
+#if PY_VERSION_HEX >= 0x03000000
+ return PyUnicode_FromStringAndSize(&x, 1);
+#else
     return PyString_FromStringAndSize(&x, 1);
+#endif
 }
   
 BOOST_PYTHON_DECL PyObject* do_return_to_python(char const* x)
 {
+#if PY_VERSION_HEX >= 0x03000000
+ return x ? PyUnicode_FromString(x) : boost::python::detail::none();
+#else
     return x ? PyString_FromString(x) : boost::python::detail::none();
+#endif
 }
   
 BOOST_PYTHON_DECL PyObject* do_return_to_python(PyObject* x)
@@ -429,7 +515,9 @@
     slot_rvalue_from_python<std::complex<long double>,complex_rvalue_from_python>();
     
     // Add an lvalue converter for char which gets us char const*
+#if PY_VERSION_HEX < 0x03000000
     registry::insert(convert_to_cstring,type_id<char>(),&converter::wrap_pytype<&PyString_Type>::get_pytype);
+#endif
 
     // Register by-value converters to std::string, std::wstring
 #if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk