Значения site.USER_SITE/USER_BASE равны None при упаковке приложения Kivy с помощью PyInstaller.Python

Программы на Python
Ответить
Anonymous
 Значения site.USER_SITE/USER_BASE равны None при упаковке приложения Kivy с помощью PyInstaller.

Сообщение Anonymous »

У меня есть простое приложение Kivy с некоторыми добавленными компонентами KivyMD. Вот мои результаты заморозки пипсов...

Код: Выделить всё

altgraph==0.17.4
certifi==2024.8.30
charset-normalizer==3.4.0
configparser==7.1.0
Cython==3.0.0
docutils==0.21.2
idna==3.10
Kivy==2.3.0
kivy-deps.angle==0.4.0
kivy-deps.glew==0.3.1
kivy-deps.sdl2==0.7.0
Kivy-examples==2.3.0
Kivy-Garden==0.1.5
kivy-translate==0.2.0
kivymd==1.2.0
macholib==1.16.3
modulegraph==0.19.6
packaging==24.2
pefile==2023.2.7
pillow==10.4.0
py2app==0.28.8
Pygments==2.18.0
pyinstaller==6.11.1
pyinstaller-hooks-contrib==2024.10
pypiwin32==223
pywin32==308
pywin32-ctypes==0.2.3
requests==2.32.3
urllib3==2.2.3
Я следовал инструкциям по упаковке в Windows, которые можно найти здесь. У меня уже есть версия, работающая с MacOS, поэтому, используя то, что я узнал из нее, я попытался упаковать для Windows.
Вот мой файл main.spec, который, согласно документации Kivy, я запускаться из папки в папке моего проекта, отсюда и использование ..\main.py:

Код: Выделить всё

# -*- mode: python ; coding: utf-8 -*-

from kivy_deps import sdl2, glew
from kivy import kivy_data_dir
from kivymd import hooks_path as kivymd_hooks_path
block_cipher = None

# assets
kivy_assets_toc = Tree(kivy_data_dir, prefix=join('kivy_install', 'data'))
tocs = [kivy_assets_toc]

a = Analysis(
['..\\main.py'],
pathex=[],
binaries=[],
datas=[('..\\locale\\*', 'locale'),('..\\images\\*', 'images')],
hiddenimports=[],
hookspath=[kivymd_hooks_path],
hooksconfig={},
runtime_hooks=["hook.py"],
excludes=['_tkinter', 'Tkinter', 'enchant', 'twisted'],
noarchive=False,
cipher=block_cipher,
optimize=0,
)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)

exe = EXE(
pyz,
Tree('..\\'),
a.scripts,
*[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
*tocs,
exclude_binaries=True,
name='main',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
coll = COLLECT(
exe,
*tocs,
a.binaries,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='main',
)

Который также имеет файлook.py, который устанавливает переменную среды:

Код: Выделить всё

import os
from os.path import join

# Required to fix OpenGL version bug when building in Windows
# where when running and freezing the application, the application cannot find the correct
# OpenGL version and fails. This forces it to work for the build...
os.environ['KIVY_GL_BACKEND'] = 'angle_sdl2'
Теперь, после упаковки и запуска, я получаю эту ошибку из угла и аналогичную для sdl2:

Код: Выделить всё

Traceback (most recent call last):
File "main.py", line 21, in 
File "", line 1176, in _find_and_load
File "", line 1147, in _find_and_load_unlocked
File "", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 384, in exec_module
File "kivymd\__init__.py", line 26, in 
File "", line 1176, in _find_and_load
File "", line 1147, in _find_and_load_unlocked
File "", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 384, in exec_module
File "kivy\__init__.py", line 320, in 
File "PyInstaller\loader\pyimod02_importers.py", line 384, in exec_module
File "kivy_deps\angle\__init__.py", line 23, in 
File "", line 108, in join
TypeError: expected str, bytes or os.PathLike object, not NoneType
Это происходит из кода angular.__init__ и sdl2.__init__, который выглядит, как показано ниже, и использует site.USER_BASE и site.USER_SITE< /код> соответственно. При объединении происходит сбой, поскольку d имеет значение None при поиске site.USER_BASE

Код: Выделить всё

for d in [sys.prefix, site.USER_BASE]:
p = join(d, 'share', 'sdl2', 'bin')
if isdir(p):
os.environ["PATH"] = p + os.pathsep + os.environ["PATH"]
if hasattr(os, 'add_dll_directory'):
os.add_dll_directory(p)
dep_bins.append(p)

Оказывается, что site.USER_BASE и site.USER_SITE имеют значение None при упаковке. Из того, что я здесь читаю, это то, что теперь они макетируют пакет сайта.
Может быть, мои знания Python не очень хороши, но, конечно же, нам нужны эти наборы в приложении Python, чтобы пакеты могли найти базу Python и пакеты сайта?
Я могу при желании перезаписать значения в файле main.py перед импортом остальных пакетов, но не уверен, какое значение им следует установить. когда внутри исполняемого файла? Обратите внимание: когда я добавляю следующие исполняемые сборки, но при их запуске происходит сбой без сообщения об ошибке. Кажется, он просто разваливается. Это понятно, поскольку я установил для них пустую строку.

Код: Выделить всё

import site
if site.USER_SITE is None:
site.USER_SITE = ""

if site.USER_BASE is None:
site.USER_BASE = ""
Невозможно ли это, учитывая, что PyInstaller имитирует импорт сайта? Кому-нибудь еще это удалось?

Подробнее здесь: https://stackoverflow.com/questions/791 ... lication-w
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»