Subfolder for Python modules

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

Re: Subfolder for Python modules

Postby wmayer » Tue Mar 07, 2017 8:20 am

Out of curiosity is it possible to have something like this:

Code: Select all

from FreeCAD.Fem.PyGui import FemCommands

instead of

Code: Select all

from Fem.PyGui import FemCommands

?
looo
Posts: 788
Joined: Mon Nov 11, 2013 5:29 pm

Re: Subfolder for Python modules

Postby looo » Tue Mar 07, 2017 8:40 am

as we use multiple directories to store packages, I think this isn't that easy to achieve. Maybe it is possible with the __path__ variable of a module: https://docs.python.org/2/tutorial/modu ... irectories

regarding this line https://github.com/FreeCAD/FreeCAD/blob ... nit.py#L91 it should already be possible.

Indeed, I wasn't aware of this

Code: Select all

>>> from FreeCAD import FemTools
>>>


So after moving to proper importing this is easily possible. Also the solution of DeepSoic would work, but I still do not like it that much :D

I think we should make it at least possible for newcomers to create proper python packages for freecad. Therfor we can simple check if a __init__.py is placed in the package. If it is we do not add the dir to the sys.path.
wmayer
Site Admin
Posts: 11357
Joined: Thu Feb 19, 2009 10:32 am

Re: Subfolder for Python modules

Postby wmayer » Tue Mar 07, 2017 9:53 am

As you may know for the PartDesign module we do it (almost) correctly. The C++ module is named _PartDesgn.so (or .pyd) and you can import a sub-module e.g. with:

Code: Select all

from PartDesign.WizardShaft import ShaftFeature as sf


regarding this line https://github.com/FreeCAD/FreeCAD/blob ... nit.py#L91 it should already be possible.

This allows us to write

Code: Select all

from FreeCAD import Fem

but trying to

Code: Select all

from FreeCAD import PartDesign

fails.
However,

Code: Select all

from FreeCAD import _PartDesign
works.
looo
Posts: 788
Joined: Mon Nov 11, 2013 5:29 pm

Re: Subfolder for Python modules

Postby looo » Tue Mar 07, 2017 10:20 am

wmayer wrote:but trying to

Code: Select all

from FreeCAD import PartDesign

fails.
However,

Code: Select all

from FreeCAD import _PartDesign
works.


You are right, PartDesign is a good example. There we have already a __init__.py.

It isn't possible to import via

Code: Select all

from FreeCAD import PartDesign
because FreeCAD.__path__ doesn't contain the dir containing the PartDesign directory.
But

Code: Select all

from FreeCAD import WizardShaft
works... So for PartDesign we simple add the wrong dirs to FreeCAD.__path__

wmayer wrote:This allows us to write

Code: Select all

from FreeCAD import Fem


No this isn't possible for me. only the files inside the Fem-dir can be imported eg.:

Code: Select all

from FreeCAD import FemTools


I have experimented a bit with the Init files. To make

Code: Select all

from FreeCAD import module
work we need to change the FreeCAD.__path__ variable. See this commit: https://github.com/looooo/FreeCAD/commi ... 5c6bdcee8a
wmayer
Site Admin
Posts: 11357
Joined: Thu Feb 19, 2009 10:32 am

Re: Subfolder for Python modules

Postby wmayer » Tue Mar 07, 2017 10:26 am

OK, I got it working now.

Code: Select all

FreeCAD.__path__=[FreeCAD.getHomePath()+'Mod']
from FreeCAD.PartDesign.WizardShaft import ShaftFeature as sf   # works


So, as the first step we can change this line https://github.com/FreeCAD/FreeCAD/blob ... nit.py#L91 to only list the Mod directory. In the second step we do as looo suggested and add the "_" prefix to all Python extension modules and add the __init__.py files.

This way the current behaviour still works but all packages can be moved to the new style. Once this is finished we can change the code to not add all paths to sys.path.
User avatar
yorik
Site Admin
Posts: 8684
Joined: Tue Feb 17, 2009 9:16 pm
Location: São Paulo, Brazil
Contact:

Re: Subfolder for Python modules

Postby yorik » Tue Mar 07, 2017 1:42 pm

wmayer wrote:So, as the first step we can change this line https://github.com/FreeCAD/FreeCAD/blob ... nit.py#L91 to only list the Mod directory. In the second step we do as looo suggested and add the "_" prefix to all Python extension modules and add the __init__.py files.

This way the current behaviour still works but all packages can be moved to the new style. Once this is finished we can change the code to not add all paths to sys.path.


+1. Seems much more pythonic.
triplus
Posts: 5016
Joined: Mon Dec 12, 2011 4:45 pm

Re: Subfolder for Python modules

Postby triplus » Tue Mar 07, 2017 7:07 pm

And after the change every piece of code out there using "the old way of importing modules" stops to work?
looo
Posts: 788
Joined: Mon Nov 11, 2013 5:29 pm

Re: Subfolder for Python modules

Postby looo » Tue Mar 07, 2017 7:54 pm

And after the change every piece of code out there using "the old way of importing modules" stops to work?
[

Hmm, we do not have to drop the old way of importing, but to solve the naming issue we should move all modules to the new way. Like I have said we can choose in which way a modul is loaded by checking for the __init__.py. We can also print a warning that old style will be removed in the future...
wmayer
Site Admin
Posts: 11357
Joined: Thu Feb 19, 2009 10:32 am

Re: Subfolder for Python modules

Postby wmayer » Wed Mar 08, 2017 7:56 am

Like I have said we can choose in which way a modul is loaded by checking for the __init__.py. We can also print a warning that old style will be removed in the future...

So, this means we can raise a warning if someone does

Code: Select all

import Fem
instead of

Code: Select all

from FreeCAD import Fem
? How does this exactly work?
User avatar
bernd
Posts: 3924
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland

Re: Subfolder for Python modules

Postby bernd » Wed Mar 08, 2017 3:18 pm

@looo and wmayer:

just to get it the right way. With the changes proposed by you and wmayer we would NOT need to change the directory names PyGui and PyObjects for the internal object class modules. All workbenches (modules) could use these directory names for their internal object module classes, without name clashing? For sure only if they would like too :)