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: 14588
Joined: Thu Feb 19, 2009 10:32 am

Re: Porting to python3

Postby wmayer » Sat Jan 09, 2016 3:54 pm

Thanks!
Why not push the branch with your changes to the official FreeCAD repo, I'll take it from there, we can delete it afterwards when we're done... After all the official FreeCAD repo is a bit yours by right
I don't want to pollute the official repo. And since I still have some old branches on SF I anyway need a github repo to migrate them some time.

Then in order to not let crash the application it might be good to put the invoking of the script in a try/catch block:

Code: Select all

try {
    Interpreter().runString(Base::ScriptFactory().ProduceScript("FreeCADInit"));
}
catch (const Base::Exception& e) {
    Base::Console().Error("%s\n", e.what());
}
Here is the commit:
https://github.com/wwmayer/FreeCAD/comm ... b32a4da94d
wmayer
Site Admin
Posts: 14588
Joined: Thu Feb 19, 2009 10:32 am

Re: Porting to python3

Postby wmayer » Sat Jan 09, 2016 5:04 pm

Yorik wrote: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:
Here you have to be careful which exact Python version you are running. I have setup a clean Debian sid and "python" is Python 2.7, python3 is Python3.4 and Python3.5 is the needed command to get the correct version.

I now have ported MainPy.cpp and of course "python" doesn't work. However, "python3" gives error message:
'module' object has no attribute PrintError
and "python3.5" gives me the same error message as FreeCADCmd
<built-in function PrintLog> returned a result with an error set
wmayer
Site Admin
Posts: 14588
Joined: Thu Feb 19, 2009 10:32 am

Re: Porting to python3

Postby wmayer » Sat Jan 09, 2016 9:57 pm

Now after fixing a few more things I get this error, too:
While initializing FreeCAD the following exception occurred: ''ParameterGrp' object has no attribute 'GetString''
ParameterGrpPy is one of the remaining classes that were manually written and its type object is not set up properly. Instead, attributes are accessed via the macro _getattr_up which doesn't work with Python3.

The best IMO is to rewrite this class based on PyCXX.
User avatar
yorik
Site Admin
Posts: 11458
Joined: Tue Feb 17, 2009 9:16 pm
Location: São Paulo, Brazil
Contact:

Re: Porting to python3

Postby yorik » Sun Jan 10, 2016 4:12 pm

Pure magic you did Werner, CONGRATS!
Below, with mandatory typical py2->py3 newbie typing error ;)

Code: Select all

$  ~/Sources/build/fcpy3/bin/FreeCADCmd
FreeCAD 0.16, Libs: 0.16R6203 +18 (Git)
(c) Juergen Riegel, Werner Mayer, Yorik van Havre 2001-2015
  #####                 ####  ###   ####  
  #                    #      # #   #   # 
  #     ##  #### ####  #     #   #  #   # 
  ####  # # #  # #  #  #     #####  #   # 
  #     #   #### ####  #    #     # #   # 
  #     #   #    #     #    #     # #   #  ##  ##  ##
  #     #   #### ####   ### #     # ####   ##  ##  ##

'str' object has no attribute 'decode'
[FreeCAD Console mode <Use Ctrl-D (i.e. EOF) to exit.>]
>>> import sys
>>> print sys.version
  File "<stdin>", line 1
    print sys.version
            ^
SyntaxError: Missing parentheses in call to 'print'
>>> print(sys.version)   
3.5.1 (default, Dec 10 2015, 14:34:41) 
[GCC 5.3.1 20151207]
>>> 
building with py2 works too. Still a couple of small issues here and there, and the GUI module still fails with py3, but this should be much easier to solve.I am learning a lot by looking at your commits... Many things I read on the net make sense only now... :|

New rebased branch with your latest commits included: https://github.com/yorikvanhavre/FreeCAD/tree/py3-6
wmayer
Site Admin
Posts: 14588
Joined: Thu Feb 19, 2009 10:32 am

