From 2ff47374f2b27b8ab8c3cbee70a8d24214ca69aa Mon Sep 17 00:00:00 2001 From: looooo Date: Thu, 31 Aug 2017 23:27:53 +0200 Subject: [PATCH] new-style-modules: adding the possebility to import from "freecad" (this mostly aims at new modules and extension modules which want to use pip) - any module having problems with nameclashes can use this syntax (from freecad import module) - current imports still work (backward cobatibility) - python extension moduels can be installed (pip) to python std path (eg.: site-packages) - adding app, gui to the new freecad package: ``` from freecad import app from freecad import gui ``` - syntax for importing c++ extension will not change ``` import FreeCAD as App import FreeCADGui as Gui ``` --- src/App/FreeCADInit.py | 25 ++++++++++++++++++++++++- src/CMakeLists.txt | 1 + src/Ext/CMakeLists.txt | 6 ++++++ src/Ext/freecad/CMakeLists.txt | 20 ++++++++++++++++++++ src/Ext/freecad/__init__.py | 4 ++++ src/Gui/FreeCADGuiInit.py | 19 +++++++++++++++++++ 6 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 src/Ext/CMakeLists.txt create mode 100644 src/Ext/freecad/CMakeLists.txt create mode 100644 src/Ext/freecad/__init__.py diff --git a/src/App/FreeCADInit.py b/src/App/FreeCADInit.py index 010b355d98..102a136f0d 100644 --- a/src/App/FreeCADInit.py +++ b/src/App/FreeCADInit.py @@ -58,6 +58,8 @@ def InitApplications(): # Checking on FreeCAD module path ++++++++++++++++++++++++++++++++++++++++++ ModDir = FreeCAD.getHomePath()+'Mod' ModDir = os.path.realpath(ModDir) + ExtDir = FreeCAD.getHomePath()+'Ext' + ExtDir = os.path.realpath(ExtDir) BinDir = FreeCAD.getHomePath()+'bin' BinDir = os.path.realpath(BinDir) LibDir = FreeCAD.getHomePath()+'lib' @@ -75,6 +77,9 @@ def InitApplications(): #print FreeCAD.getHomePath() if os.path.isdir(FreeCAD.getHomePath()+'src\\Tools'): sys.path.append(FreeCAD.getHomePath()+'src\\Tools') + + + # Searching for module dirs +++++++++++++++++++++++++++++++++++++++++++++++++++ # Use dict to handle duplicated module names ModDict = {} @@ -116,7 +121,7 @@ def InitApplications(): # also add these directories to the sys.path to # not change the old behaviour. once we have moved to # proper python modules this can eventuelly be removed. - sys.path = [ModDir, Lib64Dir, LibDir] + sys.path + sys.path = [ModDir, Lib64Dir, LibDir, ExtDir] + sys.path for Dir in ModDict.values(): if ((Dir != '') & (Dir != 'CVS') & (Dir != '__init__.py')): @@ -141,6 +146,24 @@ def InitApplications(): else: Log('Init: Initializing ' + Dir + '(Init.py not found)... ignore\n') + extension_modules = [] + import pkgutil + import importlib + import freecad + for _, freecad_module_name, freecad_module_ispkg in pkgutil.iter_modules(freecad.__path__, "freecad."): + if freecad_module_ispkg: + Log('Init: Initializing ' + freecad_module_name + '\n') + freecad_module = importlib.import_module(freecad_module_name) + extension_modules += [freecad_module_name] + if any (module_name == 'init' for _, module_name, ispkg in pkgutil.iter_modules(freecad_module.__path__)): + try: + importlib.import_module(freecad_module_name + '.init') + Log('Init: Initializing ' + freecad_module_name + '... done\n') + except ImportError as error: + Err('During initialization the error ' + str(error) + ' occurred in ' + freecad_module_name + '\n') + else: + Log('Init: No init module found in ' + freecad_module_name + ', skipping\n') + Log("Using "+ModDir+" as module path!\n") # new paths must be prepended to avoid to load a wrong version of a library try: diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2a3af2a3ae..a7a4ebaae1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,6 +5,7 @@ add_subdirectory(Base) add_subdirectory(App) add_subdirectory(Main) add_subdirectory(Mod) +add_subdirectory(Ext) if(BUILD_GUI) add_subdirectory(Gui) configure_file(Doc/freecad.qhc ${CMAKE_BINARY_DIR}/doc/freecad.qhc COPYONLY) diff --git a/src/Ext/CMakeLists.txt b/src/Ext/CMakeLists.txt new file mode 100644 index 0000000000..56b6275224 --- /dev/null +++ b/src/Ext/CMakeLists.txt @@ -0,0 +1,6 @@ +# this directory is the entry point for extension modules. Any package +# installed to a directory "freecad" which is in sys.path can be imported +# with "from freecad import package" and is checked for a init_gui.py +# module, which is import at startup. (FreeCADGuiInit.py) + +add_subdirectory(freecad) \ No newline at end of file diff --git a/src/Ext/freecad/CMakeLists.txt b/src/Ext/freecad/CMakeLists.txt new file mode 100644 index 0000000000..4d0420aac4 --- /dev/null +++ b/src/Ext/freecad/CMakeLists.txt @@ -0,0 +1,20 @@ +EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} -c +"from distutils.sysconfig import get_python_lib; print(get_python_lib())" +OUTPUT_VARIABLE python_libs OUTPUT_STRIP_TRAILING_WHITESPACE ) +SET(PYTHON_MAIN_DIR ${python_libs}) + +SET(EXT_SRCS + __init__.py +) + +ADD_CUSTOM_TARGET(freecad_COPY_SOURCE ALL + SOURCES ${EXT_SRCS}) + +fc_copy_sources(freecad_COPY_SOURCE "${CMAKE_BINARY_DIR}/Ext/freecad" ${EXT_SRCS}) + +INSTALL( + FILES + __init__.py + DESTINATION + Ext/freecad +) \ No newline at end of file diff --git a/src/Ext/freecad/__init__.py b/src/Ext/freecad/__init__.py new file mode 100644 index 0000000000..b6f98eb927 --- /dev/null +++ b/src/Ext/freecad/__init__.py @@ -0,0 +1,4 @@ +import pkgutil +__path__ = pkgutil.extend_path(__path__, __name__) + +import FreeCAD as app \ No newline at end of file diff --git a/src/Gui/FreeCADGuiInit.py b/src/Gui/FreeCADGuiInit.py index 55ab05c48b..0fbe46f932 100644 --- a/src/Gui/FreeCADGuiInit.py +++ b/src/Gui/FreeCADGuiInit.py @@ -131,8 +131,27 @@ def InitApplications(): Log('Init: Initializing ' + Dir + '(InitGui.py not found)... ignore\n') + import pkgutil + import importlib + import freecad + freecad.gui = FreeCADGui + for _, freecad_module_name, freecad_module_ispkg in pkgutil.iter_modules(freecad.__path__, "freecad."): + if freecad_module_ispkg: + Log('Init: Initializing ' + freecad_module_name + '\n') + freecad_module = importlib.import_module(freecad_module_name) + if any (module_name == 'init_gui' for _, module_name, ispkg in pkgutil.iter_modules(freecad_module.__path__)): + try: + importlib.import_module(freecad_module_name + '.init_gui') + Log('Init: Initializing ' + freecad_module_name + '... done\n') + except ImportError as error: + Err('During initialization the error ' + str(error) + ' occurred in ' + freecad_module_name + '\n') + else: + Log('Init: No init_gui module found in ' + freecad_module_name + ', skipping\n') + Log ('Init: Running FreeCADGuiInit.py start script...\n') + + # init the gui # signal that the gui is up