Ошибка импорта APScheduler при генерации исполняемого файла с py2exe или cx_freeze
При создании исполняемого файла на python 2.7 с использованием py2exe (0.6.9) или cx_freeze (5.0.1) с помощью APScheduler (3.3.1) выдается следующая ошибка:
File "apscheduler\__init__.pyc", line 2, in <module>
File "pkg_resources\__init__.pyc", line 552, in get_distribution
File "pkg_resources\__init__.pyc", line 426, in get_provider
File "pkg_resources\__init__.pyc", line 968, in require
File "pkg_resources\__init__.pyc", line 854, in resolve
pkg_resources.DistributionNotFound: The 'APScheduler' distribution was not found and is required by the application
Это мой файл cx_freeze setup.py:
import sys
from cx_Freeze import setup, Executable
# Dependencies are automatically detected, but it might need fine tuning.
build_exe_options = {"includes": ["requests", "apscheduler"], "include_files": ["XXX"]}
# GUI applications require a different base on Windows (the default is for a
# console application).
base = None
if sys.platform == "win32":
base = "Win32GUI"
setup( name = "XXX",
version = "XXX",
description = "XXX",
options = {"build_exe": build_exe_options},
executables = [Executable("XXX.py", base=base), Executable("XXX2.py", base=base)])
И это мой файл py2exe setup.py:
from distutils.core import setup
import py2exe
data_files = ['XXX']
setup(
data_files=data_files,
windows=[
{'script': 'XXX.py'},
{'script': 'XXX2.py'},
],
options={'py2exe':{
'includes': ['requests', 'apscheduler'],
'bundle_files': 1,
}
},
)
Я уже пытался использовать опцию "пакеты", но безуспешно.
Если я удаляю код из APScheduler __init__.py (apscheduler/__init__.py), он работает.
Ниже приведен файл __init__.py из пакета APScheduler:
# These will be removed in APScheduler 4.0.
release = __import__('pkg_resources').get_distribution('apscheduler').version.split('-')[0]
version_info = tuple(int(x) if x.isdigit() else x for x in release.split('.'))
version = __version__ = '.'.join(str(x) for x in version_info[:3])
Нужно ли как-то включать зависимости в библиотечный пакет py2exe/cx_freeze?
Я уже провел некоторые исследования в Интернете, но безуспешно.
1 ответ
Нашел решение. Проблема заключалась в том, что py2exe не включает каталог dist-info для library.zip. Каждый модуль имеет свой собственный каталог dist-info в библиотеках python для пакетов сайта.
Эти каталоги используются библиотеками pkg_resources для импорта модулей, как мы видим на apscheduler __init__.py:2
Все, что вам нужно сделать, это добавить эти каталоги dist-info в файл library.zip, созданный py2exe.
Ниже приведен пример импорта из Google (не связанный, но может использоваться в качестве примера) каталога zoneinfo в library.zip.
https://github.com/google/transitfeed/blob/master/setup.py
Чтобы получить путь к модулю dist-info, используйте следующую команду:
import os
import pkg_resources
dist_info_dir = pkg_resources.get_distribution('desired_module')._provider.egg_info
# get base name of directory
base_name = os.path.basename(dist_info_dir)
Примечание: если нет каталога dist-info и взамен egg-info. Вероятно, вам следует поискать пакет колеса для библиотеки или собрать себя с помощью:
python setup.py bdist_wheel
Ура!