Re: Porting to python3

Postby wmayer » Sun Jan 10, 2016 5:49 pm

Pure magic you did Werner, CONGRATS!
Found an oddity with PyCXX's Py::PythonExtension template class. The methods of ParameterGrpPy can be accessed now but when doing a "dir()" on the object it gives an empty list. Looks like a bug in PyCXX which is still there in the latest version.

There are a few more changes on my branch:
  • reverted back to PyUnicode_AsUTF8 in the Console methods.
    There are actually two ways to do it:
    PyUnicode_AsEncodedObject and PyBytes_AsString or PyUnicode_AsUTF8 but you can't mix PyUnicode_AsEncodedObject and PyUnicode_AsUTF8
  • fix crash in Base::Tools::escapedUnicodeFromUtf8
User avatar
yorik
Site Admin
Posts: 11458
Joined: Tue Feb 17, 2009 9:16 pm
Location: São Paulo, Brazil
Contact:

Re: Porting to python3

Postby yorik » Mon Jan 11, 2016 6:07 pm

cool, I rebased and merged your latest changes, bleeding edge branch is now https://github.com/yorikvanhavre/FreeCAD/tree/py3-7

current status:
with py3: builds with all modules disabled. runs in command mode, not in GUI mode
with py2: builds with all modules enabled, runs in both command and GUI mode

the py2 build however gives a lot of errors when running the tests from test WB. Normal, much of the underlying code has changed. I'm surprised it built at all :) I started looking at them, one thing annoys me, although I had read the contrary, it seems that under py2, PyLong_Check refuses to recognize an int as long:

Code: Select all

>>> o=App.ActiveDocument.addObject("App::FeatureTest","test")
>>> o.ConstraintInt
5
>>> o.ConstraintInt=10
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: Property 'ConstraintInt': type must be int, not int
>>> o.ConstraintInt=long(10)
>>> o.ConstraintInt
10
If this is true, it's annoying, will introduce a lot more of if PYTHON_MAJOR_VERSION... I'll investigate a bit more, though

But I'm not sure it is of any use to check those test errors now, because when we'll switch them all to py3, there will be a lot more :)
wmayer
Site Admin
Posts: 14588
Joined: Thu Feb 19, 2009 10:32 am

Re: Porting to python3

Postby wmayer » Mon Jan 11, 2016 8:55 pm

although I had read the contrary, it seems that under py2, PyLong_Check refuses to recognize an int as long:
You say you get this with py2. So, you also get this error with master?

When I try this with the master branch then it works with

Code: Select all

o.ConstraintInt=10
but fails with

Code: Select all

o.ConstraintInt=long(10)
User avatar
yorik
Site Admin
Posts: 11458
Joined: Tue Feb 17, 2009 9:16 pm
Location: São Paulo, Brazil
Contact:

Re: Porting to python3

Postby yorik » Mon Jan 11, 2016 9:34 pm

yes, in master all integer checks are with PyInt_Check. However this is removed in py3 (all ints are longs). In all docs I've read, it said you could safely replace all PyInt_Check by PyLong_Check, that it would work for both... But apparently not :|

But I'll try to find more info before changing.
wmayer
Site Admin
Posts: 14588
Joined: Thu Feb 19, 2009 10:32 am

Re: Porting to python3

Postby wmayer » Tue Jan 12, 2016 10:24 pm

When doing the Py3 port take also into account to avoid spamming the sys.path:
viewtopic.php?f=22&t=13238
wmayer
Site Admin
Posts: 14588
Joined: Thu Feb 19, 2009 10:32 am

Re: Porting to python3

Postby wmayer » Sat Jan 16, 2016 5:11 pm

I have a new branch for you: https://github.com/wwmayer/FreeCAD/commits/py3-7
This fixes loading the FreeCAD GUI application.

Before starting to port the FreeCAD modules we should first cleanup a few things in master so that it doesn't diverge too much from the py3 branch.
So, can you incorporate my latest changes and then rebase on master?