python pip安装轮具有自定义入口点

时间:2014-11-19 17:18:54

标签: python windows pip entry-point python-wheel

在Windows上的python virtualenv中,我安装了一个自定义包,它超越了setuptools.command.install.easy_install.get_script_args来创建一个新的自定义类型的入口点'custom_entry'

我有另一个包,我想用setuptools来准备一个自定义入口点。

如果我准备一个这个包的蛋分发并使用我修改过的easy_install.exe安装它,这会正确创建自定义入口点。

但是,如果我准备一个滚轮分发版并使用修改后的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安装常规和自定义入口点,用于两个模块customconsole

entry_points={
    'console_scripts': [
        'console = console.__main__:main'
    ],
    'custom_entry': [
        'custom = custom.__main__:main'
    ]
}

我希望无论安装过程如何都安装这两个入口点。

如果我将包customized构建为鸡蛋发布,并使用custom_install.exe创建的custom-installer进行安装,则会安装customized的两个入口点。

我希望能够使用pip将此软件包安装为wheel文件,但是从阅读源代码开始,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_entrypointsmove_wheel_files

1 个答案:

答案 0 :(得分:0)

您可能需要在console_scripts文件中使用关键字setup.py。请参阅以下答案:

它基本上表明您需要在setup.py脚本中执行以下操作:

entry_points = {
       'console_scripts': ['custom_entry_point = mypackage.mymod.test:foo']
       }

另请参阅:http://calvinx.com/2012/09/09/python-packaging-define-an-entry-point-for-console-commands/