Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r52118 - in sandbox-branches/bhy/py3k: boost/python boost/python/converter boost/python/detail libs/python/src libs/python/src/converter libs/python/src/object
From: divinekid_at_[hidden]
Date: 2009-04-01 15:03:27


Author: bhy
Date: 2009-04-01 15:03:25 EDT (Wed, 01 Apr 2009)
New Revision: 52118
URL: http://svn.boost.org/trac/boost/changeset/52118

Log:
preliminary work - 14 BPL .cpp files can be compiled with Python 3 now.
Text files modified:
   sandbox-branches/bhy/py3k/boost/python/converter/builtin_converters.hpp | 25 ++++++++-
   sandbox-branches/bhy/py3k/boost/python/converter/pyobject_traits.hpp | 2
   sandbox-branches/bhy/py3k/boost/python/detail/wrap_python.hpp | 13 +++++
   sandbox-branches/bhy/py3k/boost/python/list.hpp | 2
   sandbox-branches/bhy/py3k/boost/python/str.hpp | 4 +
   sandbox-branches/bhy/py3k/libs/python/src/converter/from_python.cpp | 21 ++++++-
   sandbox-branches/bhy/py3k/libs/python/src/converter/registry.cpp | 7 ++
   sandbox-branches/bhy/py3k/libs/python/src/list.cpp | 17 ++++++
   sandbox-branches/bhy/py3k/libs/python/src/object/class.cpp | 55 ++++++++++++--------
   sandbox-branches/bhy/py3k/libs/python/src/object/enum.cpp | 43 +++++++++++++---
   sandbox-branches/bhy/py3k/libs/python/src/object/function.cpp | 26 ++++++++-
   sandbox-branches/bhy/py3k/libs/python/src/str.cpp | 104 +++++++++++++++++++++++++++------------
   12 files changed, 242 insertions(+), 77 deletions(-)

Modified: sandbox-branches/bhy/py3k/boost/python/converter/builtin_converters.hpp
==============================================================================
--- sandbox-branches/bhy/py3k/boost/python/converter/builtin_converters.hpp (original)
+++ sandbox-branches/bhy/py3k/boost/python/converter/builtin_converters.hpp 2009-04-01 15:03:25 EDT (Wed, 01 Apr 2009)
@@ -90,6 +90,14 @@
         BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T,expr)
 
 // Specialize converters for signed and unsigned T to Python Int
+#if PY_VERSION_HEX >= 0x03000000
+
+# define BOOST_PYTHON_TO_INT(T) \
+ BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, ::PyLong_FromLong(x), &PyLong_Type) \
+ BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned T, ::PyLong_FromUnsignedLong(x), &PyLong_Type)
+
+#else
+
 # define BOOST_PYTHON_TO_INT(T) \
     BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, ::PyInt_FromLong(x), &PyInt_Type) \
     BOOST_PYTHON_TO_PYTHON_BY_VALUE( \
@@ -98,6 +106,7 @@
                 (std::numeric_limits<long>::max)()) \
         ? ::PyLong_FromUnsignedLong(x) \
         : ::PyInt_FromLong(x), &PyInt_Type)
+#endif
 
 // Bool is not signed.
 #if PY_VERSION_HEX >= 0x02030000
@@ -115,18 +124,28 @@
 
 // using Python's macro instead of Boost's - we don't seem to get the
 // config right all the time.
+// XXX(bhy) It was PyInt_Type instead of PyLong_Type here.
+// But why PyInt_Type? PyLong_From* converter is used here!
 # ifdef HAVE_LONG_LONG
-BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed BOOST_PYTHON_LONG_LONG, ::PyLong_FromLongLong(x), &PyInt_Type)
-BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, ::PyLong_FromUnsignedLongLong(x), &PyInt_Type)
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed BOOST_PYTHON_LONG_LONG, ::PyLong_FromLongLong(x), &PyLong_Type)
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned BOOST_PYTHON_LONG_LONG, ::PyLong_FromUnsignedLongLong(x), &PyLong_Type)
 # endif
     
 # undef BOOST_TO_PYTHON_INT
 
+#if PY_VERSION_HEX >= 0x03000000
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x), &PyUnicode_Type)
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x), &PyUnicode_Type)
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, ::PyBytes_FromStringAndSize(x.data(),implicit_cast<ssize_t>(x.size())), &PyUnicode_Type)
+#else
 BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x), &PyString_Type)
 BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x), &PyString_Type)
 BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, ::PyString_FromStringAndSize(x.data(),implicit_cast<ssize_t>(x.size())), &PyString_Type)
+#endif
+
 #if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
-BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::wstring, ::PyUnicode_FromWideChar(x.data(),implicit_cast<ssize_t>(x.size())), &PyString_Type)
+// XXX(bhy) Here, similar to the above, PyString_Type -> PyUnicode_Type
+BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::wstring, ::PyUnicode_FromWideChar(x.data(),implicit_cast<ssize_t>(x.size())), &PyUnicode_Type)
 # endif
 BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, ::PyFloat_FromDouble(x), &PyFloat_Type)
 BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, ::PyFloat_FromDouble(x), &PyFloat_Type)

