# -*- mode: python ; coding: utf-8 -*- """Faster onefile freeze: same portable exe (fonts + plantuml.jar + onefile). Keeps matplotlib (system font lookup) and bundles plantuml.jar. Speeds Analysis by pinning the Agg backend, skipping duplicate pygments collection (the stock hook already pulls all lexers), and not probing Qt/Gtk. """ import os from pathlib import Path from PyInstaller.utils.hooks import ( collect_data_files, collect_dynamic_libs, collect_submodules, ) # Isolated matplotlib hook subprocesses inherit this and skip GUI backend probes. os.environ["MPLBACKEND"] = "Agg" ROOT = Path(SPECPATH).resolve() datas = [ (str(ROOT / "md2gost" / "Template.docx"), "md2gost"), (str(ROOT / "md2gost" / "mml2omml"), "md2gost"), (str(ROOT / "md2gost" / "diagrams"), "md2gost/diagrams"), (str(ROOT / "prompts"), "prompts"), (str(ROOT / "docs"), "docs"), ] _plantuml = ROOT / "md2gost" / "vendor" / "plantuml.jar" if not _plantuml.is_file(): raise SystemExit( "md2gost.fast.spec: нет md2gost/vendor/plantuml.jar — " "сначала scripts/fetch_plantuml.py (jar обязателен в portable exe)" ) datas.append((str(_plantuml), "md2gost/vendor")) binaries = [] hiddenimports = collect_submodules("md2gost") datas += collect_data_files("certifi") datas += collect_data_files("lxml") datas += collect_data_files("latex2mathml") datas += collect_data_files("docx") # Explicit mpl-data so DejaVu + matplotlib font cache files are always in the exe. # hook-matplotlib.py also collects this; PyInstaller dedupes by dest path. datas += collect_data_files("matplotlib", includes=["mpl-data/**"]) for pkg in ("lxml", "freetype"): try: binaries += collect_dynamic_libs(pkg) except Exception: pass hiddenimports += [ "lxml", "lxml.etree", "lxml._elementpath", "PIL", "PIL.Image", "PIL.PngImagePlugin", "pygments", "pygments.lexers", "pygments.formatters", "freetype", "docx", "docxcompose", "docxcompose.composer", "marko", "marko.ext.gfm", "latex2mathml", "latex2mathml.converter", "requests", "certifi", "matplotlib", "matplotlib.font_manager", "matplotlib.ft2font", "tkinter", "tkinter.filedialog", "tkinter.messagebox", "tkinter.ttk", ] # Do NOT collect_submodules("pygments.lexers") here — hook-pygments.py already # collects all lexers/formatters/styles once during Analysis. try: hiddenimports += collect_submodules("tkinterdnd2") except Exception: pass excludes = [ "pytest", "PyQt5", "PyQt6", "PySide2", "PySide6", "IPython", "jupyter", "notebook", "zmq", "scipy", "pandas", "tornado", "numpy.tests", "matplotlib.tests", "matplotlib.testing", "matplotlib.backends.qt_compat", "matplotlib.backends.backend_qtagg", "matplotlib.backends.backend_qtcairo", "matplotlib.backends.backend_qt5agg", "matplotlib.backends.backend_qt5cairo", "matplotlib.backends.backend_qt5", "matplotlib.backends.backend_qt", "matplotlib.backends.backend_gtk3", "matplotlib.backends.backend_gtk3agg", "matplotlib.backends.backend_gtk3cairo", "matplotlib.backends.backend_gtk4", "matplotlib.backends.backend_gtk4agg", "matplotlib.backends.backend_gtk4cairo", "matplotlib.backends.backend_macosx", "matplotlib.backends.backend_tkagg", "matplotlib.backends.backend_tkcairo", "matplotlib.backends.backend_wx", "matplotlib.backends.backend_wxagg", "matplotlib.backends.backend_wxcairo", "matplotlib.backends.backend_nbagg", "matplotlib.backends.backend_webagg", "PIL.ImageQt", ] a = Analysis( [str(ROOT / "scripts" / "md2gost_exe.py")], pathex=[str(ROOT)], binaries=binaries, datas=datas, hiddenimports=hiddenimports, hookspath=[], hooksconfig={ "matplotlib": {"backends": "Agg"}, }, runtime_hooks=[str(ROOT / "scripts" / "pyi_rth_mplbackend.py")], excludes=excludes, noarchive=False, ) pyz = PYZ(a.pure) exe = EXE( pyz, a.scripts, a.binaries, a.datas, [], name="md2gost", debug=False, bootloader_ignore_signals=False, strip=False, upx=False, console=False, disable_windowed_traceback=False, argv_emulation=False, target_arch=None, codesign_identity=None, entitlements_file=None, )