在 Windows 上的 python virtualenv 中,我安装了一个自定义包,它覆盖 setuptools.command.install.easy_install.get_script_args 以创建新的自定义类型的入口点“custom_entry”
我有另一个包,我想用 setuptools 准备暴露一个自定义入口点。
如果我准备这个包的 egg 发行版并使用我修改过的 easy_install.exe 安装它,这将正确创建自定义入口点。
但是,如果我准备一个 wheel 分发版并使用修改后的 pip.exe 安装它,则不会添加自定义入口点。
为什么 pip 不遵循与 easy_install 相同的安装过程?
阅读 pip 的源代码,似乎 wheel.py 中的函数get_entrypoints排除了除 console_scripts 和 gui_scripts 之外的所有入口点。这个对吗?
如果是这样,我应该如何为 pip 安装安装自定义入口点?
- - 编辑
看来我应该提供更多细节。
在我的第一个包中custom-installer
,我正在覆盖(猴子补丁,真的)easy_install.get_script_args
,在custom_install.__init__.py
:
from setuptools.command import easy_install
_GET_SCRIPT_ARGS = easy_install.get_script_args
def get_script_args(dist, executable, wininst):
for script_arg in _GET_SCRIPT_ARGS(dist, executable, wininst):
yield script_arg # replicate existing behaviour, handles console_scripts and other entry points
for group in ['custom_entry']:
for name, _ in dist.get_entry_map(group).items():
script_text = (
## some custom stuff
)
## do something else
yield (## yield some other stuff) # to create adjunct files to the -custom.py script
yield (name + '-custom.py', script_text, 't')
easy_install.get_script_args = get_script_args
main = easy_install.main
在那个包中setup.py
,我为我的自定义安装程序提供了一个 (console_script) 入口点:
entry_points={
'console_scripts': [
'custom_install = custom_install.__init__:main'
]
}
使用 pip 正确安装此软件包会创建安装程序脚本/venv/Scripts/custom_install.exe
对于我的第二个包,customized
我有常规和自定义入口点来安装setup.py
,两个模块custom
和console
.
entry_points={
'console_scripts': [
'console = console.__main__:main'
],
'custom_entry': [
'custom = custom.__main__:main'
]
}
无论安装过程如何,我都希望看到这两个入口点都已安装。
如果我将包构建customized
为 egg 发行版并使用custom_install.exe
created by安装它custom-installer
,那么 的两个入口点customized
都已安装。
我希望能够使用 pip 将此包安装为轮文件,但从阅读源代码来看,pip 似乎明确跳过了“console_scripts”和“gui_scripts”以外的任何入口点:
def get_entrypoints(filename):
if not os.path.exists(filename):
return {}, {}
# This is done because you can pass a string to entry_points wrappers which
# means that they may or may not be valid INI files. The attempt here is to
# strip leading and trailing whitespace in order to make them valid INI
# files.
with open(filename) as fp:
data = StringIO()
for line in fp:
data.write(line.strip())
data.write("\n")
data.seek(0)
cp = configparser.RawConfigParser()
cp.readfp(data)
console = {}
gui = {}
if cp.has_section('console_scripts'):
console = dict(cp.items('console_scripts'))
if cp.has_section('gui_scripts'):
gui = dict(cp.items('gui_scripts'))
return console, gui
随后,pip 使用与 easy_install 完全不同的代码集生成入口点脚本。据推测,我可以覆盖 pip 的这些实现,就像使用 easy_install 所做的那样,以创建我的自定义入口点,但我觉得我走错了路。
谁能建议一种更简单的方法来实现与 pip 兼容的自定义入口点?如果没有,我可以覆盖get_entrypoints
and move_wheel_files
。