Инсталиране на data_files в setup.py с pip install -e

Опитвам се да осигуря скрипт за завършване на bash за моя CLI инструмент, който е написан на Python. Според 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 е повреден? Пълният проект може да бъде намерен тук


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.prefix на 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