Как установить пакет с pip, который имеет доступ к R-скрипту - PullRequest
0 голосов
/ 16 мая 2018

выпуск

Мне нужно создать пакет python, который будет иметь доступ к R-скрипту и сделать его устанавливаемым в pip

Настройка:

Моя структура пакета выглядит следующим образом

foo/  
  setup.py  
  foo/
    foo.R

Содержимое setup.py:

from setuptools import setup, find_packages

setup(
    name='foo',
    packages=find_packages(),
    scripts=['foo/foo.R'],
    zip_safe=False,
)

и содержимое foo.R:

#!/usr/bin/env Rscript

R.version

Я устанавливаю этот пакет с:
pip install -e .

Когда я смотрю на установленный R-скрипт, он больше не является R-скриптом, поэтому, когда он вызывается, он запускается как python и поэтому завершается с ошибкой

$ cat $(which foo.R) для просмотра содержимого файла

Что я ожидаю:

#!/usr/bin/env Rscript

R.version

Что я получу:

#!/Users/jc33/miniconda3/bin/python
# EASY-INSTALL-DEV-SCRIPT: 'foo==0.0.0','foo.R'
__requires__ = 'foo==0.0.0'
__import__('pkg_resources').require('foo==0.0.0')
__file__ = '/Users/jc33/Desktop/foo/foo/foo.R'
exec(compile(open(__file__).read(), __file__, 'exec'))

дополнительная область

Это очень надуманный пример, который был создан с единственной целью - найти решение, а не обсуждать преимущества поиска сценария R с помощью setuptools. Для получения дополнительной информации я создаю более сложный пакет Python, подобный this , который должен будет вызывать R в какой-то момент, это делается с помощью subprocess.run, однако я считаю, что это выходит за рамки этого вопроса

Python=='3.5.2'
setuptools=='27.2.0'
pip=='10.0.1

Ответы [ 3 ]

0 голосов
/ 16 мая 2018

scripts для Python скриптов. Если вы хотите установить что-то это вовсе не код Python, вам нужно рассматривать это как данные. В setuptools это называется package_data:

setup(
    name='foo',
    packages=find_packages(),
    package_data={
        'foo': ['foo.R'],
    },
    zip_safe=False,
)

Файл будет установлен как foo/foo.R, и вы можете найти его из модуля в foo/, скажем, это foo/foo.py. Первое, что нужно сделать в foo.py, это найти его каталог, а затем вызвать foo.R:

import os, subprocess
foo_dir = os.path.dirname(__file__)
subprocess.check_call(['r', os.path.join(foo_dir, 'foo.R')])

PS. Обратите внимание, что код должен находиться в модуле в каталоге foo/. Для другого каталога он должен манипулировать с __file__ другим способом.

0 голосов
/ 17 мая 2018

Это происходит потому, что ваш R-скрипт недостаточно похож на Python.

Если вы поместите некоторый код R, который вызывает синтаксическую ошибку, такую ​​как начальный . или любое использование $ или foo[[0]], вы обнаружите, что setuptools (но на самом деле distutils + easy_install) не производит develop обертка.

Источник, управляющий оболочкой скрипта, можно найти здесь . Он тестирует с is_python_script, который вызывает is_python. Это в свою очередь просто компилирует файл. Успешная компиляция возвращает True и приводит к тому, что easy_install создает скрипт-обертку, а неудачный - False, а файл просто копируется дословно (что вам нужно).

0 голосов
/ 16 мая 2018

Это нормальное поведение для «редактируемых» установок.Из setuptools docs :

Кроме того, команда Develop создает сценарии-оболочки в каталоге целевых сценариев, которые будут запускать ваши сценарии в процессе разработки после проверки того, что все ваши пакеты install_requiresдоступно по sys.path.

pip install -e не совсем то же самое, что python setup.py develop, но оно должно быть очень близко.Я считаю, что реализация - это тонкая оболочка вокруг python setup.py develop.

...