Вопрос

Как мне сделать setup.py включить файл, который не является частью кода?(В частности, это файл лицензии, но это может быть любая другая вещь.)

Я хочу иметь возможность контролировать расположение файла.В исходной папке файл находится в корневом каталоге пакета.(т.е.на том же уровне, что и самый верхний __init__.py.) Я хочу, чтобы он оставался точно таким же, когда пакет установлен, независимо от операционной системы.Как мне это сделать?

Это было полезно?

Решение

Вероятно, лучший способ сделать это - использовать setuptools package_data директива.Это действительно означает использование setuptools (или distribute) вместо distutils, но это очень плавное "обновление".

Вот полный (но непроверенный) пример:

from setuptools import setup, find_packages

setup(
    name='your_project_name',
    version='0.1',
    description='A description.',
    packages=find_packages(exclude=['ez_setup', 'tests', 'tests.*']),
    package_data={'': ['license.txt']},
    include_package_data=True,
    install_requires=[],
)

Обратите внимание на конкретные строки, которые здесь имеют решающее значение:

package_data={'': ['license.txt']},
include_package_data=True,

package_data является dict из имен пакетов (пусто = все пакеты) в список шаблонов (может включать глобусы).Например, если вы хотите указать только файлы в своем пакете, вы тоже можете это сделать:

package_data={'yourpackage': ['*.txt', 'path/to/resources/*.txt']}

Решение здесь определенно есть нет чтобы переименовать свой не-py файлы с .py расширение.

Видишь Презентация Иэна Бикинга для получения дополнительной информации.

Обновить:Другой [Лучший] Подход

Другой подход, который хорошо работает, если вы просто хотите контролировать содержимое исходного дистрибутива (sdist) и иметь файлы вне пакета (например,каталог верхнего уровня) заключается в добавлении MANIFEST.in файл.Видишь документация по Python для определения формата этого файла.

С момента написания этого ответа я обнаружил, что с помощью MANIFEST.in обычно это менее разочаровывающий подход, чтобы просто убедиться, что ваш исходный дистрибутив (tar.gz) содержит нужные вам файлы.

Например, если вы хотите включить requirements.txt начиная с верхнего уровня, рекурсивно включите каталог "data" верхнего уровня:

include requirements.txt
recursive-include data *

Тем не менее, для того, чтобы эти файлы были скопированы во время установки в папку пакета внутри site-packages, вам необходимо предоставить include_package_data=True к тому setup() функция.Видишь Добавление файлов, не содержащих код для получения дополнительной информации.

Другие советы

Чтобы выполнить то, что вы описываете, потребуется два шага...

  • Файл необходимо добавить в исходный архив архива
  • setup.py необходимо внести изменения, чтобы установить файл данных по исходному пути

Шаг 1:Чтобы добавить файл в исходный архив, включите его в МАНИФЕСТ

Создать ПРОЯВЛЯЮЩИЙСЯ шаблон в папке, содержащей setup.py

МАНИФЕСТ - это, по сути, текстовый файл со списком всех файлов, которые будут включены в исходный архив.

Вот как выглядит МАНИФЕСТ для моего проекта:

  • CHANGELOG.txt
  • INSTALL.txt
  • LICENSE.txt
  • pypreprocessor.py
  • README.txt
  • setup.py
  • test.py
  • TODO.txt

Примечание:В то время как sdist делает автоматическое добавление некоторых файлов, Я предпочитаю явно указывать их, чтобы быть уверенным, вместо того, чтобы предсказывать, что он делает, а что нет.

Шаг 2:Чтобы установить файл данных в исходную папку, измените setup.py

Поскольку вы хотите добавить в файл данных (LICENSE.txt) источник установить папку, необходимо изменить данные путь установки, соответствующие исходному пути установки.Это необходимо, поскольку по умолчанию файлы данных устанавливаются в другое расположение, чем исходные файлы.

Чтобы изменить каталог установки данных в соответствии с исходным каталогом установки...

Извлеките информацию об установочном каталоге из distutils с помощью:

