Установка data_files в setup.py с помощью pip install -e

Я пытаюсь предоставить сценарий завершения bash для моего инструмента CLI, написанного на Python. Согласно Управлению по упаковке Python , data_files в setup.py — это именно то, что мне нужно:

Хотя настройки package_data достаточно для большинства нужд, в некоторых случаях вам может понадобиться поместить файлы данных вне ваших пакетов. Директива data_files позволяет это сделать. Это в основном полезно, если вам нужно установить файлы, которые используются другими программами, которые могут не знать о пакетах Python.

Поэтому я добавил файл завершения следующим образом:

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

и попробуйте проверить это с помощью:

pip install -e .

В моей виртуальной среде. Однако скрипт завершения не устанавливается. Я что-то забыл или pip сломался? Полный проект можно найти здесь


person Bastian Venthur    schedule 17.03.2019    source источник
comment
Просто мысль ... вы внимательно проверили свой вывод? Может ли быть какая-то ошибка или предупреждающее сообщение?   -  person CryptoFool    schedule 17.03.2019
comment
Ничего, даже предупреждения или чего-то еще, даже когда я устанавливаю с -vvv.   -  person Bastian Venthur    schedule 17.03.2019
comment
Для установки в /usr ваши пользователи должны запустить pip install от имени пользователя root. То есть вы запрещаете использовать pip install --user или устанавливать в виртуальную среду. Вторая проблема заключается в том, что bash хранит завершение в /usr/share/bash-completion/completions только в Linux. То есть пакет устанавливает файл завершения в неправильный каталог на FreeBSD или MacOS. Короче говоря, data_files — это совершенно неверный подход.   -  person phd    schedule 17.03.2019
comment
См. также docs.python.org/2/distutils/: Каталог должен быть относительным путем. Он интерпретируется относительно префикса установки (префикс sys.Python для системных установок; site.USER_BASE для пользовательских установок). Distutils допускает, что каталог может быть абсолютным путем установки, но это не рекомендуется, так как это несовместимо с форматом упаковки колеса. Информация о каталоге из файлов не используется для определения конечного местоположения установленного файла; используется только имя файла.   -  person phd    schedule 17.03.2019


Ответы (1)


У меня была такая же проблема, и я реализовал обходной путь.

Мне кажется, что python setup.py develop или (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},
)
person Samir Sadek    schedule 05.03.2020