📚

cx_freezeでハマったところ

2024/02/05に公開

pyside6+αを使ったpythonスクリプトをexeファイルにする際にcx_freezeを使ったが幾つかハマった所があったので忘備録として残します。

pip install cx_Freeze

を実行してcx_freezeをインストールしsetup.pyを作る。

from cx_Freeze import setup, Executable
import sys

# Dependencies are automatically detected, but some might need fine-tuning
build_exe_options = {"packages": ["os", "sys", "aiohttp", "sqlite3", "PySide6"],
                     "excludes": ["tkinter"]}

# GUI applications require a different base on Windows
base = None
if sys.platform == "win32":
    base = "Win32GUI"

setup(
    name = "Orb Browser",
    version = "0.1",
    description = "light and fast web browser",
    options = {"build_exe": build_exe_options},
    executables = [Executable("Orb Browser.py", base=base, icon="your_icon.ico")]
)

そしてexeファイル化したいpythonスクリプトとsetup.pyを同じフォルダー内に移動させて

python setup.py bdist_msi

を実行!そしてexeファイルが出来上がる…と思っていた時期が僕にもありました…( ´•ω•` )
実行しようとすると

File "C:\Users\ユーザー名\Downloads\ブラウザ\setup.py", line 18
    executables = [Executable(script="Orb Browser.py", base=base, icon="C:\Users\ユーザー名\Downloads\icon2.ico")]
                                                                                                           ^
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape

と言うエラーメッセージが表示されます。

調べてみるとこのエラーメッセージは、PythonがUnicodeエスケープシーケンスを解析できなかったことを示しているようで具体的に言うと\U は8桁の16進数でUnicode文字を表すためのエスケープシーケンスですが、その後に期待される8桁の16進数が存在しないため、エラーが発生しているようです。

具体的には、Windowsのパス文字列を直接文字列として記述したために発生したようでWindowsのパスはバックスラッシュ(\)を使用しますが、Pythonではバックスラッシュがエスケープシーケンスの開始を示すため、エラーが生じたようです。

解決策

バックスラッシュを二重にしてエスケープすることで解決出来ました。(文字列をraw文字列に修正しても解決できるようです。)

executables = [Executable(script="Orb Browser.py", base=base, icon="C:\\Users\\com04\\Downloads\\icon2.ico")]

「よし、コレでexeファイルを作れる!」と思ったのも束の間、今度は

Traceback (most recent call last):
  File "C:\Users\com04\setup.py", line 1, in <module>
    from cx_Freeze import setup, Executable
  File "C:\Users\com04\cx_Freeze.py", line 1, in <module>
    from cx_Freeze import setup, Executable
ImportError: cannot import name 'setup' from partially initialized module 'cx_Freeze' (most likely due to a circular import) (C:\Users\com04\cx_Freeze.py)

と言うエラーメッセージが表示されました…( ´•ω•` )

調べてみるとこのエラーメッセージは、cx_Freezeモジュールが部分的に初期化された状態でsetup`をインポートできないことを示しているようで(過去にcx_freezeの練習をした時に謝って作ってしまった)cx_Freeze.pyが循環インポートを引き起こしていることを示していました。

解決策

問題を引き起こしているcx_freeze.pyを削除したら解決しました。

結論

cx_freezeより使い慣れてるnuitkaを使った方が良かったかな…(でもnuitkaでは何故かpysideのpywebengineにあたる機能が動作しなかったので使えませんでした…)

宣伝

以前から開発していたWebブラウザのWindows版が完成しました!もしよければダウンロードして使って下さい。

ダウンロードリンク

Discussion