[Solved] Python shell in FreeCAD and sys.executable value

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
joha2
Posts: 303
Joined: Tue Oct 11, 2016 9:48 pm

[Solved] Python shell in FreeCAD and sys.executable value

Post by joha2 »

Heyhey

I already asked that question in the Python coding subforum, but there is no answer available until now; maybe it is the wrong subforum:

For execution of Fenics code within FreeCAD directly from the shell or as a macro it is problematic that sys.executable is set to the FreeCAD binary.
Is there a good reason to set sys.executable to the FreeCAD binary? Can that be changed? (Either in the preferences or hard coded?)
Is there a possibility to grab the path of the Python executable from the underlying OS?

Best wishes
Johannes
Last edited by joha2 on Wed Apr 03, 2019 7:59 pm, edited 3 times in total.
wmayer
Founder
Posts: 20319
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Python shell in FreeCAD and sys.executable value

Post by wmayer »

For execution of Fenics code within FreeCAD directly from the shell or as a macro it is problematic that sys.executable is set to the FreeCAD binary.
Why?
Is there a possibility to grab the path of the Python executable from the underlying OS?
I haven't seen a method to get the full path name including the Python executable name. But there is a way to get the path the Python executable is located in.

Code: Select all

import distutils
distutils.sysconfig.PREFIX
joha2
Posts: 303
Joined: Tue Oct 11, 2016 9:48 pm

Re: Python shell in FreeCAD and sys.executable value

Post by joha2 »

Hi Werner,
wmayer wrote: Fri Apr 20, 2018 8:06 am
For execution of Fenics code within FreeCAD directly from the shell or as a macro it is problematic that sys.executable is set to the FreeCAD binary.
Why?
Because if I perform Fenics code which needs so called Expression classes, there is a subprocess started compiling the appropriate C++ code (Just-In-Time compiler) with the help of cmake. In the CMakeList.txt file there is a line

Code: Select all

set(PYTHON_EXECUTABLE /home/fenics/shared/FreeCAD)
which seems to depend on sys.executable (in the shared folder FreeCAD is a symlink). If I set it manually to /usr/bin/python the JIT compiling works without problems. The main problem for the JIT compiler and its underlying cmake process seems to be that the FreeCAD binary just not behaves like a classical python binary and therefore the sys.executable string is misleading. I suggest to make the sys.executable string for the FC Python console changeable in the preferences (set it to a userdefined value, or check environment for binary).
wmayer wrote: Fri Apr 20, 2018 8:06 am
Is there a possibility to grab the path of the Python executable from the underlying OS?
I haven't seen a method to get the full path name including the Python executable name. But there is a way to get the path the Python executable is located in.

Code: Select all

import distutils
distutils.sysconfig.PREFIX
Maybe this could be used to encapsulate the check for the external Python binary in a forthcoming Fenics workbench/solver. Thanks for the hint.

Best wishes
Johannes
User avatar
looo
Veteran
Posts: 3941
Joined: Mon Nov 11, 2013 5:29 pm

Re: Python shell in FreeCAD and sys.executable value

Post by looo »

sys.executable of ipython, jupyter-notebook and qt-console also point to the python interpreter.

edit:
in blender sys.executable points to '/usr/bin/blender'
joha2
Posts: 303
Joined: Tue Oct 11, 2016 9:48 pm

Re: Python shell in FreeCAD and sys.executable value

Post by joha2 »

looo wrote: Fri Apr 20, 2018 5:28 pm sys.executable of ipython, jupyter-notebook and qt-console also point to the python interpreter.

edit:
in blender sys.executable points to '/usr/bin/blender'
So there are different default settings in different programs. But how about FC? Why is this value chosen as it is? And does it make sense to let the user change it? Best wishes
Johannes
wmayer
Founder
Posts: 20319
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Python shell in FreeCAD and sys.executable value

Post by wmayer »

