Я работаю над кросс-платформенным проектом Python. Это инструмент командной строки с автозавершением оболочки, поэтому скорость имеет значение.setuptools добавляет латентность запуска на 150 мс для всех скриптов
Путь setuptools
создает консольный скрипт, налагающий минимум на 150 мс - иногда больше. Это просто неприемлемо для того инструмента, который я пишу, и не должен быть необходимым, учитывая, как мало он делает в основном случае.
Я стараюсь следовать лучшей практике для современного проекта Python, поэтому я использую setuptools
для создания проекта. Пакет поддерживает окна, поэтому его способность генерировать двоичные обертки для точек входа очень важна.
Это происходит независимо от того, как установить пакет - pip install
, pip install -e
, pip install --egg
, python setup.py install
и т.д.
Там в github issue обсуждали эту проблему, но не обходной путь или решение до сих пор.
В другом месте я видел людей, возвращающихся к distutils из-за этого, но это не вариант для моего проекта.
Единственное обходное решение, которое я могу придумать, - это каким-то образом расширить или настроить то, что делает setuptools
, когда он устанавливает проект, чтобы бинарная прокладка не использовала pkg_resources
.
Что я могу сделать взамен этой довольно радикальной и неконструктивной меры?
Моего setup.py
является основным - примерно следующим образом:
import pip.req
import setuptools
def install_reqs():
reqs = pip.req.parse_requirements('requirements.txt', session=False)
reqs = [str(ir.req) for ir in reqs]
return reqs
setuptools.setup(
name='myproj',
version='v1.0.0-dev',
packages=setuptools.find_packages(exclude=('tests')),
install_requires=install_reqs(),
include_package_data=True,
entry_points={
'console_scripts': [
'myproj = myproj.cli.myproj:main',
]
},
)
Прокладка, что Setuptools генерирует для точки входа выглядит следующим образом:
!$myhome/.venv/myproj/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'myproj==1.0.0.dev0','console_scripts','myproj'
__requires__ = 'myproj==1.0.0.dev0'
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.exit(
load_entry_point('myproj==1.0.0.dev0', 'console_scripts', 'myproj')()
)
Вот некоторые cProfile
статистика с использованием Setuptools -генерированный сценарий консоли:
ncalls tottime percall cumtime percall filename:lineno(function)
121/1 0.015 0.000 0.278 0.278 {built-in method builtins.exec}
1 0.000 0.000 0.278 0.278 myproj:3(<module>)
125/3 0.001 0.000 0.221 0.074 <frozen importlib._bootstrap>:966(_find_and_load)
125/3 0.001 0.000 0.221 0.074 <frozen importlib._bootstrap>:939(_find_and_load_unlocked)
125/5 0.001 0.000 0.219 0.044 <frozen importlib._bootstrap>:659(_load_unlocked)
99/5 0.001 0.000 0.219 0.044 <frozen importlib._bootstrap_external>:656(exec_module)
152/4 0.000 0.000 0.218 0.054 <frozen importlib._bootstrap>:214(_call_with_frames_removed)
2 0.000 0.000 0.204 0.102 __init__.py:15(<module>)
32/15 0.000 0.000 0.135 0.009 {built-in method builtins.__import__}
1 0.000 0.000 0.088 0.088 __init__.py:540(load_entry_point)
1 0.000 0.000 0.085 0.085 __init__.py:2564(load_entry_point)
1 0.000 0.000 0.083 0.083 __init__.py:2216(load)
И здесь в качестве пользовательского сценария без Setuptools шайбы:
ncalls tottime percall cumtime percall filename:lineno(function)
58/1 0.006 0.000 0.053 0.053 {built-in method builtins.exec}
1 0.000 0.000 0.053 0.053 test.py:1(<module>)
53/3 0.000 0.000 0.052 0.017 <frozen importlib._bootstrap>:966(_find_and_load)
53/3 0.000 0.000 0.052 0.017 <frozen importlib._bootstrap>:939(_find_and_load_unlocked)
53/5 0.000 0.000 0.051 0.010 <frozen importlib._bootstrap>:659(_load_unlocked)
65/4 0.000 0.000 0.051 0.013 <frozen importlib._bootstrap>:214(_call_with_frames_removed)
45/5 0.000 0.000 0.051 0.010 <frozen importlib._bootstrap_external>:656(exec_module)
Обычай сценария - test.py - очень просто:
from myproj.cli.myproj import main
main()
Итак, напишите собственный сценарий. –
Как мне его развернуть? Когда setuptools развертывает что-то из 'console_scripts' или' scripts', он генерирует прокладку, которая использует 'load_entry_point()', что происходит медленно. – Cera