FreeCAD / homebrew-freecad

Homebrew recipes for FreeCAD
54 stars 34 forks source link

freecad@0.21.2_py310: runtime issue with PySide #558

Open ipatch opened 2 months ago

ipatch commented 2 months ago

it seems the most recent bottle when installed on m1 hardware is having issues with workbenches that require the "proxy" PySide module setup by freecad itself as the native name for the pyside2 module is PySide2 and the native module for pyside6 is PySide6. freecad it self sets up a "proxy" python module that should allow either the PySide2 or PySide6 module to be referenced / used from the PySide module (from what i understand).

14:06:22  (qt.qpa.fonts) Populating font family aliases took 61 ms. Replace uses of missing font family "Courier" with one that exists to avoid this cost.
14:06:24  During initialization the error "Failed to wrap widget" occurred in /Users/chris/homebrew/Cellar/freecad@0.21.2_py310/0.21.2/Mod/Tux/InitGui.py
14:06:24  Please look into the log file for further information
14:09:26  Failed to wrap widgetError: Initializing one or more of the Draft modules failed, Draft will not work as expected.
23:09:26  Failed to wrap widget
13:09:26  Traceback (most recent call last):
  File "<string>", line 142, in Initialize

so workbenches like Draft and Arch will not properly load.

image

image

ipatch commented 2 months ago

so i attempted to resolve this issue yesterday by modifying the cmake file that sets up pyside for the freecad package by installing / placing the freecad "proxy" PySide module in the same path / dir structure as the conda package in hopes that the PySide module would be in a default search path for freecad when launching, but however i'm still getting an error of "can't wrap widget" when attempting to load a workbench that relies on the freecad PySide module. 🤨

however when running freecad and then issue the below commands in the freecad console i do not see an errors related loading of either of the modules.

>>> import PySide
>>> import PySide2
>>> import shiboken2

i did / do not get any errors when loading those modules in the python console.


