Karim Bahgat
Karim Bahgat

Reputation: 3041

Writing wrappers for Python 3 vs Python 2

In Python, is there any difference in how one would write Python wrappers for c++ libraries if one aims to make it compatible with Py3 vs Py2?

Or should a wrapper originally written for Py2 work the same way for Py3 and visa versa? As I understand it, Python wrappers are written in c++ in a .cxx file which then have to be compiled.

Details

I ask because I'm wanting to install Aggdraw (wrapper for c++ Anti Grain Geometry drawing library), which works in Python 2.6-7, but results in errors on Python 3.4 (Windows 7 32-bit, via "PATH=C:/Python27[or Python34]" and "python setup.py install" in the command line). My hope is to revive this amazing wrapper module for Python 3, and was hoping anyone else here would be interesting in helping out.

I can get it compiled on Python 2.6 and 2.7 without any problems, and I have both Visual C++ 2008 and 2010 so it's not a compiler problem. The problem seems to be in the actual .cxx wrapper code.

Could it be that the Aggdraw wrapper was only written with Python 2x in mind (almost 10 years ago now), and so it didn't take into account problems that might arise in Python 3x? My best guess is that the wrapper fails to convert certain c++ objects/types over to Python due to deprecated and changed features in version 3.4.

I might be willing to go through the .cxx wrapper code to change the necessary parts, if someone can help me identify what the troubleparts are (see command line error codes below)? If we get it fixed then I'll update this post with a link to the "revived" wrapper code.

If there should´t be a difference between Python 2 and 3 wrappers, any idea why I´m getting the error codes below in Py3 but not Py2?

Thanks!

Original wrapper code: click here

C:\Users\BIGKIMO\Desktop\aggdraw-master>python setup.py build
=== freetype not available (edit setup.py to enable)
running install
running build
running build_ext
building 'aggdraw' extension
C:\Program Files\Microsoft Visual Studio 10.0\VC\BIN\cl.exe /c /nologo /Ox /MD /
W3 /GS- /DNDEBUG -Iagg2/include -IC:\Python34\include -IC:\Python34\include /Tpa
ggdraw.cxx /Fobuild\temp.win32-3.4\Release\aggdraw.obj
aggdraw.cxx
aggdraw.cxx(124) : error C2440: 'initializing' : cannot convert from 'const char
 [5]' to 'Py_ssize_t'
        There is no context in which this conversion is possible
aggdraw.cxx(126) : error C2440: 'initializing' : cannot convert from 'destructor
' to 'printfunc'
        This conversion requires a reinterpret_cast, a C-style cast or function-
style cast
aggdraw.cxx(128) : error C2440: 'initializing' : cannot convert from 'getattrfun
c' to 'setattrfunc'
        This conversion requires a reinterpret_cast, a C-style cast or function-
style cast
aggdraw.cxx(142) : error C2440: 'initializing' : cannot convert from 'const char
 [4]' to 'Py_ssize_t'
        There is no context in which this conversion is possible
aggdraw.cxx(144) : error C2440: 'initializing' : cannot convert from 'destructor
' to 'printfunc'
        This conversion requires a reinterpret_cast, a C-style cast or function-
style cast
aggdraw.cxx(161) : error C2440: 'initializing' : cannot convert from 'const char
 [6]' to 'Py_ssize_t'
        There is no context in which this conversion is possible
aggdraw.cxx(163) : error C2440: 'initializing' : cannot convert from 'destructor
' to 'printfunc'
        This conversion requires a reinterpret_cast, a C-style cast or function-
style cast
aggdraw.cxx(187) : error C2440: 'initializing' : cannot convert from 'const char
 [5]' to 'Py_ssize_t'
        There is no context in which this conversion is possible
aggdraw.cxx(189) : error C2440: 'initializing' : cannot convert from 'destructor
' to 'printfunc'
        This conversion requires a reinterpret_cast, a C-style cast or function-
style cast
aggdraw.cxx(191) : error C2440: 'initializing' : cannot convert from 'getattrfun
c' to 'setattrfunc'
        This conversion requires a reinterpret_cast, a C-style cast or function-
style cast
aggdraw.cxx(207) : error C2440: 'initializing' : cannot convert from 'const char
 [5]' to 'Py_ssize_t'
        There is no context in which this conversion is possible
aggdraw.cxx(209) : error C2440: 'initializing' : cannot convert from 'destructor
' to 'printfunc'
        This conversion requires a reinterpret_cast, a C-style cast or function-
style cast
aggdraw.cxx(211) : error C2440: 'initializing' : cannot convert from 'getattrfun
c' to 'setattrfunc'
        This conversion requires a reinterpret_cast, a C-style cast or function-
