Как я могу заставить setuptools игнорировать инвентарь Subversion?

При упаковке пакета Python с помощью setup.py, который использует setuptools:

from setuptools import setup
...

исходный дистрибутив, созданный:

python setup.py sdist

не только включает, как обычно, файлы, указанные в MANIFEST.in, но также безвозмездно включает все файлы, которые Subversion перечисляет как контролируемые версиями в каталоге пакета. Это сильно раздражает. Это не только затрудняет какой-либо явный контроль над тем, какие файлы распространяются вместе с моим пакетом, но и означает, что когда я собираю свой пакет после «svn export» вместо «svn checkout», содержимое моего package может быть совсем другим, так как без .svn метаданных setuptools будет выбирать, что включать.

Мой вопрос: как я могу отключить это ужасное поведение, чтобы «setuptools» обрабатывал мой проект одинаково, использую ли я Subversion, или контроль версий, о котором он никогда не слышал, или голое дерево, созданное с помощью «svn export», которое я создали в конце моего проекта, чтобы убедиться, что он правильно строится где-то, кроме моего рабочего каталога?

Лучшее, что мне удалось до сих пор, это уродливая обезьяна-патч:

from setuptools.command import sdist
del sdist.finders[:]

Но это Python, а не джунгли, поэтому, конечно, я хочу лучшее решение, в котором вообще не используются обезьяны. Как я могу укротить setuptools, отключить его магию и заставить его вести себя разумно, вместо этого глядя на видимые, предсказуемые правила в моем MANIFEST.py?


person Brandon Rhodes    schedule 15.07.2009    source источник
comment
Я думаю, что у меня точно такая же проблема, только с .git и py2app: stackoverflow.com/questions/9845590/   -  person jdi    schedule 30.03.2012
comment
Вау, действительно похоже, та же проблема!   -  person Brandon Rhodes    schedule 31.03.2012
comment
Я опубликовал хак с обезьянкой в ​​качестве ответа на свой вопрос. пока ничего лучше не нашел   -  person jdi    schedule 31.03.2012


Ответы (6)


Простое решение, не используйте setuptools для создания исходного дистрибутива, перейдите на distutils для этой команды:

from distutils.command.sdist import sdist
from setuptools import setup

setup(
    # ... all the usual setup arguments ...
    cmdclass = {'sdist': sdist},
)
person Rotkraut    schedule 11.04.2020
comment
Я не знал, что класс можно настроить для каждой команды! Спасибо что подметил это. - person Brandon Rhodes; 12.04.2020

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

Проблема здесь в том, что сам setuptools включает довольно много черной магии, в том числе использование точки входа с именем setuptools.file_finders, где вы можете добавлять плагины для поиска файлов для включения. Я, однако, в полной растерянности относительно того, как УДАЛИТЬ плагины из него...

  • Быстрый обходной путь: svn экспортирует ваш пакет во временный каталог и запускает оттуда setup.py. Это означает, что у вас нет svn, поэтому программа поиска svn не находит файлов для включения. :)

  • Более длинный обходной путь: вам действительно нужны setuptools? Setuptools имеет много функций, поэтому ответ, скорее всего, да, но в основном эти функции — это зависимости (поэтому ваши зависимости устанавливаются easy_install), пакеты пространства имен (foo.bar) и точки входа. Пакеты пространства имен также могут быть созданы без инструментов настройки. Но если вы не используете ни один из них, вам может сойти с рук просто использование distutils.

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

Итак, как вы видите, этот ответ, хотя и настолько полный, насколько я могу его сделать, все же до смущения неполный. На самом деле я не могу ответить на ваш вопрос, хотя я думаю, что ответ «Вы не можете».

person Lennart Regebro    schedule 15.07.2009

Создайте файл 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.

person PJ Eby    schedule 24.12.2009
comment
Это вызывает ошибку для меня. Мне пришлось использовать recursive-exclude . *. - person Aryeh Leib Taurog; 28.01.2014

Вероятно, ответ находится в вашем setup.py. Вы используете find_packages? Эта функция по умолчанию использует VCS (например, subversion, hg, ...). Если вам это не нравится, просто напишите другую функцию Python, которая собирает только то, что вам нужно.

person Felix Schwarz    schedule 15.07.2009
comment
На самом деле find_packages просто использует listdir и ищет файлы с именами __init__.py. - person Lennart Regebro; 15.07.2009

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

Сравните sdist с bdist_egg; Бьюсь об заклад, будут включены только те файлы, которые указаны явно.

Я сделал простой тест с тремя файлами, все в svn. Пустые файлы dummy.lkj и foobar.py с setup.py выглядят так:

import setuptools
setuptools.setup(name='foobar', version='0.1', py_modules=['foobar'])

sdist создает архив, который включает dummy.lkj. bdist_egg создает яйцо, которое не включает dummy.lkj.

person Heikki Toivonen    schedule 15.07.2009

Вы, вероятно, хотите что-то вроде этого:

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...
)
person Fake Code Monkey Rashid    schedule 15.07.2009
comment
+1: Для тех, кто минусует, объясните, почему пост недействителен. Этот подход, кажется, отлично работает. - person Mr Fooz; 17.06.2014