20:09:58  Traceback (most recent call last):
20:09:58    File "/Users/chris/homebrew/Cellar/freecad@0.21.2_py310/0.21.2/Mod/AddonManager/AddonManager.py", line 171, in launch
20:09:58      self.dialog = FreeCADGui.PySideUic.loadUi(
20:09:58    File "<string>", line 4, in <module>
20:09:58  RuntimeError: Failed to wrap widget
ipatch commented 2 months ago

freecad forum post referencing this github issue,

https://forum.freecad.org/viewtopic.php?t=90195

ipatch commented 2 months ago

heres a little followup to this ongoing issue. i'm able to interact with the Draft workbench using freecad in a headless mode, as seen in the below python console session. i'm also able to open the document using the same built and installed freecad using the GUI.

finally the below error message occurs in the GUI when i attempt to load the Draft Workbench 🤷‍♂️

>>> import PySide2
>>> import freecad
>>> import PySide
>>> Gui.activeWorkbench().Name
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'Gui' is not defined
>>> ^[[A^[[A^[[A^C
KeyboardInterrupt
>>> ^[[A^C
KeyboardInterrupt
>>> Gui.runCommand('Std_Workbench',6)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'Gui' is not defined
>>> import FreeCADGui as Gui
>>> Gui.activateWorkbench("PartDesign")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'FreeCADGui' has no attribute 'activateWorkbench'
>>> doc = App.newDocument()
>>> import PartDesign
>>> import Draft
>>> import Tux
>>> doc.saveAs("/Users/chris/Desktop/foo1.FCStd")
>>> start_point = App.Vector(0, 0, 0)
>>> end_point = App.Vector(10, 10, 0)
>>> line = Draft.makeLine(start_point, end_point)
>>> doc.recompute()
1
>>> doc^[[A^C
KeyboardInterrupt
>>> doc.saveAs("/Users/chris/Desktop/foo1.FCstd")
>>>

image


on going error message

16:08:27  (qt.qpa.fonts) Populating font family aliases took 58 ms. Replace uses of missing font family "Courier" with one that exists to avoid this cost. 
16:08:29  During initialization the error "Failed to wrap widget" occurred in /Users/chris/homebrew/Cellar/freecad@0.21.2_py310/0.21.2/Mod/Tux/InitGui.py
16:08:29  Please look into the log file for further information
16:35:43  QMainWindowLayout::tabPosition called with out-of-bounds value '0'
16:40:06  Failed to wrap widgetError: Initializing one or more of the Draft modules failed, Draft will not work as expected.
16:40:06  Failed to wrap widget
16:40:06  Traceback (most recent call last):
  File "<string>", line 142, in Initialize
ipatch commented 2 months ago

doing some more logging, 🧐

17:43:23  Failed to wrap widgetError: Initializing one or more of the Draft modules failed, Draft will not work as expected.
17:43:23  Failed to wrap widget
17:43:23  Traceback (most recent call last):
  File "<string>", line 142, in Initialize

18:26:40  Failed to wrap widget
18:26:40  Traceback (most recent call last):
  File "<string>", line 52, in Initialize
  File "/Users/chris/homebrew/Cellar/pyside2@5.15.11_py310/5.15.11/lib/python3.10/site-packages/shiboken2/files.dir/shibokensupport/feature.py", line 139, in _import
    return original_import(name, *args, **kwargs)
  File "/Users/chris/homebrew/Cellar/freecad@0.21.2_py310/0.21.2/Mod/Draft/DraftTools.py", line 51, in <module>
    import DraftGui  # Initializes the DraftToolBar class
  File "/Users/chris/homebrew/Cellar/pyside2@5.15.11_py310/5.15.11/lib/python3.10/site-packages/shiboken2/files.dir/shibokensupport/feature.py", line 139, in _import
    return original_import(name, *args, **kwargs)
  File "/Users/chris/homebrew/Cellar/freecad@0.21.2_py310/0.21.2/Mod/Draft/DraftGui.py", line 1884, in <module>
    FreeCADGui.draftToolBar = DraftToolBar()
  File "/Users/chris/homebrew/Cellar/freecad@0.21.2_py310/0.21.2/Mod/Draft/DraftGui.py", line 302, in __init__
    mw = FreeCADGui.getMainWindow()
ipatch commented 2 months ago
╰─λ freecadcmd                                                                                                          0 (0.573s)
FreeCAD 0.21.2, Libs: 0.21.2RUnknown
(c) Juergen Riegel, Werner Mayer, Yorik van Havre and others 2001-2023
FreeCAD is free and open-source software licensed under the terms of LGPL2+ license.
FreeCAD wouldn't be possible without FreeCAD community.
  #####                 ####  ###   ####
  #                    #      # #   #   #
  #     ##  #### ####  #     #   #  #   #
  ####  # # #  # #  #  #     #####  #   #
  #     #   #### ####  #    #     # #   #
  #     #   #    #     #    #     # #   #  ##  ##  ##
  #     #   #### ####   ### #     # ####   ##  ##  ##

[FreeCAD Console mode <Use Ctrl-D (i.e. EOF) to exit.>]
>>> import FreeCADGui as Gui
>>> mw = Gui.getMainWindow()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'FreeCADGui' has no attribute 'getMainWindow'. Did you mean: 'showMainWindow'?
>>>

https://github.com/FreeCAD/FreeCAD/blob/b9bfa5c5507506e4515816414cd27f4851d00489/src/Mod/Draft/DraftGui.py#L302

chennes commented 2 months ago

You are importing gui code from the CLI version?

ipatch commented 2 months ago

i reran a few of those commands from a GUI, and am still getting the below errors.

image


Python 3.10.14 (main, Mar 19 2024, 21:46:16) [Clang 15.0.0 (clang-1500.1.0.2.5)] on darwin
Type 'help', 'copyright', 'credits' or 'license' for more information.
>>> # Gui.runCommand('Std_Workbench',6)
>>> # Gui.runCommand('Std_ViewStatusBar',1)
>>> import FreeCADGui as Gui
>>> Gui.getMainWindow
<built-in function getMainWindow>
>>> import Draft
>>> import DraftGui
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/Users/chris/homebrew/lib/python3.10/site-packages/shiboken2/files.dir/shibokensupport/feature.py", line 139, in _import
    return original_import(name, *args, **kwargs)
  File "/Users/chris/homebrew/Cellar/freecad@0.21.2_py310/0.21.2/Mod/Draft/DraftGui.py", line 1884, in <module>
    FreeCADGui.draftToolBar = DraftToolBar()
  File "/Users/chris/homebrew/Cellar/freecad@0.21.2_py310/0.21.2/Mod/Draft/DraftGui.py", line 302, in __init__
    mw = FreeCADGui.getMainWindow()
RuntimeError: Failed to wrap widget
>>>
ipatch commented 1 week ago

little follow up to this issue. when building either a bottled version for macos m1, or building via cmake from a cli i'm still getting the above mentioned errors related to the PySide python proxy module, when building and running freecad 1.0.0 rc2.

opening up a freecad repl on the m1 i get the below output,

╰─λ ~/.local/freecad-rc2/MacOS/FreeCADCmd                                                                             130 (8.771s)
FreeCAD 1.0.0, Libs: 1.0.0RC2R38806 (Git)
(C) 2001-2024 FreeCAD contributors
FreeCAD is free and open-source software licensed under the terms of LGPL2+ license.

[FreeCAD Console mode <Use Ctrl-D (i.e. EOF) to exit.>]
>>> print(sys.path)
['/Users/chris/.local/freecad-rc2/Mod/Help', '/Users/chris/.local/freecad-rc2/Mod/Material', '/Users/chris/.local/freecad-rc2/Mod/Import', '/Users/chris/.local/freecad-rc2/Mod/Part', '/Users/chris/.local/freecad-rc2/Mod/Tux', '/Users/chris/.local/freecad-rc2/Mod/PartDesign', '/Users/chris/.local/freecad-rc2/Mod/BIM', '/Users/chris/.local/freecad-rc2/Mod/Measure', '/Users/chris/.local/freecad-rc2/Mod/Points', '/Users/chris/.local/freecad-rc2/Mod/AddonManager', '/Users/chris/.local/freecad-rc2/Mod/CAM', '/Users/chris/.local/freecad-rc2/Mod/Idf', '/Users/chris/.local/freecad-rc2/Mod/Inspection', '/Users/chris/.local/freecad-rc2/Mod/Robot', '/Users/chris/.local/freecad-rc2/Mod/Surface', '/Users/chris/.local/freecad-rc2/Mod/OpenSCAD', '/Users/chris/.local/freecad-rc2/Mod/Start', '/Users/chris/.local/freecad-rc2/Mod/Sketcher', '/Users/chris/.local/freecad-rc2/Mod/Show', '/Users/chris/.local/freecad-rc2/Mod/MeshPart', '/Users/chris/.local/freecad-rc2/Mod/Assembly', '/Users/chris/.local/freecad-rc2/Mod/TechDraw', '/Users/chris/.local/freecad-rc2/Mod/Web', '/Users/chris/.local/freecad-rc2/Mod/Spreadsheet', '/Users/chris/.local/freecad-rc2/Mod/Fem', '/Users/chris/.local/freecad-rc2/Mod/Test', '/Users/chris/.local/freecad-rc2/Mod/Plot', '/Users/chris/.local/freecad-rc2/Mod/ReverseEngineering', '/Users/chris/.local/freecad-rc2/Mod/Draft', '/Users/chris/.local/freecad-rc2/Mod/Mesh', '/Users/chris/.local/freecad-rc2/Mod', '/Users/chris/.local/freecad-rc2/lib', '/Users/chris/.local/freecad-rc2/Ext', '/Users/chris/homebrew/Cellar/python@3.12/3.12.7_1/Frameworks/Python.framework/Versions/3.12/lib/python312.zip', '/Users/chris/homebrew/Cellar/python@3.12/3.12.7_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12', '/Users/chris/homebrew/Cellar/python@3.12/3.12.7_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/lib-dynload', '/Users/chris/homebrew/Cellar/python@3.12/3.12.7_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages', '/Users/chris/homebrew/Cellar/coin3d@4.0.3_py312/4.0.3/lib/python3.12/site-packages', '/Users/chris/homebrew/Cellar/med-file@4.1.1_py312/4.1.1_1/lib/python3.12/site-packages', '/Users/chris/homebrew/Cellar/numpy@2.1.1_py312/2.1.1/lib/python3.12/site-packages', '/Users/chris/homebrew/Cellar/pybind11_py312/2.13.6/libexec/lib/python3.12/site-packages', '/Users/chris/homebrew/Cellar/pyside2@5.15.15_py312/5.15.15/lib/python3.12/site-packages', '/Users/chris/homebrew/Cellar/fc_bundle_py312/0.9.2_1/libexec/vendor/lib/python3.12/site-packages', '/Users/chris/Library/Application Support/FreeCAD/Macro/', '/Users/chris/Library/Application Support/FreeCAD/Macro', '/Users/chris/.local/freecad-rc2/Macro', '/Users/chris/Library/Application Support/FreeCAD/Mod']
>>> ^D

from what i can see the proxy PySide python module is located in the ~/.local/freecad-rc2/MacOS/PySide but that directory is not listed in the search path for python modules unfortunately, and the below code that scaffolds this out can be seen below,

  file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/Ext/PySide)
    file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/__init__.py "# PySide wrapper\n"
                                "from PySide${PYSIDE_MAJOR_VERSION} import __version__\n"
                                "from PySide${PYSIDE_MAJOR_VERSION} import __version_info__\n")
    file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtCore.py "from PySide${PYSIDE_MAJOR_VERSION}.QtCore import *\n\n"
                                "#QCoreApplication.CodecForTr=0\n"
                                "#QCoreApplication.UnicodeUTF8=1\n")
    file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtNetwork.py  "from PySide${PYSIDE_MAJOR_VERSION}.QtNetwork import *\n")
    if(BUILD_GUI)
        file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtGui.py  "from PySide${PYSIDE_MAJOR_VERSION}.QtGui import *\n"
                                    "from PySide${PYSIDE_MAJOR_VERSION}.QtWidgets import *\n"
                                    "QHeaderView.setResizeMode = QHeaderView.setSectionResizeMode\n")
        file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtSvg.py  "from PySide${PYSIDE_MAJOR_VERSION}.QtSvg import *\n")
        file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtUiTools.py  "from PySide${PYSIDE_MAJOR_VERSION}.QtUiTools import *\n")
        file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtWidgets.py  "from PySide${PYSIDE_MAJOR_VERSION}.QtWidgets import *\n")
        if(PYSIDE_MAJOR_VERSION LESS 6)
            file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtSvgWidgets.py  "from PySide${PYSIDE_MAJOR_VERSION}.QtSvg import QGraphicsSvgItem\n"
                                                                       "from PySide${PYSIDE_MAJOR_VERSION}.QtSvg import QSvgWidget\n")
            file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtWebEngineWidgets.py  "from PySide${PYSIDE_MAJOR_VERSION}.QtWebEngineWidgets import *\n")
        else()
            file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtSvgWidgets.py  "from PySide${PYSIDE_MAJOR_VERSION}.QtSvgWidgets import *\n")
            file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtWebEngineWidgets.py  "from PySide${PYSIDE_MAJOR_VERSION}.QtWebEngineWidgets import *\n"
                                                                              "from PySide${PYSIDE_MAJOR_VERSION}.QtWebEngineCore import QWebEnginePage\n")
        endif()
    endif()

https://github.com/FreeCAD/FreeCAD/blob/main/cMake/FreeCAD_Helpers/SetupShibokenAndPyside.cmake

and part of the reason why the proxy PySide module is placed in the directory that currently is,

if(APPLE AND NOT BUILD_WITH_CONDA)
        install(
        DIRECTORY
            ${CMAKE_BINARY_DIR}/Ext/PySide
        DESTINATION
            MacOS
        )
    else()
        install(
        DIRECTORY
            ${CMAKE_BINARY_DIR}/Ext/PySide
        DESTINATION
            Ext
        )
    endif()
ipatch commented 1 week ago

i think i finally figure this one out. 🤞

for reasons i don't understand the formula within the tap ie. shiboken2@5.15.15_py312 crashes on launch of the python module shiboken2 which in turn from what i am seeing is what is causing the error failed to wrap widget.

so the work around is to still build the formula, but just include it in the cmake prefix path when building freecad, because the pyside2 formula in the tap also constructs a shiboken2 py module in it's site-packages dir, and importing that shiboken2 module does not crash on launch.

just built freecad using cmake on the freecad community m1. and am able to open the draft workbench 🥳