Установить по умолчанию «необязательные» зависимости в Python (setuptools) - PullRequest
0 голосов
/ 19 ноября 2018

Есть ли способ указать необязательные зависимости для пакета Python, который должен быть установлен по умолчанию из pip, но для которого установка не должна рассматриваться как сбой, если их невозможно установить?

Я знаю, что могу указать install_requires, чтобы пакеты были установлены для 90% пользователей, использующих ОС, которые могут легко устанавливать определенные дополнительные зависимости, и я также знаю, что могу указать extra_require, чтобы указать, что пользователи могут объявить, что они хотят полную установку, чтобы получить эти функции, но я не нашел способа сделать установку по умолчанию pip, попытаться установить пакеты, но не жаловаться, если их невозможно установить.

(Конкретный пакет, для которого я хотел бы обновить setuptools и setup.py, называется music21, для которого 95% инструментов можно запускать без matplotlib, IPython, scipy, pygame, некоторых неясных аудио инструментов и т.д., но пакет получает дополнительные возможности и скорость, если эти пакеты установлены, и я бы предпочел, чтобы люди имели эти возможности по умолчанию, но не сообщали об ошибках, если их невозможно установить)

Ответы [ 3 ]

0 голосов
/ 01 декабря 2018

Самый простой способ сделать это - добавить пользовательскую команду установки, которая просто отправляет команду pip для установки «дополнительных» пакетов. В вашем setup.py:

import sys
import subprocess
from setuptools import setup
from setuptools.command.install import install

class MyInstall(install):
    def run(self):
        subprocess.call([sys.executable, "-m", "pip", "install", "whatever"])
        install.run(self)

setup(
    ...

    cmdclass={
        'install': MyInstall,
    },
)

Как и hoefling, как сказано выше, будет работать только , если вы публикуете исходный дистрибутив (.tar.gz или .zip). Он не будет работать, если вы опубликуете свой пакет как встроенный дистрибутив (.whl).

0 голосов
/ 06 декабря 2018

Это может быть то, что вы ищете.Похоже, это встроенная функция инструментов настройки, которая позволяет вам объявлять «необязательные зависимости».

https://setuptools.readthedocs.io/en/latest/setuptools.html#declaring-extras-optional-features-with-their-own-dependencies

Ex

setup(
    name="Project-A",
    ...
    extras_require={
        'PDF':  ["ReportLab>=1.2", "RXP"],
        'reST': ["docutils>=0.3"],
    }
)
0 голосов
/ 30 ноября 2018

Не идеальное решение, но вы можете настроить скрипт после установки, чтобы попытаться установить пакеты, что-то вроде этого:

from distutils.core import setup
from distutils import debug


from setuptools.command.install import install
class PostInstallExtrasInstaller(install):
    extras_install_by_default = ['matplotlib', 'nothing']

    @classmethod
    def pip_main(cls, *args, **kwargs):
        def pip_main(*args, **kwargs):
            raise Exception('No pip module found')
        try:
            from pip import main as pip_main
        except ImportError:
            from pip._internal import main as pip_main

        ret = pip_main(*args, **kwargs)
        if ret:
            raise Exception(f'Exitcode {ret}')
        return ret

    def run(self):
        for extra in self.extras_install_by_default:
            try:
                self.pip_main(['install', extra])
            except Exception as E:
                print(f'Optional package {extra} not installed: {E}')
            else:
                print(f"Optional package {extra} installed")
        return install.run(self)


setup(
    name='python-package-ignore-extra-dep-failures',
    version='0.1dev',
    packages=['somewhat',],
    license='Creative Commons Attribution-Noncommercial-Share Alike license',
    install_requires=['requests',],
    extras_require={
        'extras': PostInstallExtrasInstaller.extras_install_by_default,
    },
    cmdclass={
        'install': PostInstallExtrasInstaller,
    },
)
...