The point is that FreeCAD uses Python's C API and there it must initialize it in order to use its functions. Part of the initialization process is to call the function Py_SetProgramName(argv[0]); and that's how it happens that the executable name is set to the FreeCAD executable.
The main problem for the JIT compiler and its underlying cmake process seems to be that the FreeCAD binary just not behaves like a classical python binary and therefore the sys.executable string is misleading.
Can you figure out what are the arguments passed to the FreeCAD executable? If it's not too complicated it might be possible to make FreeCAD behave at least in this scenario as a classical Python executable.
I suggest to make the sys.executable string for the FC Python console changeable in the preferences (set it to a userdefined value, or check environment for binary).
IMO, this should be avoided. There must be a solution that works out of the box without requesting the user to set the correct path.
joha2
Posts: 303
Joined: Tue Oct 11, 2016 9:48 pm

Re: Python shell in FreeCAD and sys.executable value

Post by joha2 »

wmayer wrote: Sat Apr 21, 2018 8:34 am The point is that FreeCAD uses Python's C API and there it must initialize it in order to use its functions. Part of the initialization process is to call the function Py_SetProgramName(argv[0]); and that's how it happens that the executable name is set to the FreeCAD executable.
The main problem for the JIT compiler and its underlying cmake process seems to be that the FreeCAD binary just not behaves like a classical python binary and therefore the sys.executable string is misleading.
Can you figure out what are the arguments passed to the FreeCAD executable? If it's not too complicated it might be possible to make FreeCAD behave at least in this scenario as a classical Python executable.
Yes this seems to be a good solution. I injected a simple print_args C++ program into the CMakeList.txt file and performed cmake.
The output just comes from the Python version check.

Code: Select all

arg # 0 : /home/fenics/shared/print_args
arg # 1 : -c
arg # 2 : import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))
It seems that in this case it would be sufficient for FreeCAD to perform the Python code given after a -c argument (like for the classical Python binary). But I am not sure if this is sufficient for further building steps, but let's see. Would it be possible for FC to just interpret code after a -c argument?
wmayer wrote: Sat Apr 21, 2018 8:34 am
I suggest to make the sys.executable string for the FC Python console changeable in the preferences (set it to a userdefined value, or check environment for binary).
IMO, this should be avoided. There must be a solution that works out of the box without requesting the user to set the correct path.
Yes I also had the feeling that tihs is an unelegant solution, it is just a quick and dirty override. So let's abandon this solution :-)

Best wishes
Johannes
wmayer
Founder
Posts: 20319
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Python shell in FreeCAD and sys.executable value

Post by wmayer »

If you build FreeCAD yourself you can try this code snippet:

Code: Select all

        PyObject* prefix = PySys_GetObject("exec_prefix");
#if PY_MAJOR_VERSION >= 3
        PyObject *path = PyUnicode_FromFormat("%U/bin/python", prefix);
#else
        PyObject *path = PyString_FromFormat("%s/bin/python", PyString_AsString(prefix));
#endif
        PySys_SetObject("executable", path);
        Py_DECREF(path);
Just put it inside the function InterpreterSingleton::init before the line PythonStdOutput::init_type();

Alternatively you can also do:

Code: Select all

sys.executable=sys.exec_prefix+"/bin/python"
wherever you want.
wmayer
Founder
Posts: 20319
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Python shell in FreeCAD and sys.executable value

Post by wmayer »

git commit b440dc8 now supports the standard Python behaviour.
joha2
Posts: 303
Joined: Tue Oct 11, 2016 9:48 pm

Re: Python shell in FreeCAD and sys.executable value

Post by joha2 »

Nice, now the Fenics macro I wrote with some simple expressions works out of the box! Thanks Werner for implementing!
Next step: Try to solve more complex PDE problems.

Best regards
Johannes

For everybody else: This thread is part of the effort to implement Fenics into FreeCAD: https://forum.freecadweb.org/viewtopic.php?f=18&t=4677
Post Reply