from distutils.command.install import INSTALL_SCHEMES

Измените каталог установки данных, чтобы он соответствовал исходному каталогу установки:

for scheme in INSTALL_SCHEMES.values():
    scheme['data'] = scheme['purelib']

И добавьте файл данных и местоположение в setup():

data_files=[('', ['LICENSE.txt'])]

Примечание:Описанные выше шаги должны выполнять именно то, что вы описали стандартным образом, не требуя каких-либо библиотек расширений.

создайте MANIFEST.in в корневом каталоге проекта с помощью recursive-include в нужном каталоге или include с именем файла.

include LICENSE
include README.rst
recursive-include package/static *
recursive-include package/templates *

документацию можно найти здесь

В setup.py в настройках (:

setup(
   name = 'foo library'
   ...
  package_data={
   'foolibrary.folderA': ['*'],     # All files from folder A
   'foolibrary.folderB': ['*.txt']  #All text files from folder B
   },

Вот более простой ответ, который сработал для меня.

Во-первых, согласно приведенному выше комментарию Python Dev, setuptools не требуется:

package_data is also available to pure distutils setup scripts 
since 2.3. – Éric Araujo

Это замечательно, потому что, установив в пакете требование setuptools, вам также придется установить его. Короче говоря:

from distutils.core import setup

setup(
    # ...snip...
    packages          = ['pkgname'],
    package_data      = {'pkgname': ['license.txt']},
)

Шаг 1: создайте файл MANIFEST.in в той же папке, что и файл setup.py

Шаг 2: укажите относительный путь к файлам, которые вы хотите добавить в MANIFEST.in

include README.rst
include docs/*.txt
include funniest/data.json

Шаг 3: установите include_package_data = True в функции setup () , чтобы скопировать эти файлы в пакет сайта

ссылка здесь

Я просто хотел продолжить работу с Python 2.7 в Centos 6. Добавление пакетов_данных или файлов_данных, как упомянуто выше, не сработало для меня. Я добавил MANIFEST.IN с нужными мне файлами, которые помещают файлы, отличные от python, в tarball, но не устанавливал их на целевой машине через RPM.

В итоге я смог получить файлы в своем решении, используя " параметры " в настройках / setuptools. Файлы опций позволяют вам изменять различные разделы файла спецификации из setup.py. Следующим образом.

from setuptools import setup


setup(
    name='theProjectName',
    version='1',
    packages=['thePackage'],
    url='',
    license='',
    author='me',
    author_email='me@email.com',
    description='',
    options={'bdist_rpm': {'install_script': 'filewithinstallcommands'}},
)

файл - MANIFEST.in:

include license.txt

файл - файл с командами установки:

mkdir -p $RPM_BUILD_ROOT/pathtoinstall/
#this line installs your python files
python setup.py install -O1 --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES
#install license.txt into /pathtoinstall folder
install -m 700 license.txt $RPM_BUILD_ROOT/pathtoinstall/
echo /pathtoinstall/license.txt >> INSTALLED_FILES

Я хотел оставить комментарий к одному из вопросов, но у меня недостаточно репутации, чтобы сделать это >.>

Вот что сработало у меня (придумал это после обращения к документам):

package_data={
    'mypkg': ['../*.txt']
},

include_package_data: False

Последняя строка, как ни странно, также оказалась для меня решающей (вы также можете опустить этот аргумент ключевого слова - он работает так же).

Что это делает, так это копирует все текстовые файлы в ваш каталог верхнего уровня или корневой каталог (на один уровень выше пакета mypkg вы хотите распространять).

Надеюсь, это поможет!

Обошел обходной путь: я переименовал свой lgpl2.1_license.txt в lgpl2.1_license.txt.py и поместил несколько тройных кавычек вокруг текста. Теперь мне не нужно ни использовать параметр data_files , ни указывать абсолютные пути. Я знаю, что сделать его модулем Python некрасиво, но считаю его менее уродливым, чем указание абсолютных путей.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top