Как добавить дополнительные файлы на колесо?
Как контролировать, какие файлы включены в колесо? Похоже, что MANIFEST.in
не используется python setup.py bdist_wheel
.
UPDATE
Я ошибся в разнице между установкой из исходного tarball и колесом. Исходный дистрибутив включает файлы, указанные в MANIFEST.in
, но установленный пакет содержит только файлы python. Требуются шаги для идентификации дополнительных файлов, которые должны быть установлены, независимо от того, установлена ли установка через дистрибутив источника, яйцо или колесо. А именно, package_data требуется для дополнительных файлов пакета и data_files для файлов вне вашего пакета, таких как сценарии командной строки или системных конфигурационных файлов.
Оригинальный вопрос
У меня проект, где я использовал python setup.py sdist
для сборки моего пакета, MANIFEST.in
для управления включенными и исключенными файлами и pyroma и check-manifest, чтобы подтвердить мои настройки.
Недавно я преобразовал его в двойной код Python 2/3 и добавил setup.cfg с
[bdist_wheel]
universal = 1
Я могу построить колесо с python setup.py bdist_wheel
, и оно, по-видимому, является универсальным колесом. Однако он не включает все файлы, указанные в MANIFEST.in
.
Что устанавливается?
Я углубился, и теперь знаю больше об упаковке и колесе. Вот что я узнал:
Я загружаю два файла пакета в проект multigtfs на PyPi:
-
multigtfs-0.4.2.tar.gz
- исходный tar-мяч, включающий все файлы в MANIFEST.in
.
-
multigtfs-0.4.2-py2.py3-none-any.whl
- Бинарное распределение, о котором идет речь.
Я создал две новые виртуальные среды с Python 2.7.5 и установил каждый пакет (pip install multigtfs-0.4.2.tar.gz
). Эти две среды практически идентичны. У них разные файлы .pyc
, которые являются "скомпилированными" файлами Python. Существуют файлы журналов, которые записывают разные пути на диске. Установка из исходного tar-шара включает в себя папку multigtfs-0.4.2-py27.egg-info
, подробно описывающая установку, а установка колеса имеет папку multigtfs-0.4.2.dist-info
с подробностями этого процесса. Однако, с точки зрения кода, использующего проект multigtfs, нет никакой разницы между двумя способами установки.
Явным образом, ни один из них не имеет .zip файлов, используемых в моем тесте, поэтому набор тестов не будет выполнен:
$ django-admin startproject demo
$ cd demo
$ pip install psycopg2 # DB driver for PostGIS project
$ createdb demo # Create PostgreSQL database
$ psql -d demo -c "CREATE EXTENSION postgis" # Make it a PostGIS database
$ vi demo/settings.py # Add multigtfs to INSTALLED_APPS,
# Update DATABASE to set ENGINE to django.contrib.gis.db.backends.postgis
# Update DATABASE to set NAME to test
$ ./manage.py test multigtfs.tests # Run the tests
...
IOError: [Errno 2] No such file or directory: u'/Users/john/.virtualenvs/test/lib/python2.7/site-packages/multigtfs/tests/fixtures/test3.zip'
Указание дополнительных файлов
Используя предложения из ответов, я добавил несколько дополнительных директив в setup.py
:
from __future__ import unicode_literals
# setup.py now requires some funky binary strings
...
setup(
name='multigtfs',
packages=find_packages(),
package_data={b'multigtfs': ['test/fixtures/*.zip']},
include_package_data=True,
...
)
Это устанавливает файлы zip (а также README) в папку, и тесты теперь выполняются правильно. Спасибо за предложения!
Ответы
Ответ 1
Вы пытались использовать package_data
в своем setup.py
? MANIFEST.in
кажется целевым для версий python <= 2.6, я не уверен, что более высокие версии даже смотрят на него.
После изучения https://github.com/pypa/sampleproject их MANIFEST.in
говорит:
# If using Python 2.6 or less, then have to include package data, even though
# it already declared in setup.py
include sample/*.dat
который, по-видимому, подразумевает, что этот метод устарел. Между тем, в setup.py
они объявляют:
setup(
name='sample',
...
# If there are data files included in your packages that need to be
# installed, specify them here. If using Python 2.6 or less, then these
# have to be included in MANIFEST.in as well.
package_data={
'sample': ['package_data.dat'],
},
...
)
(Я не уверен, почему они выбрали шаблон в MANIFEST.in
и имя файла в setup.py
. Они ссылаются на тот же файл)
Который, наряду с более простым, снова, кажется, подразумевает, что маршрут package_data
превосходит метод MANIFEST.in
. Ну, если вам не нужно поддерживать 2,6, то есть в этом случае мои молитвы выходят к вам.
Ответ 2
Вы можете указать дополнительные файлы для установки с помощью директивы data_files. Это то, что вы ищете? Вот небольшой пример:
from setuptools import setup
from glob import glob
setup(
name='extra',
version='0.0.1',
py_modules=['extra'],
data_files=[
('images', glob('assets/*.png')),
],
)
Ответ 3
Прежде чем вносить какие-либо изменения в MANIFEST.in
или setup.py
, необходимо удалить старые выходные каталоги. Setuptools кэширует некоторые данные, и это может привести к неожиданным результатам.
rm -rf build *.egg-info
Если вы этого не сделаете, не ожидайте, что ничего не будет работать правильно.
Теперь это не так.
-
Если вы создаете исходный дистрибутив (sdist
), вы можете использовать любой метод ниже.
-
Если вы строите колесо (bdist_wheel
), затем include_package_data
и MANIFEST.in
игнорируются, и вы должны использовать package_data
и data_files
.
INCLUDE_PACKAGE_DATA
Это хороший вариант, но bdist_wheel
не соблюдает его.
setup(
...
include_package_data=True
)
# MANIFEST.in
include package/data.json
DATA_FILES для непакетных данных
Это наиболее гибкий вариант, потому что вы можете добавить любой файл из вашего репо в sdist
или bdist_wheel
setup(
....
data_files=[
('output_dir':['conf/data.json']),
]
# For sdist, output_dir is ignored!
#
# For bdist_wheel, data.json from conf dir in root of your repo
# and stored at 'output_dir/' inside of the sdist package.
)
PACKAGE_DATA для не-python файлов внутри пакета
Как и выше, но для bdist_wheel
вы можете поместить свои файлы данных в пакет. Он идентичен для sdist
но имеет больше ограничений, чем data_files
потому что файлы могут data_files
только из вашего data_files
пакета.
setup(
...
package_data={'package':'data.json'},
# data.json must be inside of your actual package
)
Ответ 4
Вы можете использовать package_data
и data_files
в setup.py
указать дополнительные файлы, но они до смешного трудно получить права (и глючит).
Альтернативой является использование MANIFEST.in
и добавление include_package_data=True
в setup()
вашего setup.py
как указано здесь.
С помощью этой директивы MANIFEST.in
будет использоваться для указания файлов, которые будут включены не только в исходный архив tar/zip, но также в установщик wheel и win32. Это также работает с любой версией Python (я тестировал проект от py2.6 до py3.6).
Ответ 5
У меня был каталог config/с файлами JSON, которые мне нужно было добавить в пакет wheel. Итак, я добавил эти строки в MANIFEST.in
:
recursive-include config/ *.json
Следующая директива для setup.py
:
setup(
...
include_package_data=True,
)
И ничего не сработало. Пока я не создал пустой файл с именем __init__.py
внутри директории config/
.
(Python 3.6.7, колесо 3.6.7, setuptools 39.0.1)
Ответ 6
"Колесо представляет собой архив в формате ZIP..." (http://wheel.readthedocs.org/en/latest)
Итак, обрабатывайте файл .whl так же, как и .zip файл. Добавьте файл с помощью
- Python ZipFile object
- любая утилита архива /zip файла, такая как 7-zip, Winzip, Ark, файловый ролик и т.д.