Porting to python3

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
wmayer
Site Admin
Posts: 14887
Joined: Thu Feb 19, 2009 10:32 am

Re: Porting to python3

Postby wmayer » Sat Oct 24, 2015 4:19 pm

Just to know, porting to Python3 need Qt5 ??? and PySide2 ???
No and no. Once we do the Qt5 porting then we need PySide2.
User avatar
yorik
Site Admin
Posts: 11552
Joined: Tue Feb 17, 2009 9:16 pm
Location: São Paulo, Brazil
Contact:

Re: Porting to python3

Postby yorik » Sun Oct 25, 2015 12:01 am

Yes, one problem at a time... :|

By the way, I finished porting GUI, it is now possible to build FreeCAD with all modules deactivated, but now both the py2 and py3 versions crash at startup :) Still something not right apparently. The py3 port has problems with the initializing of the interpreter. Apparently still not right there. Too bad there are so few examples on the net..

Anyway, we're progressing!
looo
Posts: 2908
Joined: Mon Nov 11, 2013 5:29 pm

Re: Porting to python3

Postby looo » Thu Nov 26, 2015 4:00 pm

Very nice to see that freecad is on the way to python3.
please help with my conda-packaging efforts: https://liberapay.com/looooo/
User avatar
yorik
Site Admin
Posts: 11552
Joined: Tue Feb 17, 2009 9:16 pm
Location: São Paulo, Brazil
Contact:

Re: Porting to python3

Postby yorik » Wed Jan 06, 2016 1:52 am

I did a little progress, the updated (rebased on todays master) branch is py3-4 on my github. It builds fine with both py2 and py3 but still crashes on launch, some problem at init (py2 didn't like the change from getattr -> getattro, and with py3 "No module named "FreeCAD", which should be easier to solve)

But I think we're almost there...
looo
Posts: 2908
Joined: Mon Nov 11, 2013 5:29 pm

Re: Porting to python3

Postby looo » Wed Jan 06, 2016 9:28 pm

It compiles :) Impressive.

Importing the python3 compiled FreeCAD from python3 throw this error:

Code: Select all

>>> import FreeCAD
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define init function (PyInit_FreeCAD)
please help with my conda-packaging efforts: https://liberapay.com/looooo/
User avatar
yorik
Site Admin
Posts: 11552
Joined: Tue Feb 17, 2009 9:16 pm
Location: São Paulo, Brazil
Contact:

Re: Porting to python3

Postby yorik » Thu Jan 07, 2016 1:40 am

hmm that might be the problem, thanks for the hint!
wmayer
Site Admin
Posts: 14887
Joined: Thu Feb 19, 2009 10:32 am

Re: Porting to python3

Postby wmayer » Thu Jan 07, 2016 11:03 am

looo wrote:It compiles :) Impressive.

Importing the python3 compiled FreeCAD from python3 throw this error:

Code: Select all

>>> import FreeCAD
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define init function (PyInit_FreeCAD)
Two questions:
1. The new prefix for Python entry function is now "PyInit_" instead of "init", right?
2. How did you test this? There are two different shared libraries for "FreeCAD". The one is FreeCAD.dll (Windows or libFreeCAD.so (Linux) or libFreeCAD.dylib (OSX)) and FreeCAD.pyd (Windows or FreeCAD.so (Linux/OSX)).

The former library is not a Python module but internally it dynamically creates a module "FreeCAD" in memory with all the Python classes and functions. When doing an "import FreeCAD" this doesn't actually do anything because the FreeCAD module already exists. This is the behaviour when using the applications FreeCAD or FreeCADCmd.

The latter library is a real Python module and its main purpose is to initialize FreeCAD internals and is linked against the former library. This module is only needed when importing FreeCAD from a normal Python session or any other Python based application.
looo
Posts: 2908
Joined: Mon Nov 11, 2013 5:29 pm

Re: Porting to python3

Postby looo » Thu Jan 07, 2016 11:44 am

2. How did you test this? There are two different shared libraries for "FreeCAD". The one is FreeCAD.dll (Windows or libFreeCAD.so (Linux) or libFreeCAD.dylib (OSX)) and FreeCAD.pyd (Windows or FreeCAD.so (Linux/OSX)).
I started python from the /lib directory where these files are stored:
FreeCAD.so libFreeCADApp.so libFreeCADBase.so

with python2 and master branch I get this:

Code: Select all

>>> import FreeCAD
FreeCAD 0.16, Libs: 0.16R6188 (Git)
>>> FreeCAD.__file__
'FreeCAD.so'
So I think it should be the right file?
1. The new prefix for Python entry function is now "PyInit_" instead of "init", right?
I don't know. It seems that this has changed in python3, but I couldn't find any information on this by now.
please help with my conda-packaging efforts: https://liberapay.com/looooo/
wmayer
Site Admin
Posts: 14887
Joined: Thu Feb 19, 2009 10:32 am

Re: Porting to python3

Postby wmayer » Thu Jan 07, 2016 1:09 pm

I found something here:
http://python3porting.com/cextensions.html

This means void initFreeCAD must be changed to

Code: Select all

PyObject* PyInit_FreeCAD
User avatar
yorik
Site Admin
Posts: 11552
Joined: Tue Feb 17, 2009 9:16 pm
Location: São Paulo, Brazil
Contact:

Re: Porting to python3

Postby yorik » Thu Jan 07, 2016 1:25 pm

*EDIT* AAh thanks Werner, I couldn't find that!!
wmayer wrote: How did you test this?
I can do that too, just go to the compiled lib folder, run a python3 console and "import FreeCAD". This is what I have in that folder, btw, no libFreeCAD.so:

FreeCADGui.so
FreeCAD.so
libFreeCADApp.so
libFreeCADBase.so
libFreeCADGui.so
wmayer wrote:1. The new prefix for Python entry function is now "PyInit_" instead of "init", right?
Yes that might be the problem, but I still couldn't find where/how that is done... At the moment I can see no init function in src/App/Application.cpp (I suppose that is where it should be), I thought all this was done automatically by the module init macros, but maybe I was wrong... Will investigate further.

When building the py3 branch with python2 I get other kinds of errors, but I think I know where the culprit is. In python3 the getattr(const char*) method of python classes is not supported anymore, it needs to be switched to getattro(PyObject*), which I did, but I apparently did some mistakes in it :)