Python setuptools为所有脚本添加150毫秒的启动延迟

Python setuptools为所有脚本添加150毫秒的启动延迟,python,setuptools,packaging,Python,Setuptools,Packaging,我正在从事一个跨平台的Python项目。它是一个具有shell自动完成功能的命令行工具,因此速度很重要 setuptools生成控制台脚本的方式带来了至少150毫秒的开销,有时甚至更多。对于我正在编写的工具来说,这是完全不可接受的,而且考虑到它在基本情况下所起的作用是如此之小,这也不应该是必要的 我试图遵循现代Python项目的最佳实践,因此我使用setuptools构建项目。该软件包支持windows,因此它为入口点生成二进制包装的能力至关重要 无论我如何安装程序包-pip-install,p

我正在从事一个跨平台的Python项目。它是一个具有shell自动完成功能的命令行工具,因此速度很重要

setuptools
生成控制台脚本的方式带来了至少150毫秒的开销,有时甚至更多。对于我正在编写的工具来说,这是完全不可接受的,而且考虑到它在基本情况下所起的作用是如此之小,这也不应该是必要的

我试图遵循现代Python项目的最佳实践,因此我使用
setuptools
构建项目。该软件包支持windows,因此它为入口点生成二进制包装的能力至关重要

无论我如何安装程序包-
pip-install
pip-install-e
pip-install-egg
python setup.py install
,等等,都会发生这种情况

有人在讨论这个问题,但到目前为止还没有解决办法

在其他地方,我看到有人因为这个原因搬回distutils,但这不是我项目的选择

我能想到的唯一解决办法是以某种方式扩展或定制
setuptools
在按项目安装时所做的工作,以便二进制垫片不会使用
pkg\u资源

除了这一相当激烈和非建设性的措施,我还能做些什么


My
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')()
    )
下面是一些使用setuptools生成的控制台脚本的
cProfile
stats:

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)

如果我使用“pip install”从源代码安装项目,我也看到了这个问题。但是,如果先构建一个二进制wheel文件,然后安装wheel,生成的垫片似乎不会使用pkg_资源,而且速度更快。我已经在cookiecutter项目中对此进行了测试:

如果我克隆此项目,然后使用原始方法“pip install”进行安装,则生成的可执行脚本包含从pkg_资源导入的内容(速度较慢):

但是,如果执行以下两个命令:

python setup.py bdist_wheel
pip install dist/cookiecutter-1.5.1-py2.py3-none-any.whl
生成的垫片不包含pkg_资源(并且更快):


当我在Windows上尝试后一种方法时,它仍然创建了.exe垫片。

那么请编写您自己的脚本。我将如何部署它?当setuptools从
控制台脚本
脚本
部署某些内容时,它会生成使用
加载入口点()
的垫片,该垫片速度较慢。
from myproj.cli.myproj import main

main()
#!/usr/local/opt/python3/bin/python3.5
# EASY-INSTALL-ENTRY-SCRIPT: 'cookiecutter==1.5.1','console_scripts','cookiecutter'
__requires__ = 'cookiecutter==1.5.1'
import re
import sys
from pkg_resources import load_entry_point

if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
    sys.exit(
        load_entry_point('cookiecutter==1.5.1', 'console_scripts', 'cookiecutter')()
    )
python setup.py bdist_wheel
pip install dist/cookiecutter-1.5.1-py2.py3-none-any.whl
#!/usr/local/opt/python3/bin/python3.5

# -*- coding: utf-8 -*-
import re
import sys

from cookiecutter.__main__ import main

if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
    sys.exit(main())