Modified: sandbox-branches/bhy/py3k/boost/python/converter/pyobject_traits.hpp
==============================================================================
--- sandbox-branches/bhy/py3k/boost/python/converter/pyobject_traits.hpp (original)
+++ sandbox-branches/bhy/py3k/boost/python/converter/pyobject_traits.hpp 2009-04-01 15:03:25 EDT (Wed, 01 Apr 2009)
@@ -34,7 +34,9 @@
 // This is not an exhaustive list; should be expanded.
 BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Type);
 BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(List);
+#if PY_VERSION_HEX < 0x03000000
 BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Int);
+#endif
 BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Long);
 BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Dict);
 BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Tuple);

Modified: sandbox-branches/bhy/py3k/boost/python/detail/wrap_python.hpp
==============================================================================
--- sandbox-branches/bhy/py3k/boost/python/detail/wrap_python.hpp (original)
+++ sandbox-branches/bhy/py3k/boost/python/detail/wrap_python.hpp 2009-04-01 15:03:25 EDT (Wed, 01 Apr 2009)
@@ -175,6 +175,19 @@
         ( (op)->ob_type = (typeobj), _Py_NewReference((PyObject *)(op)), (op) )
 #endif
 
+// Define Python 3 macros for Python 2.x
+#if PY_VERSION_HEX < 0x02060000
+
+# define Py_TYPE(o) (((PyObject*)(o))->ob_type)
+# define Py_REFCNT(o) (((PyObject*)(o))->ob_refcnt)
+# define Py_SIZE(o) (((PyVarObject*)(o))->ob_size)
+
+# define PyVarObject_HEAD_INIT(type, size) \
+ PyObject_HEAD_INIT(type) size,
+
+#endif
+
+
 #ifdef __MWERKS__
 # pragma warn_possunwant off
 #elif _MSC_VER

