Why doesn't freecad modules look like normal python modules?

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
User avatar
looo
Veteran
Posts: 3941
Joined: Mon Nov 11, 2013 5:29 pm

Why doesn't freecad modules look like normal python modules?

Post by looo »

A very simple question:

Freecad Modules look like this:

my_module/InitGui.py
my_module/Init.py


a nomal python module has this structure:

my_module/__init__.py


Why does freecad not use this structure (or something similar):

my_module/__init__.py (=Init.py)
my_module/Gui/__init__.py (=InitGui.py)

And why does freecad exec the Init.py/ InitGui.py at startup instead of importing them?

* some things that normally work for python modules won't work with freecad because of this:
- os.path.dirname(__file__) -> name '__file__' is not defined
- class Workbench can be used without import
User avatar
DeepSOIC
Veteran
Posts: 7896
Joined: Fri Aug 29, 2014 12:45 am
Location: used to be Saint-Petersburg, Russia

Re: Why doesn't freecad modules look like normal python modules?

Post by DeepSOIC »

Just a note:
when I needed __file__ in initGui.py, I got around by importing a dummy py file specific to my workbench, and getting its __file__ attribute. Probably ugly hack, but it works.
User avatar
yorik
Founder
Posts: 13659
Joined: Tue Feb 17, 2009 9:16 pm
Location: Brussels
Contact:

Re: Why doesn't freecad modules look like normal python modules?

Post by yorik »

FreeCAD modules are not python modules. Different things. Some modules have no python at all.
And also Init.py and InitGui.py are special files meant to be used by freecad, not imported by python. I think if we wanted to mimmick python working, we would create more problems for users than we would solve (why is this crap made like a python module if it's not a python module!)
You must see these files as little python helpers that "register" the module to freecad...

In a module dir, you can add python modules the way you describe without problems...
ickby
Veteran
Posts: 3116
Joined: Wed Oct 05, 2011 7:36 am

Re: Why doesn't freecad modules look like normal python modules?

Post by ickby »

And why does freecad exec the Init.py/ InitGui.py at startup instead of importing them?
If freecad would load all modules at startup it would be unbearingly slow. That is one of the nice features of the current module handling: the files are parsed to get the needed information (name, icons, import/export file types...) but the heavy loading is defered until the workbench is opened by the user.
User avatar
looo
Veteran
Posts: 3941
Joined: Mon Nov 11, 2013 5:29 pm

Re: Why doesn't freecad modules look like normal python modules?

Post by looo »

FreeCAD modules are not python modules. Different things.
What is the difference? For me a freecad-module written in python is a python-module which has dependencies on FreeCAD and optionally on FreeCADGui. A "import FreeCAD" and a "import FreeCADGui" will be enough to state that this modules are used with FreeCAD.
But FreeCAD introduce many confusion with the structure it uses:
for example if I import a InitGui.py from python it should definetly print an ImportError, but instead it prints an NameError (try import the InitGui.py of lattice Workbench). This is the problem with the exec() I think. THat is because Workbench does not have to be imported to get subcalssed.

Code: Select all

NameError: name 'Workbench' is not defined
Another question regarding this:
When type "import Draft" normal python would import the __init__.py from Draft, but in freecad the Draft/Draft.py will be imported. Freecad simply adds all the libraries to the python-path. If there exist two files with same name in different libraries, only one can be imported. Why not take the standard python way with a __init__.py and an import like 'from Draft import Draft'?

If freecad would load all modules at startup it would be unbearingly slow. That is one of the nice features of the current module handling: the files are parsed to get the needed information (name, icons, import/export file types...) but the heavy loading is defered until the workbench is opened by the user.
If we only rename the InitGui.py to __init__.py and instead of exec() use import this will lead to heavy loading?
Can you point me to the file where the parsing takes place?
ickby
Veteran
Posts: 3116
Joined: Wed Oct 05, 2011 7:36 am

Re: Why doesn't freecad modules look like normal python modules?

Post by ickby »

If we only rename the InitGui.py to __init__.py and instead of exec() use import this will lead to heavy loading?
Can you point me to the file where the parsing takes place?
I thought you want to load the module and not onyl the description file. I'm not a python expert, but in your proposed structure, is it possible to make a import(MyModule) which loads __init__ without it loading the heavy libraries? Because currently the heavy stuff is only loaded on import(MyModule) which is decoupled to the reading of the Init files. Loading libs may never happen if the user does not use the workbench in gui mode or if he never calls import(MyModule) in console mode, nonetheless the Init files need to be parsed always.
User avatar
looo
Veteran
Posts: 3941
Joined: Mon Nov 11, 2013 5:29 pm

Re: Why doesn't freecad modules look like normal python modules?

Post by looo »

is it possible to make a import(MyModule) which loads __init__ without it loading the heavy libraries
Python only import the __init__.py file. How much of your library is imported is dependent on the content of the __init__.py file. So for sure it is possible to specify which things should be loaded. I think there shouldn't be any difference to the InitGui.py approach.
nonetheless the Init files need to be parsed always.
by parsing you mean the exec of the InitGui.py/ Init.py ?
ickby
Veteran
Posts: 3116
Joined: Wed Oct 05, 2011 7:36 am

Re: Why doesn't freecad modules look like normal python modules?

Post by ickby »

Python only import the __init__.py file. How much of your library is imported is dependent on the content of the __init__.py file. So for sure it is possible to specify which things should be loaded. I think there shouldn't be any difference to the InitGui.py approach.
But then, how would you import the libraries? If import(myModule) read __init__ and does not load the libraries, how would the user than do this in console mode? How would the functionality then be loaded, if import(MyModule) does not do it?

Agian, I'm not a expert, and if this is special topic is sortet there may be many more other points which make it usefull to handle freecad modules different.
by parsing you mean the exec of the InitGui.py/ Init.py ?
Yes, they set stuff that is always needed by freecad, no matter if the module is importet or not
User avatar
looo
Veteran
Posts: 3941
Joined: Mon Nov 11, 2013 5:29 pm

Re: Why doesn't freecad modules look like normal python modules?

Post by looo »

Ok, my suggestions in the first post won't work, but how about this minimal module structure:

my_module
----__init__.py-->heavy stuff
----Init.py-->App related stuff
----InitGui.py-->Gui related stuff

+ changing the exec() in something like load_module(name, file, pathname, description)
+ not add every module-directory to the python-path.
+ rename shared objects that have also a python-module in something like "_my_module.so" and import them in the __init__.py (from _my_module import *)

results in:
"import my_module" will import the __init__.py and the heavy things --> normal python import without naming problems
the class Workbench has to be explicitly imported in the InitGui.py --> (No magic Workbench class, no confusing Errors)
User avatar
looo
Veteran
Posts: 3941
Joined: Mon Nov 11, 2013 5:29 pm

Re: Why doesn't freecad modules look like normal python modules?

Post by looo »

ok i missed that this FreeCADGuiInit.py file is somehow implemented in the freecad executable. So there is no possibility to import the workbench class from a python file?
Post Reply