Ha ha ha! Stupid me. You are right. But at least what I said applies to FreeCADGui, then.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:
Porting to python3
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Be nice to others! Respect the FreeCAD code of conduct!
Re: Porting to python3
Re: Porting to python3
No. That's what I wanted to explain. FreeCADApp.so (or .dll) is not a Python module. However, internally inside Application::Application we create a Python module called "FreeCAD" and add the classes Vector, Matrix, ... to it and a few things more. You don't need this "init" function here because you cannot import FreeCADApp via Python.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.
To see if the port for https://github.com/yorikvanhavre/FreeCA ... n.cpp#L189 is correct you should start FreeCADCmd. Does this crash at startup or not? The point with the Python3 API is that we have to do something (we return it to Python) with the pointer we get from PyModule_Create when using it inside an init function.
So, maybe we also have to hand over this pointer to Python we create inside Application::Application.
Re: Porting to python3
Aah okay now I understood. importing the FreeCAD module from an external console uses the stuff in mainpy.cpp, which isn't used when you launch FreeCAD directly...
Okay, let's leave mainpy for later then. One headache at a time
I fixed a couple of more errors, the latest stuff is now on https://github.com/yorikvanhavre/FreeCAD/tree/py3-5
So far, it compiles with both python2 and 3 (with all modules disabled) and doesn't crash anymore when running FreeCADCmd. However, some python stuff still fails to initialize and the app terminates...
With py2:
with py3:
The errors are different but it might be the same thing. Couldn't find what's wrong yet...
Okay, let's leave mainpy for later then. One headache at a time
I fixed a couple of more errors, the latest stuff is now on https://github.com/yorikvanhavre/FreeCAD/tree/py3-5
So far, it compiles with both python2 and 3 (with all modules disabled) and doesn't crash anymore when running FreeCADCmd. However, some python stuff still fails to initialize and the app terminates...
With py2:
Code: Select all
~/Sources/build/fcpy2> bin/FreeCADCmd
FreeCAD 0.16, Libs: 0.16R6179 +12 (Git)
(c) Juergen Riegel, Werner Mayer, Yorik van Havre 2001-2015
##### #### ### ####
# # # # # #
# ## #### #### # # # # #
#### # # # # # # # ##### # #
# # #### #### # # # # #
# # # # # # # # # ## ## ##
# # #### #### ### # # #### ## ## ##
Initialization of FreeCAD failed:
While initializing FreeCAD the following exception occurred: ''ParameterGrp' object has no attribute 'GetString''
Python is searching for its runtime files in the following directories:
/usr/lib/python2.7/:/usr/lib/python2.7/plat-x86_64-linux-gnu:/usr/lib/python2.7/lib-tk:/usr/lib/python2.7/lib-old:/usr/lib/python2.7/lib-dynload
Python version information:
2.7.11 (default, Dec 9 2015, 00:29:25)
[GCC 5.3.1 20151205]
Please contact the application's support team for more information.
Code: Select all
~/Sources/build/fcpy3> bin/FreeCADCmd
FreeCAD 0.16, Libs: 0.16R6179 +12 (Git)
(c) Juergen Riegel, Werner Mayer, Yorik van Havre 2001-2015
##### #### ### ####
# # # # # #
# ## #### #### # # # # #
#### # # # # # # # ##### # #
# # #### #### # # # # #
# # # # # # # # # ## ## ##
# # #### #### ### # # #### ## ## ##
Initialization of FreeCAD failed:
While initializing FreeCAD the following exception occurred: 'No module named 'FreeCAD''
Python is searching for its runtime files in the following directories:
0x1f25fd0
Python version information:
3.5.1 (default, Dec 10 2015, 14:34:41)
[GCC 5.3.1 20151207]
Please contact the application's support team for more information.
Re: Porting to python3
I think i's time that I start to compile your branch. Is there anything I have to be aware of?
Re: Porting to python3
wmayer wrote:I think i's time that I start to compile your branch
Nope... I just untick all modules in cmake-gui, and when compiling with python3 just change all python2-related libs to python3. Make sure you're using minimum version 3.5 (3.5 received new utf8-to-unicode conversion tools that we'd be foolish to refuse)wmayer wrote:Is there anything I have to be aware of?
All the python3-related commits are prefixed with py3. Most of the changes are actually always the same thing, basically either:
- pystring is removed in python3, so everything pystring-related becomes pyunicode when using py3
- the creation of python classes has changed a little bit (it uses other macros, a couple of builtin methods have been removed, getattr/setattr are replaced by getattro/setattro, etc..). This is the part that affects both python2 and 3, and most certainly where I screwed something Fortunately it doesn't happen in a lot of places, basically almost everything is in Base/PyObjectBase and Tools/generate*
- the creation of modules is different too, but this normally doesn't affect py2 because they are in different #if clauses
Re: Porting to python3
I came one step further. It's exactly like I assumed that we have to do something with the pointer we get from PyModule_Create. It isn't obvious and I didn't find anything in the documentation but I know that Python's sys module is written in C and it's a built-in module. So, I searched through the source code and found the undocumented function _PyImport_FixupBuiltin.
So, we have to add this line:
However, FreeCADCmd still crashes afterwards but when commenting out the line
the application works. Then you can do an "import FreeCAD" and use its module functions.
So, we have to add this line:
Code: Select all
_PyImport_FixupBuiltin(pAppModule, "FreeCAD");
Code: Select all
Interpreter().runString(Base::ScriptFactory().ProduceScript("FreeCADInit"));
Re: Porting to python3
When
is enabled then the error message is
EDIT:
When you pass a string to the Log function it raises an exception. If you pass a number or None then everything works as expected.
Code: Select all
Interpreter().runString(Base::ScriptFactory().ProduceScript("FreeCADInit"));
So, this means something is wrong with https://github.com/yorikvanhavre/FreeCA ... e.cpp#L524<built-in function PrintLog> returned a result with an error set
EDIT:
When you pass a string to the Log function it raises an exception. If you pass a number or None then everything works as expected.
Re: Porting to python3
Ok I added the fixup function too just after the PyModule_Create lines, indeed now the module starts!
Crazy, when looking for that function name on the net, you find nothing... Only you are bold enough to go dig into the python code itself Werner!
So yes the problem is probably in neither of the two places but at something more fundamental like the console init, or the interpreter init (I had some trouble to find what to do there too).
It's really not easy to find similar cases on the net...
Crazy, when looking for that function name on the net, you find nothing... Only you are bold enough to go dig into the python code itself Werner!
Now this is a similar error to when compiling the branch with python2, but not at the same place:wmayer wrote:When
Interpreter().runString(Base::ScriptFactory().ProduceScript("FreeCADInit"));
is enabled then the error message is
<built-in function PrintLog> returned a result with an error set
Code: Select all
While initializing FreeCAD the following exception occurred: ''ParameterGrp' object has no attribute 'GetString''
It's really not easy to find similar cases on the net...
Re: Porting to python3
The function responsible to load the shared library and invoke its PyInit entry point is _PyImport_LoadDynamicModuleWithSpec. If the initialization succeeded it calls _PyImport_FixupExtensionObject to let te interpreter know the new module. And this latter function is invoked by _PyImport_FixupBuiltin.Crazy, when looking for that function name on the net, you find nothing... Only you are bold enough to go dig into the python code itself Werner!
I assume since these functions start with an underscore they are considered for internal purposes only and that's why they are not documented.
I don't think there is something wrong with interpreter init but the init of the ParameterGrp class.While initializing FreeCAD the following exception occurred: ''ParameterGrp' object has no attribute 'GetString''
When I want to clone your branch on github and send you pull requests what exactly do I have to do? Until now I never did something on github.
Re: Porting to python3
Maybe, but I'm not so sure.. This is basically what changed in that file:wmayer wrote:I don't think there is something wrong with interpreter init but the init of the ParameterGrp class.
https://github.com/yorikvanhavre/FreeCA ... f12330b72c
Not much really, unless there is some obvious mistake (or the switch from getattr -> getattro is flawed, but from what I've read it was recommended already well before python3), but I haven't found it yet...
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 rightwmayer wrote:When I want to clone your branch on github and send you pull requests what exactly do I have to do? Until now I never did something on github.
Otherwise using the github stuff is easy too, just go to https://github.com/FreeCAD/FreeCAD and click the "fork" button above, it will copy the whole repo to your own github account. Then you'll need to add the URL of this new repo of yours to your local remotes, and you can force-push any branch to there instead of the default with
Code: Select all
git push mygithub branchname
If you fork my repo instead of the official FreeCAD one, github will detect that you worked on one of my branches, and will offer you to do an automatic pull request whenever you push something there (just visit your repo page on github after a push). But this is just candy, I can grab your branch myself of course.
The only problem with having a copy of the FreeCAD repo on your own github account is the hassle to keep both up to date... I know there are ways to make it automatically push anything to both, but I was too lazy, and until today I always do "git push && git push github" whenever I push something...