Modified: sandbox-branches/bhy/py3k/boost/python/list.hpp
==============================================================================
--- sandbox-branches/bhy/py3k/boost/python/list.hpp (original)
+++ sandbox-branches/bhy/py3k/boost/python/list.hpp 2009-04-01 15:03:25 EDT (Wed, 01 Apr 2009)
@@ -19,7 +19,7 @@
   {
       void append(object_cref); // append object to end
 
- long count(object_cref value) const; // return number of occurrences of value
+ Py_ssize_t count(object_cref value) const; // return number of occurrences of value
 
       void extend(object_cref sequence); // extend list by appending sequence elements
     

Modified: sandbox-branches/bhy/py3k/boost/python/str.hpp
==============================================================================
--- sandbox-branches/bhy/py3k/boost/python/str.hpp (original)
+++ sandbox-branches/bhy/py3k/boost/python/str.hpp 2009-04-01 15:03:25 EDT (Wed, 01 Apr 2009)
@@ -404,7 +404,11 @@
 {
   template <>
   struct object_manager_traits<str>
+#if PY_VERSION_HEX >= 0x03000000
+ : pytype_object_manager_traits<&PyUnicode_Type,str>
+#else
       : pytype_object_manager_traits<&PyString_Type,str>
+#endif
   {
   };
 }

Modified: sandbox-branches/bhy/py3k/libs/python/src/converter/from_python.cpp
==============================================================================
--- sandbox-branches/bhy/py3k/libs/python/src/converter/from_python.cpp (original)
+++ sandbox-branches/bhy/py3k/libs/python/src/converter/from_python.cpp 2009-04-01 15:03:25 EDT (Wed, 01 Apr 2009)
@@ -96,7 +96,12 @@
     if (!data.convertible)
     {
         handle<> msg(
- ::PyString_FromFormat(
+#if PY_VERSION_HEX >= 0x03000000
+ ::PyUnicode_FromFormat
+#else
+ ::PyString_FromFormat
+#endif
+ (
                 "No registered converter was able to produce a C++ rvalue of type %s from this Python object of type %s"
                 , converters.target_type.name()
                 , source->ob_type->tp_name
@@ -196,7 +201,12 @@
   void throw_no_lvalue_from_python(PyObject* source, registration const& converters, char const* ref_type)
   {
       handle<> msg(
- ::PyString_FromFormat(
+#if PY_VERSION_HEX >= 0x03000000
+ ::PyUnicode_FromFormat
+#else
+ ::PyString_FromFormat
+#endif
+ (
               "No registered converter was able to extract a C++ %s to type %s"
               " from this Python object of type %s"
               , ref_type
@@ -218,7 +228,12 @@
       if (source->ob_refcnt <= 1)
       {
           handle<> msg(
- ::PyString_FromFormat(
+#if PY_VERSION_HEX >= 0x3000000
+ ::PyUnicode_FromFormat
+#else
+ ::PyString_FromFormat
+#endif
+ (
                   "Attempt to return dangling %s to object of type: %s"
                   , ref_type
                   , converters.target_type.name()));

Modified: sandbox-branches/bhy/py3k/libs/python/src/converter/registry.cpp
==============================================================================
--- sandbox-branches/bhy/py3k/libs/python/src/converter/registry.cpp (original)
+++ sandbox-branches/bhy/py3k/libs/python/src/converter/registry.cpp 2009-04-01 15:03:25 EDT (Wed, 01 Apr 2009)
@@ -70,7 +70,12 @@
     if (this->m_to_python == 0)
     {
         handle<> msg(
- ::PyString_FromFormat(
+#if PY_VERSION_HEX >= 0x3000000
+ ::PyUnicode_FromFormat
+#else
+ ::PyString_FromFormat
+#endif
+ (
                 "No to_python (by-value) converter found for C++ type: %s"
                 , this->target_type.name()
                 )

Modified: sandbox-branches/bhy/py3k/libs/python/src/list.cpp
==============================================================================
--- sandbox-branches/bhy/py3k/libs/python/src/list.cpp (original)
+++ sandbox-branches/bhy/py3k/libs/python/src/list.cpp 2009-04-01 15:03:25 EDT (Wed, 01 Apr 2009)
@@ -48,7 +48,14 @@
 long list_base::index(object_cref value) const
 {
     object result_obj(this->attr("index")(value));
+ // TODO(bhy) In Python 2.5, PyInt_AsSsize_t did the same thing as PyLong_AsSsize_t,
+ // i.e., it can accepts both int and long. So we may have a better way to do this,
+ // so we can support ssize_t with Python 2.x.
+#if PY_VERSION_HEX >= 0x03000000
+ ssize_t result = PyLong_AsSsize_t(result_obj.ptr());
+#else
     long result = PyInt_AsLong(result_obj.ptr());
+#endif
     if (result == -1)
         throw_error_already_set();
     return result;
@@ -69,7 +76,11 @@
 
 void list_base::insert(object const& index, object_cref x)
 {
+#if PY_VERSION_HEX >= 0x03000000
+ ssize_t index_ = PyLong_AsSsize_t(index.ptr());
+#else
     long index_ = PyInt_AsLong(index.ptr());
+#endif
     if (index_ == -1 && PyErr_Occurred())
         throw_error_already_set();
     this->insert(index_, x);
@@ -128,10 +139,14 @@
 
 // For some reason, moving this to the end of the TU suppresses an ICE
 // with vc6.
-long list_base::count(object_cref value) const
+Py_ssize_t list_base::count(object_cref value) const
 {
     object result_obj(this->attr("count")(value));
+#if PY_VERSION_HEX >= 0x03000000
+ Py_ssize_t result = PyLong_AsSsize_t(result_obj.ptr());
+#else
     long result = PyInt_AsLong(result_obj.ptr());
+#endif
     if (result == -1)
         throw_error_already_set();
     return result;

Modified: sandbox-branches/bhy/py3k/libs/python/src/object/class.cpp
==============================================================================
--- sandbox-branches/bhy/py3k/libs/python/src/object/class.cpp (original)
+++ sandbox-branches/bhy/py3k/libs/python/src/object/class.cpp 2009-04-01 15:03:25 EDT (Wed, 01 Apr 2009)
@@ -106,8 +106,7 @@
 }
 
 static PyTypeObject static_data_object = {
- PyObject_HEAD_INIT(0)//&PyType_Type)
- 0,
+ PyVarObject_HEAD_INIT(NULL, 0)
     const_cast<char*>("Boost.Python.StaticProperty"),
     PyType_Type.tp_basicsize,
     0,
@@ -160,17 +159,20 @@
 
 namespace objects
 {
+#if PY_VERSION_HEX < 0x03000000
+ // XXX Not sure why this run into compiling error in Python 3
   extern "C"
   {
       // This declaration needed due to broken Python 2.2 headers
       extern DL_IMPORT(PyTypeObject) PyProperty_Type;
   }
+#endif
 
   BOOST_PYTHON_DECL PyObject* static_data()
   {
       if (static_data_object.tp_dict == 0)
       {
- static_data_object.ob_type = &PyType_Type;
+ Py_TYPE(&static_data_object) = &PyType_Type;
           static_data_object.tp_base = &PyProperty_Type;
           if (PyType_Ready(&static_data_object))
               return 0;
@@ -203,15 +205,14 @@
         // If we found a static data descriptor, call it directly to
         // force it to set the static data member
         if (a != 0 && PyObject_IsInstance(a, objects::static_data()))
- return a->ob_type->tp_descr_set(a, obj, value);
+ return Py_TYPE(a)->tp_descr_set(a, obj, value);
         else
             return PyType_Type.tp_setattro(obj, name, value);
     }
 }
 
 static PyTypeObject class_metatype_object = {
- PyObject_HEAD_INIT(0)//&PyType_Type)
- 0,
+ PyVarObject_HEAD_INIT(NULL, 0)
     const_cast<char*>("Boost.Python.class"),
     PyType_Type.tp_basicsize,
     0,
@@ -266,7 +267,7 @@
 // object.
 void instance_holder::install(PyObject* self) throw()
 {
- assert(self->ob_type->ob_type == &class_metatype_object);
+ assert(Py_TYPE(Py_TYPE(self)) == &class_metatype_object);
     m_next = ((objects::instance<>*)self)->objects;
     ((objects::instance<>*)self)->objects = this;
 }
@@ -279,7 +280,7 @@
   {
       if (class_metatype_object.tp_dict == 0)
       {
- class_metatype_object.ob_type = &PyType_Type;
+ Py_TYPE(&class_metatype_object) = &PyType_Type;
           class_metatype_object.tp_base = &PyType_Type;
           if (PyType_Ready(&class_metatype_object))
               return type_handle();
@@ -308,7 +309,7 @@
 
           Py_XDECREF(kill_me->dict);
           
- inst->ob_type->tp_free(inst);
+ Py_TYPE(inst)->tp_free(inst);
       }
 
       static PyObject *
@@ -318,7 +319,13 @@
           PyObject* d = type_->tp_dict;
           PyObject* instance_size_obj = PyObject_GetAttrString(d, const_cast<char*>("__instance_size__"));
 
- long instance_size = instance_size_obj ? PyInt_AsLong(instance_size_obj) : 0;
+ // TODO(bhy) ssize_t for Python 2.x
+ Py_ssize_t instance_size = instance_size_obj ?
+#if PY_VERSION_HEX >= 0x03000000
+ PyLong_AsSsize_t(instance_size_obj) : 0;
+#else
+ PyInt_AsLong(instance_size_obj) : 0;
+#endif
           
           if (instance_size < 0)
               instance_size = 0;
@@ -332,7 +339,12 @@
               // like, so we'll store the total size of the object
               // there. A negative number indicates that the extra
               // instance memory is not yet allocated to any holders.
- result->ob_size = -(static_cast<int>(offsetof(instance<>,storage) + instance_size));
+#if PY_VERSION_HEX >= 0x02060000
+ Py_SIZE(result) =
+#else
+ result->ob_size =
+#endif
+ -(static_cast<int>(offsetof(instance<>,storage) + instance_size));
           }
           return (PyObject*)result;
       }
@@ -368,8 +380,7 @@
   };
 
   static PyTypeObject class_type_object = {
- PyObject_HEAD_INIT(0) //&class_metatype_object)
- 0,
+ PyVarObject_HEAD_INIT(NULL, 0)
       const_cast<char*>("Boost.Python.instance"),
       offsetof(instance<>,storage), /* tp_basicsize */
       1, /* tp_itemsize */
@@ -424,7 +435,7 @@
   {
       if (class_type_object.tp_dict == 0)
       {
- class_type_object.ob_type = incref(class_metatype().get());
+ Py_TYPE(&class_type_object) = incref(class_metatype().get());
           class_type_object.tp_base = &PyBaseObject_Type;
           if (PyType_Ready(&class_type_object))
               return type_handle();
@@ -436,7 +447,7 @@
   BOOST_PYTHON_DECL void*
   find_instance_impl(PyObject* inst, type_info type, bool null_shared_ptr_only)
   {
- if (inst->ob_type->ob_type != &class_metatype_object)
+ if (Py_TYPE(Py_TYPE(inst)) != &class_metatype_object)
           return 0;
     
       instance<>* self = reinterpret_cast<instance<>*>(inst);
@@ -527,7 +538,7 @@
           d["__doc__"] = doc;
       
       object result = object(class_metatype())(name, bases, d);
- assert(PyType_IsSubtype(result.ptr()->ob_type, &PyType_Type));
+ assert(PyType_IsSubtype(Py_TYPE(result.ptr()), &PyType_Type));
       
       if (scope().ptr() != Py_None)
           scope().attr(name) = result;
@@ -651,7 +662,7 @@
         ::PyErr_Format(
             PyExc_TypeError
           , const_cast<char*>("staticmethod expects callable object; got an object of type %s, which is not callable")
- , callable->ob_type->tp_name
+ , Py_TYPE(callable)->tp_name
             );
         
         throw_error_already_set();
@@ -681,18 +692,18 @@
 
 void* instance_holder::allocate(PyObject* self_, std::size_t holder_offset, std::size_t holder_size)
 {
- assert(self_->ob_type->ob_type == &class_metatype_object);
+ assert(Py_TYPE(Py_TYPE(self_)) == &class_metatype_object);
     objects::instance<>* self = (objects::instance<>*)self_;
     
     int total_size_needed = holder_offset + holder_size;
     
- if (-self->ob_size >= total_size_needed)
+ if (-Py_SIZE(self) >= total_size_needed)
     {
         // holder_offset should at least point into the variable-sized part
         assert(holder_offset >= offsetof(objects::instance<>,storage));
 
         // Record the fact that the storage is occupied, noting where it starts
- self->ob_size = holder_offset;
+ Py_SIZE(self) = holder_offset;
         return (char*)self + holder_offset;
     }
     else
@@ -706,9 +717,9 @@
 
 void instance_holder::deallocate(PyObject* self_, void* storage) throw()
 {
- assert(self_->ob_type->ob_type == &class_metatype_object);
+ assert(Py_TYPE((self_)) == &class_metatype_object);
     objects::instance<>* self = (objects::instance<>*)self_;
- if (storage != (char*)self + self->ob_size)
+ if (storage != (char*)self + Py_SIZE(self))
     {
         PyMem_Free(storage);
     }

Modified: sandbox-branches/bhy/py3k/libs/python/src/object/enum.cpp
==============================================================================
--- sandbox-branches/bhy/py3k/libs/python/src/object/enum.cpp (original)
+++ sandbox-branches/bhy/py3k/libs/python/src/object/enum.cpp 2009-04-01 15:03:25 EDT (Wed, 01 Apr 2009)
@@ -18,7 +18,11 @@
 
 struct enum_object
 {
+#if PY_VERSION_HEX >= 0x03000000
+ PyLongObject base_object;
+#else
     PyIntObject base_object;
+#endif
     PyObject* name;
 };
 
@@ -32,19 +36,33 @@
 {
     static PyObject* enum_repr(PyObject* self_)
     {
- const char *mod = PyString_AsString(PyObject_GetAttrString( self_, const_cast<char*>("__module__")));
+ // XXX(bhy) Potentional memory leak here since PyObject_GetAttrString returns a new reference
+ // const char *mod = PyString_AsString(PyObject_GetAttrString( self_, const_cast<char*>("__module__")));
+ PyObject *mod = PyObject_GetAttrString( self_, "__module__");
         enum_object* self = downcast<enum_object>(self_);
         if (!self->name)
         {
- return PyString_FromFormat("%s.%s(%ld)", mod, self_->ob_type->tp_name, PyInt_AS_LONG(self_));
+ return
+#if PY_VERSION_HEX >= 0x03000000
+ PyUnicode_FromFormat("%S.%s(%ld)", mod, self_->ob_type->tp_name, PyLong_AsLong(self_));
+#else
+ PyString_FromFormat("%S.%s(%ld)", mod, self_->ob_type->tp_name, PyInt_AS_LONG(self_));
+#endif
         }
         else
         {
- char* name = PyString_AsString(self->name);
+ //char* name = PyString_AsString(self->name);
+ PyObject* name = self->name;
             if (name == 0)
                 return 0;
-
- return PyString_FromFormat("%s.%s.%s", mod, self_->ob_type->tp_name, name);
+
+ return
+#if PY_VERSION_HEX >= 0x03000000
+ PyUnicode_FromFormat
+#else
+ PyString_FromFormat
+#endif
+ ("%S.%s.%S", mod, self_->ob_type->tp_name, name);
         }
     }
 
@@ -53,7 +71,11 @@
         enum_object* self = downcast<enum_object>(self_);
         if (!self->name)
         {
+#if PY_VERSION_HEX >= 0x03000000
+ return PyLong_Type.tp_str(self_);
+#else
             return PyInt_Type.tp_str(self_);
+#endif
         }
         else
         {
@@ -63,8 +85,7 @@
 }
 
 static PyTypeObject enum_type_object = {
- PyObject_HEAD_INIT(0) // &PyType_Type
- 0,
+ PyVarObject_HEAD_INIT(NULL, 0) // &PyType_Type
     const_cast<char*>("Boost.Python.enum"),
     sizeof(enum_object), /* tp_basicsize */
     0, /* tp_itemsize */
@@ -84,7 +105,9 @@
     0, /* tp_setattro */
     0, /* tp_as_buffer */
     Py_TPFLAGS_DEFAULT
+#if PY_VERSION_HEX <= 0x03000000
     | Py_TPFLAGS_CHECKTYPES
+#endif
     | Py_TPFLAGS_HAVE_GC
     | Py_TPFLAGS_BASETYPE, /* tp_flags */
     0, /* tp_doc */
@@ -125,8 +148,12 @@
   {
       if (enum_type_object.tp_dict == 0)
       {
- enum_type_object.ob_type = incref(&PyType_Type);
+ Py_TYPE(&enum_type_object) = incref(&PyType_Type);
+#if PY_VERSION_HEX >= 0x02060000
+ enum_type_object.tp_base = &PyLong_Type;
+#else
           enum_type_object.tp_base = &PyInt_Type;
+#endif
           if (PyType_Ready(&enum_type_object))
               throw_error_already_set();
       }

Modified: sandbox-branches/bhy/py3k/libs/python/src/object/function.cpp
==============================================================================
--- sandbox-branches/bhy/py3k/libs/python/src/object/function.cpp (original)
+++ sandbox-branches/bhy/py3k/libs/python/src/object/function.cpp 2009-04-01 15:03:25 EDT (Wed, 01 Apr 2009)
@@ -105,9 +105,9 @@
     }
     
     PyObject* p = this;
- if (function_type.ob_type == 0)
+ if (Py_TYPE(&function_type) == 0)
     {
- function_type.ob_type = &PyType_Type;
+ Py_TYPE(&function_type) = &PyType_Type;
         ::PyType_Ready(&function_type);
     }
     
@@ -435,9 +435,13 @@
         function* new_func = downcast<function>(attribute.ptr());
         PyObject* dict = 0;
         
+#if PY_VERSION_HEX < 0x03000000
+ // Old-style class gone in Python 3
         if (PyClass_Check(ns))
             dict = ((PyClassObject*)ns)->cl_dict;
- else if (PyType_Check(ns))
+ else
+#endif
+ if (PyType_Check(ns))
             dict = ((PyTypeObject*)ns)->tp_dict;
         else
             dict = PyObject_GetAttrString(ns, const_cast<char*>("__dict__"));
@@ -595,9 +599,18 @@
     static PyObject *
     function_descr_get(PyObject *func, PyObject *obj, PyObject *type_)
     {
+#if PY_VERSION_HEX >= 0x03000000
+ // The implement is different in Python 3 because of the removal of unbound method
+ if (obj == Py_None || obj == NULL) {
+ Py_INCREF(func);
+ return func;
+ }
+ return PyMethod_New(func, obj);
+#else
         if (obj == Py_None)
             obj = NULL;
         return PyMethod_New(func, obj, type_);
+#endif
     }
 
     static void
@@ -641,7 +654,11 @@
     {
         function* f = downcast<function>(op);
         if (f->name().ptr() == Py_None)
+#if PY_VERSION_HEX >= 0x03000000
+ return PyUnicode_InternFromString("<unnamed Boost.Python function>");
+#else
             return PyString_InternFromString("<unnamed Boost.Python function>");
+#endif
         else
             return python::incref(f->name().ptr());
     }
@@ -665,8 +682,7 @@
 };
 
 PyTypeObject function_type = {
- PyObject_HEAD_INIT(0)
- 0,
+ PyVarObject_HEAD_INIT(NULL, 0)
     const_cast<char*>("Boost.Python.function"),
     sizeof(function),
     0,

Modified: sandbox-branches/bhy/py3k/libs/python/src/str.cpp
==============================================================================
--- sandbox-branches/bhy/py3k/libs/python/src/str.cpp (original)
+++ sandbox-branches/bhy/py3k/libs/python/src/str.cpp 2009-04-01 15:03:25 EDT (Wed, 01 Apr 2009)
@@ -10,16 +10,33 @@
 detail::new_reference str_base::call(object const& arg_)
 {
     return (detail::new_reference)PyObject_CallFunction(
- (PyObject*)&PyString_Type, const_cast<char*>("(O)"),
+#if PY_VERSION_HEX >= 0x03000000
+ (PyObject*)&PyUnicode_Type,
+#else
+ (PyObject*)&PyString_Type,
+#endif
+ const_cast<char*>("(O)"),
         arg_.ptr());
 }
 
 str_base::str_base()
- : object(detail::new_reference(::PyString_FromString("")))
+ : object(detail::new_reference(
+#if PY_VERSION_HEX >= 0x03000000
+ ::PyUnicode_FromString("")
+#else
+ ::PyString_FromString("")
+#endif
+ ))
 {}
 
 str_base::str_base(const char* s)
- : object(detail::new_reference(::PyString_FromString(s)))
+ : object(detail::new_reference(
+#if PY_VERSION_HEX >= 0x03000000
+ ::PyUnicode_FromString(s)
+#else
+ ::PyString_FromString(s)
+#endif
+ ))
 {}
 
 namespace {
@@ -38,9 +55,12 @@
 str_base::str_base(char const* start, char const* finish)
     : object(
         detail::new_reference(
- ::PyString_FromStringAndSize(
- start, str_size_as_py_ssize_t(finish - start)
- )
+#if PY_VERSION_HEX >= 0x03000000
+ ::PyUnicode_FromStringAndSize
+#else
+ ::PyString_FromStringAndSize
+#endif
+ (start, str_size_as_py_ssize_t(finish - start))
         )
     )
 {}
@@ -48,9 +68,12 @@
 str_base::str_base(char const* start, std::size_t length) // new str
     : object(
         detail::new_reference(
- ::PyString_FromStringAndSize(
- start, str_size_as_py_ssize_t(length)
- )
+#if PY_VERSION_HEX >= 0x03000000
+ ::PyUnicode_FromStringAndSize
+#else
+ ::PyString_FromStringAndSize
+#endif
+ ( start, str_size_as_py_ssize_t(length) )
         )
     )
 {}
@@ -122,9 +145,17 @@
     return this->attr("encode")(encoding,errors);
 }
 
+
+// XXX(bhy) Why not use extract<long> instead of Python C-API?
+#if PY_VERSION_HEX >= 0x03000000
+ #define _BOOST_PYTHON_ASLONG PyLong_AsLong
+#else
+ #define _BOOST_PYTHON_ASLONG PyInt_AsLong
+#endif
+
 bool str_base::endswith(object_cref suffix) const
 {
- bool result = PyInt_AsLong(this->attr("endswith")(suffix).ptr());
+ bool result = _BOOST_PYTHON_ASLONG(this->attr("endswith")(suffix).ptr());
     if (PyErr_Occurred())
         throw_error_already_set();
     return result;
@@ -135,7 +166,7 @@
 
 long str_base::find(object_cref sub) const
 {
- long result = PyInt_AsLong(this->attr("find")(sub).ptr());
+ long result = _BOOST_PYTHON_ASLONG(this->attr("find")(sub).ptr());
     if (PyErr_Occurred())
         throw_error_already_set();
     return result;
@@ -143,7 +174,7 @@
 
 long str_base::find(object_cref sub, object_cref start) const
 {
- long result = PyInt_AsLong(this->attr("find")(sub,start).ptr());
+ long result = _BOOST_PYTHON_ASLONG(this->attr("find")(sub,start).ptr());
     if (PyErr_Occurred())
         throw_error_already_set();
     return result;
@@ -151,7 +182,7 @@
 
 long str_base::find(object_cref sub, object_cref start, object_cref end) const
 {
- long result = PyInt_AsLong(this->attr("find")(sub,start,end).ptr());
+ long result = _BOOST_PYTHON_ASLONG(this->attr("find")(sub,start,end).ptr());
     if (PyErr_Occurred())
         throw_error_already_set();
     return result;
@@ -159,7 +190,7 @@
 
 long str_base::index(object_cref sub) const
 {
- long result = PyInt_AsLong(this->attr("index")(sub).ptr());
+ long result = _BOOST_PYTHON_ASLONG(this->attr("index")(sub).ptr());
     if (PyErr_Occurred())
         throw_error_already_set();
     return result;
@@ -167,7 +198,7 @@
 
 long str_base::index(object_cref sub, object_cref start) const
 {
- long result = PyInt_AsLong(this->attr("index")(sub,start).ptr());
+ long result = _BOOST_PYTHON_ASLONG(this->attr("index")(sub,start).ptr());
     if (PyErr_Occurred())
         throw_error_already_set();
     return result;
@@ -175,7 +206,7 @@
 
 long str_base::index(object_cref sub, object_cref start, object_cref end) const
 {
- long result = PyInt_AsLong(this->attr("index")(sub,start,end).ptr());
+ long result = _BOOST_PYTHON_ASLONG(this->attr("index")(sub,start,end).ptr());
     if (PyErr_Occurred())
         throw_error_already_set();
     return result;
@@ -183,7 +214,7 @@
 
 bool str_base::isalnum() const
 {
- bool result = PyInt_AsLong(this->attr("isalnum")().ptr());
+ bool result = _BOOST_PYTHON_ASLONG(this->attr("isalnum")().ptr());
     if (PyErr_Occurred())
         throw_error_already_set();
     return result;
@@ -191,7 +222,7 @@
 
 bool str_base::isalpha() const
 {
- bool result = PyInt_AsLong(this->attr("isalpha")().ptr());
+ bool result = _BOOST_PYTHON_ASLONG(this->attr("isalpha")().ptr());
     if (PyErr_Occurred())
         throw_error_already_set();
     return result;
@@ -199,7 +230,7 @@
 
 bool str_base::isdigit() const
 {
- bool result = PyInt_AsLong(this->attr("isdigit")().ptr());
+ bool result = _BOOST_PYTHON_ASLONG(this->attr("isdigit")().ptr());
     if (PyErr_Occurred())
         throw_error_already_set();
     return result;
@@ -207,7 +238,7 @@
 
 bool str_base::islower() const
 {
- bool result = PyInt_AsLong(this->attr("islower")().ptr());
+ bool result = _BOOST_PYTHON_ASLONG(this->attr("islower")().ptr());
     if (PyErr_Occurred())
         throw_error_already_set();
     return result;
@@ -215,7 +246,7 @@
 
 bool str_base::isspace() const
 {
- bool result = PyInt_AsLong(this->attr("isspace")().ptr());
+ bool result = _BOOST_PYTHON_ASLONG(this->attr("isspace")().ptr());
     if (PyErr_Occurred())
         throw_error_already_set();
     return result;
@@ -223,7 +254,7 @@
 
 bool str_base::istitle() const
 {
- bool result = PyInt_AsLong(this->attr("istitle")().ptr());
+ bool result = _BOOST_PYTHON_ASLONG(this->attr("istitle")().ptr());
     if (PyErr_Occurred())
         throw_error_already_set();
     return result;
@@ -231,7 +262,7 @@
 
 bool str_base::isupper() const
 {
- bool result = PyInt_AsLong(this->attr("isupper")().ptr());
+ bool result = _BOOST_PYTHON_ASLONG(this->attr("isupper")().ptr());
     if (PyErr_Occurred())
         throw_error_already_set();
     return result;
@@ -246,7 +277,7 @@
 
 long str_base::rfind(object_cref sub) const
 {
- long result = PyInt_AsLong(this->attr("rfind")(sub).ptr());
+ long result = _BOOST_PYTHON_ASLONG(this->attr("rfind")(sub).ptr());
     if (PyErr_Occurred())
         throw_error_already_set();
     return result;
@@ -254,7 +285,7 @@
 
 long str_base::rfind(object_cref sub, object_cref start) const
 {
- long result = PyInt_AsLong(this->attr("rfind")(sub,start).ptr());
+ long result = _BOOST_PYTHON_ASLONG(this->attr("rfind")(sub,start).ptr());
     if (PyErr_Occurred())
         throw_error_already_set();
     return result;
@@ -262,7 +293,7 @@
 
 long str_base::rfind(object_cref sub, object_cref start, object_cref end) const
 {
- long result = PyInt_AsLong(this->attr("rfind")(sub,start,end).ptr());
+ long result = _BOOST_PYTHON_ASLONG(this->attr("rfind")(sub,start,end).ptr());
     if (PyErr_Occurred())
         throw_error_already_set();
     return result;
@@ -270,7 +301,7 @@
 
 long str_base::rindex(object_cref sub) const
 {
- long result = PyInt_AsLong(this->attr("rindex")(sub).ptr());
+ long result = _BOOST_PYTHON_ASLONG(this->attr("rindex")(sub).ptr());
     if (PyErr_Occurred())
         throw_error_already_set();
     return result;
@@ -278,7 +309,7 @@
 
 long str_base::rindex(object_cref sub, object_cref start) const
 {
- long result = PyInt_AsLong(this->attr("rindex")(sub,start).ptr());
+ long result = _BOOST_PYTHON_ASLONG(this->attr("rindex")(sub,start).ptr());
     if (PyErr_Occurred())
         throw_error_already_set();
     return result;
@@ -286,7 +317,7 @@
 
 long str_base::rindex(object_cref sub, object_cref start, object_cref end) const
 {
- long result = PyInt_AsLong(this->attr("rindex")(sub,start,end).ptr());
+ long result = _BOOST_PYTHON_ASLONG(this->attr("rindex")(sub,start,end).ptr());
     if (PyErr_Occurred())
         throw_error_already_set();
     return result;
@@ -322,7 +353,7 @@
 
 bool str_base::startswith(object_cref prefix) const
 {
- bool result = PyInt_AsLong(this->attr("startswith")(prefix).ptr());
+ bool result = _BOOST_PYTHON_ASLONG(this->attr("startswith")(prefix).ptr());
     if (PyErr_Occurred())
         throw_error_already_set();
     return result;
@@ -330,7 +361,7 @@
 
 bool str_base::startswith(object_cref prefix, object_cref start) const
 {
- bool result = PyInt_AsLong(this->attr("startswith")(prefix,start).ptr());
+ bool result = _BOOST_PYTHON_ASLONG(this->attr("startswith")(prefix,start).ptr());
     if (PyErr_Occurred())
         throw_error_already_set();
     return result;
@@ -338,12 +369,14 @@
 
 bool str_base::startswith(object_cref prefix, object_cref start, object_cref end) const
 {
- bool result = PyInt_AsLong(this->attr("startswith")(prefix,start,end).ptr());
+ bool result = _BOOST_PYTHON_ASLONG(this->attr("startswith")(prefix,start,end).ptr());
     if (PyErr_Occurred())
         throw_error_already_set();
     return result;
 }
 
+#undef _BOOST_PYTHON_ASLONG
+
 BOOST_PYTHON_DEFINE_STR_METHOD(strip, 0)
 BOOST_PYTHON_DEFINE_STR_METHOD(swapcase, 0)
 BOOST_PYTHON_DEFINE_STR_METHOD(title, 0)
@@ -357,7 +390,12 @@
     {
         const_cast<converter::registration &>(
             converter::registry::lookup(boost::python::type_id<boost::python::str>())
- ).m_class_object = &PyString_Type;
+ )
+#if PY_VERSION_HEX >= 0x03000000
+ .m_class_object = &PyUnicode_Type;
+#else
+ .m_class_object = &PyString_Type;
+#endif
     }
 }register_str_pytype_ptr_;
     


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