Как я могу заставить setuptools игнорировать инвентаризацию subversion?
При упаковке пакета Python с помощью setup.py, который использует setuptools:
from setuptools import setup
...
исходный дистрибутив, созданный:
python setup.py sdist
содержит, как обычно, файлы, указанные в файле MANIFEST.in, но он также без исключения включает в себя все файлы, которые списки Subversion являются версиями под каталогом пакетов. Это очень раздражает. Это не только затрудняет осуществление какого-либо явного контроля над тем, какие файлы распространяются вместе с моим пакетом, но это означает, что когда я создаю свой пакет после "svn export" вместо "svn checkout", содержимое моего пакет может быть совсем другим, поскольку без .svn метаданных setuptools будут делать разные варианты того, что включать.
Мой вопрос: как я могу отключить это ужасное поведение, так что "setuptools" относится к моему проекту так же, как я использую Subversion или контроль над версией, о котором он никогда не слышал, или о голом дереве, созданном с помощью "svn export" что я создал в конце моего проекта, чтобы убедиться, что он строит чисто где-то помимо моего рабочего каталога?
Лучшее, что я до сих пор уладил, - уродливый патч обезьяны:
from setuptools.command import sdist
del sdist.finders[:]
Но это Python, а не джунгли, поэтому, конечно, я хочу лучшее решение, в котором вообще нет обезьян. Как я могу приручить setuptools, отключить его магию и заставить себя вести себя разумно, посмотрев на видимые, предсказуемые правила в моем MANIFEST.py?
Ответы
Ответ 1
Я знаю, что ты много знаешь об этом, Брэндон, но я постараюсь дать как полный ответ, как я могу (хотя я и не хочу, чтобы он был хорош для других).
Проблема в том, что setuptools сам включает в себя довольно много черной магии, включая использование точки входа setuptools.file_finders, где вы можете добавлять плагины для поиска файлов для включения. Я, однако, полностью потеряю, как удалить из него плагины...
-
Быстрое обходное решение: svn экспортирует ваш пакет во временный каталог и запустит setup.py. Это означает, что у вас нет svn, поэтому svn finder не находит файлов для включения.:)
-
Более длительное обходное решение: вам действительно нужны setuptools? У Setuptools есть много возможностей, поэтому ответ, скорее всего, да, но в основном эти функции являются depdenencies (поэтому ваши зависимости устанавливаются с помощью easy_install), пакетов пространства имен (foo.bar) и точек входа. Пакеты пространства имен могут быть созданы без setuptools. Но если вы не используете ни один из них, вам действительно удастся просто использовать distutils.
-
Уродливое обходное решение: обезьяна, которую вы дали sdist в своем вопросе, который просто заставляет плагин не иметь никаких искателей и быстро выйти.
Итак, как вы видите, этот ответ, хотя и настолько полный, насколько я могу это сделать, все еще неловко незавершен. Я не могу ответить на ваш вопрос, хотя я думаю, что ответ "Ты не можешь".
Ответ 2
Создайте файл MANIFEST.in с помощью
recursive-exclude .
# other MANIFEST.in commands go here
# to explicitly include whatever files you want
См. http://docs.python.org/distutils/commandref.html#sdist-cmd для синтаксиса MANIFEST.in.
Ответ 3
Возможно, ответ находится в вашем setup.py. Вы используете find_packages? Эта функция по умолчанию использует VCS (например, subversion, hg,...). Если вам это не нравится, просто напишите другую функцию Python, которая собирает только те вещи, которые вы хотите.
Ответ 4
Я бы сказал, что поведение sdist по умолчанию правильное. Когда вы создаете дистрибутив source, я ожидаю, что он будет содержать все, который будет проверен в Subversion. Разумеется, было бы неплохо, если бы они были в состоянии приспособить его в особых обстоятельствах.
Сравните sdist с bdist_egg; Я ставлю, что только файлы, которые явно указаны, включены.
Я сделал простой тест с тремя файлами, все в svn. Пустые dummy.lkj и foobar.py и с setup.py выглядит так:
import setuptools
setuptools.setup(name='foobar', version='0.1', py_modules=['foobar'])
sdist создает tarball, который включает dummy.lkj. bdist_egg создает яйцо, которое не включает dummy.lkj.
Ответ 5
Вероятно, вы хотите что-то вроде этого:
from distutils.core import setup
def packages():
import os
packages = []
for path, dirs, files in os.walk("yourprogram"):
if ".svn" in dirs:
dirs.remove(".svn")
if "__init__.py" in files:
packages.append(path.replace(os.sep, "."))
return packages
setup(
# name, version, description, etc...
packages = packages(),
# pacakge_data, data_files, etc...
)