style cast
aggdraw.cxx(488) : error C3861: 'PyString_Check': identifier not found
aggdraw.cxx(489) : error C3861: 'PyString_AS_STRING': identifier not found
aggdraw.cxx(575) : error C3861: 'PyString_Check': identifier not found
aggdraw.cxx(583) : error C3861: 'PyString_AS_STRING': identifier not found
aggdraw.cxx(584) : error C3861: 'PyString_GET_SIZE': identifier not found
aggdraw.cxx(730) : error C3861: 'PyInt_Check': identifier not found
aggdraw.cxx(730) : error C3861: 'PyInt_AS_LONG': identifier not found
aggdraw.cxx(731) : error C3861: 'PyInt_Check': identifier not found
aggdraw.cxx(731) : error C3861: 'PyInt_AS_LONG': identifier not found
aggdraw.cxx(735) : error C3861: 'PyInt_Check': identifier not found
aggdraw.cxx(735) : error C3861: 'PyInt_AS_LONG': identifier not found
aggdraw.cxx(736) : error C3861: 'PyInt_Check': identifier not found
aggdraw.cxx(736) : error C3861: 'PyInt_AS_LONG': identifier not found
aggdraw.cxx(742) : error C3861: 'PyInt_Check': identifier not found
aggdraw.cxx(742) : error C3861: 'PyInt_AS_LONG': identifier not found
aggdraw.cxx(745) : error C3861: 'PyInt_Check': identifier not found
aggdraw.cxx(745) : error C3861: 'PyInt_AS_LONG': identifier not found
aggdraw.cxx(759) : error C3861: 'PyInt_Check': identifier not found
aggdraw.cxx(760) : error C3861: 'PyInt_AsLong': identifier not found
aggdraw.cxx(763) : error C3861: 'PyString_Check': identifier not found
aggdraw.cxx(765) : error C3861: 'PyString_AS_STRING': identifier not found
aggdraw.cxx(788) : error C3861: 'PyString_Check': identifier not found
aggdraw.cxx(789) : error C3861: 'PyString_AS_STRING': identifier not found
aggdraw.cxx(1157) : error C3861: 'PyString_FromStringAndSize': identifier not fo
und
aggdraw.cxx(1289) : error C3861: 'PyString_FromString': identifier not found
aggdraw.cxx(1294) : error C3861: 'Py_FindMethod': identifier not found
aggdraw.cxx(1482) : error C3861: 'Py_FindMethod': identifier not found
aggdraw.cxx(1890) : error C3861: 'Py_FindMethod': identifier not found
aggdraw.cxx(1910) : error C3646: 'initaggdraw' : unknown override specifier
aggdraw.cxx(1911) : error C2091: function returns function
aggdraw.cxx(1911) : error C4430: missing type specifier - int assumed. Note: C++
 does not support default-int
aggdraw.cxx(1912) : error C2039: 'ob_type' : is not a member of '_typeobject'
        c:\python34\include\object.h(334) : see declaration of '_typeobject'
aggdraw.cxx(1912) : error C2039: 'ob_type' : is not a member of '_typeobject'
        c:\python34\include\object.h(334) : see declaration of '_typeobject'
aggdraw.cxx(1913) : error C2039: 'ob_type' : is not a member of '_typeobject'
        c:\python34\include\object.h(334) : see declaration of '_typeobject'
aggdraw.cxx(1913) : error C2039: 'ob_type' : is not a member of '_typeobject'
        c:\python34\include\object.h(334) : see declaration of '_typeobject'
aggdraw.cxx(1913) : error C2039: 'ob_type' : is not a member of '_typeobject'
        c:\python34\include\object.h(334) : see declaration of '_typeobject'
aggdraw.cxx(1915) : error C3861: 'Py_InitModule': identifier not found
aggdraw.cxx(1940) : warning C4508: 'DL_EXPORT' : function should return a value;
 'void' return type assumed

Upvotes: 3

Views: 2605

Answers (2)

Istlota
Istlota

Reputation: 94

In the interest of expanding upon the previous answer, there are many functions which acted upon string in Py2.7 and now act upon bytes or unicode in Py3. Similarly, what referred to int may now refer to long. As just one example of this that caused a problem here, PyString_Check has been deprecated by pyBytes_Check. Read the following for more details:

https://docs.python.org/3/howto/cporting.html?highlight=pystring

Upvotes: 1

BlamKiwi
BlamKiwi

Reputation: 2193

The Python FFI library (ctype) has changes between each version of python. It would be up to you to go through the change list and see what exactly is different and why it isn't working.

For example, ssizet and strings are different between the two Python versions.

https://docs.python.org/3/whatsnew/3.2.html#ctypes Differences in ctypes between Python 2 and 3

Upvotes: 3

Related Questions