首页 > 解决方案 > 使用 pip install -e 在 setup.py 中安装 data_files

问题描述

我正在尝试为我的 CLI 工具提供一个用 Python 编写的 bash 完成脚本。根据Python Packaging Authority的说法,data_files在 setup.py 中正是我所需要的:

尽管配置 package_data 足以满足大多数需求,但在某些情况下,您可能需要将数据文件放在包之外。data_files 指令允许您这样做。如果您需要安装其他程序使用的文件,它可能非常有用,这些程序可能不知道 Python 包。

所以我添加了这样的完成文件:

data_files=[
    ('/usr/share/bash-completion/completions', ['completion/dotenv']),
],

并尝试使用以下方法对其进行测试:

pip install -e .

在我的虚拟环境中。但是,未安装完成脚本。我是忘记了什么还是pip坏了?完整的项目可以在这里找到

标签: pythonpipsetuptoolsbash-completion

解决方案


我有同样的问题,我已经实施了一个解决方法。

在我看来,python setup.py developor ( pip install -e .) 运行的功能与python setup.py install. 事实上,我通过查看python setup.py install运行的源代码已经注意到build_py

https://github.com/python/cpython/blob/master/Lib/distutils/command/build_py.py#L134 https://github.com/pypa/setuptools/blob/master/setuptools/command/build_py.py

经过几次挖掘后,我选择develop如下覆盖命令。以下代码为python3.6:

""" SetupTool Entry Point """
import sys
from pathlib import Path
from shutil import copy2

from setuptools import find_packages, setup
from setuptools.command.develop import develop

# create os_data_files that will be used by the default install command
os_data_files = [
    (
        f"{sys.prefix}/config",  # providing absolute path, sys.prefix will be different in venv
        [
            "src/my_package/config/properties.env",
        ],
    ),        
]


def build_package_data():
    """ implement the necessary function for develop """
    for dest_dir, filenames in os_data_files:
        for filename in filenames:
            print(
                "CUSTOM SETUP.PY (build_package_data): copy %s to %s"
                % (filename, dest_dir)
            )
            copy2(filename, dest_dir)


def make_dirstruct():
    """ Set the the logging path """
    for subdir in ["config"]:
        print("CUSTOM SETUP.PY (make_dirstruct): creating %s" % subdir)
        (Path(BASE_DIR) / subdir).mkdir(parents=True, exist_ok=True)


class CustomDevelopCommand(develop):
    """ Customized setuptools install command """

    def run(self):
        develop.run(self)
        make_dirstruct()
        build_package_data()

# provide the relevant information for stackoverflow
setup(        
    package_dir={"": "src"},
    packages=find_packages("src"),
    data_files=os_data_files,                
    cmdclass={"develop": CustomDevelopCommand},
)

推荐阅读