marcelotduarte / cx_Freeze

cx_Freeze creates standalone executables from Python scripts, with the same performance, is cross-platform and should work on any platform that Python itself works on.
https://marcelotduarte.github.io/cx_Freeze/
Other
1.28k stars 210 forks source link

partially initialized module 'PyQt5' has no attribute 'QtCore' #2414

Open programmeddeath1 opened 1 month ago

programmeddeath1 commented 1 month ago

I am trying to package a PyQt5 application with ROS dependencies. Below is my setup file -

import sys
from cx_Freeze import setup, Executable
import os

# Add ROS paths
ros_paths = [
    '/home/greenpi/noetic_ws/install_isolated/lib/python3/dist-packages',
    '/home/greenpi/noetic_ws/devel_isolated/lib/python3/dist-packages',
    '/opt/ros/noetic/lib/python3/dist-packages'
]
# Add global Python paths
python_paths = [
    '/usr/lib/python3/dist-packages',
    '/usr/local/lib/python3.10/dist-packages',    
    '/home/greenpi/.local/lib/python3.10/site-packages'
]

# Extend the Python path
sys.path.extend(ros_paths + python_paths)

# Collect additional files and directories
include_files = [
    ('../delta_description/config/delta_robot.rviz', 'config/delta_robot.rviz'),
    ('/usr/bin/neato', 'graphviz/bin/neato'),
    ('/usr/bin/dot', 'graphviz/bin/dot'),
    ('/usr/bin/fdp', 'graphviz/bin/fdp'),
    ('/usr/bin/sfdp', 'graphviz/bin/sfdp'),
    ('/usr/bin/twopi', 'graphviz/bin/twopi'),
    ('/usr/bin/circo', 'graphviz/bin/circo'),
    # Add other files or directories as needed
]

# Define the base for the executable
base = None

# Define the executable
executables = [
    Executable(
        'main_qthread_docker.py',
        base=base,
        target_name='deltaapp',
        icon=None  # You can add an icon if needed
    )
]

# Define the setup
setup(
    name="deltaapp",
    version="0.1",
    description="My PyQt and ROS application",
    options={
        "build_exe": {
            "packages": [
                "os", "sys", "PyQt5", "PyQt5.QtCore", "PyQt5.QtGui", "PyQt5.QtWidgets", "cv2", "numpy", "roslib",
                "rospy", "std_msgs", "geometry_msgs", "sensor_msgs", "depthai", "yaml", "torch", "pandas"
            ],
            "excludes": ["tkinter"],
            "include_files": include_files,
            "path": sys.path,
            "build_exe": "build_exe"
        }
    },
    executables=executables
)

It builds successfully. When I run the executable it fails with

Traceback (most recent call last):
  File "/home/greenpi/.local/lib/python3.10/site-packages/cx_Freeze/initscripts/__startup__.py", line 138, in run
    module_init.run(name + "__main__")
  File "/home/greenpi/.local/lib/python3.10/site-packages/cx_Freeze/initscripts/console.py", line 17, in run
    exec(code, module_main.__dict__)
  File "main_qthread_docker.py", line 3, in <module>
  File "/usr/lib/python3/dist-packages/PyQt5/__init__.py", line 39, in <module>
  File "/home/greenpi/.local/lib/python3.10/site-packages/cx_Freeze/hooks/pyqt5/_append_to_init.py", line 23, in <module>
    _run()
  File "/home/greenpi/.local/lib/python3.10/site-packages/cx_Freeze/hooks/pyqt5/_append_to_init.py", line 8, in _run
    qtcore = __import__("PyQt5", fromlist=["QtCore"]).QtCore
AttributeError: partially initialized module 'PyQt5' has no attribute 'QtCore' (most likely due to a circular import)

Which means it has not properly inported the PyQt5 dependency, what am I doing wrong here? Thank you for your help in advance!

marcelotduarte commented 1 month ago

Use zip_include_packages: https://github.com/marcelotduarte/cx_Freeze/blob/main/samples/pyqt5/setup.py#L33

programmeddeath1 commented 1 month ago

I cloned the repo and built the pyqt5 example using python3 setup,py build.

I then ran the test_pqt5 it gives me the same partially initialized error.

The PyQT i am using is the default PyQT5 installed at the system level in ubuntu 22.

Python 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import PyQt5 as pt
>>> pt.__path__
['/usr/lib/python3/dist-packages/PyQt5']

Could this be what is causing the conflict or issue? I am running ubuntu 22 on a orange pi sbc board. The pyqt app opens normally if i do python3 test_pyqt5.py.

Edit 1 I tried the same sample on my amd laptop too, its giving the same error, so it should not be a device or OS issue.

marcelotduarte commented 1 month ago

I use a virtualenv and install cx_Freeze and pyqt5 using pip (see also README). I do not test with system pytq5. I test it using conda-forge too.

programmeddeath1 commented 1 month ago

I have to use the system PyQt5 package because, on my sbc, the PyQT5 package cannot be installed through pip. It needs to be built from source.

Is it feasible to make cx_freeze use the system pip package? if so can you tell me the steps, else i assume I will have to try with a source build which currently doesnt seem feasible.

marcelotduarte commented 1 month ago

The program 'main_qthread_docker.py' runs in Python? python3 main_qthread_docker.py works? I installed pyqt5-dev (sudo apt install pyqt5-dev) And tried:

$ python3
Python 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import PyQt5 as pt
>>> pt.__path__
_NamespacePath(['/usr/lib/python3/dist-packages/PyQt5'])
>>> 
$ python3 samples/pyqt5/test_pyqt5.py 
Traceback (most recent call last):
  File "/home/marcelo/github/cx_Freeze/samples/pyqt5/test_pyqt5.py", line 5, in <module>
    from PyQt5.QtCore import Qt
ModuleNotFoundError: No module named 'PyQt5.QtCore'

So the sample did not work with system python. This works w/ pyqt5 from pypi. Do I need more packages than pyqt5-dev?