<p>pip install --editable и pip install clash для пакетов пространства имен</p>

Созданный на 14 мар. 2011  ·  41Комментарии  ·  Источник: pypa/pip

Пакет пространства имен, установленный с возможностью редактирования, и другой, установленный регулярно, не работают вместе.

auto-locked bug

Самый полезный комментарий

Для всех, кому интересно, вот исчерпывающий список того, как пакеты пространств имен работают в pip install , pip install -e , python setup.py install и python setup.py develop :

https://github.com/jonparrott/namespace-pkg-tests/blob/master/table.md

tl; dr: вы можете использовать pip install -e и python setup.py develop если все остальные пакеты в вашем пространстве имен были установлены с использованием pip .

Все 41 Комментарий

Такая же проблема здесь :(

Я разместил код для проверки этой ошибки: http://public.hg.stephane-klein.info/hgwebdir.cgi/test_pip_namespace_bug_3/

Корень проблемы здесь в том, что в setuptools есть два метода для обеспечения работы пакетов пространства имен: метод __init__.py (который задокументирован и может использоваться людьми) и метод ...-nspkg.pth file, который является используется только с --single-version-externally-managed (который использует пип). Эти два метода несовместимы друг с другом.

После некоторого обсуждения с mitsuhiko и другими в IRC, кажется, что лучшим (частичным) решением для pip является добавление «pip install -e» модифицированной версии стандартного файла setuptools ... nspkg.pth для каждого установленного пакета. . (Необходимые изменения заключаются в том, чтобы вместо sitedir использовать путь разработки egg-link и полностью пропустить проверку для init .py, поскольку пакет, установленный для разработки, будет иметь init .py). Это означает, что pip по крайней мере будет совместим с самим собой (пакеты пространства имен pip-installed и pip-editable-installed будут работать вместе). Пакеты пространств имен Pip-installed и setuptools / distribute-installed несовместимы.

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

Я думаю, что pip должен каким-то образом просто убить nspkg.pth и установить __init__.py . Пока сам пакет спроектирован правильно (т.е. __init__.py пуст, за исключением extension_path / declare_namespace), это не должно быть проблемой. Параметр --single-version-ex external-managed был разработан с учетом системных упаковщиков, но они не собираются использовать pip в первую очередь. Поэтому мне интересно, есть ли какой-нибудь способ полностью отключить это поведение, не слишком навязчиво.

+1 для перехода от '--single-version-external-managed': этот параметр вообще не предназначен для вариантов использования pip. Если pip не может выполнять хотя бы такую ​​же работу по установке, как easy_install, какова его цель?

Полностью отказаться от --single-version-externally-managed не будет; плоские установки - это особенность. Я бы рассмотрел возможность отказа от него только в случае пакетов пространства имен, чтобы избежать этих проблем. Мне это не нравится, но, похоже, здесь нет отличного варианта, учитывая присущую несовместимость между двумя типами поддержки пакетов пространства имен, встроенными в setuptools / distribute.

Утверждение, что --single-version-externally-managed «не предназначено для случаев использования pip» - это нечто среднее между ошибкой и отвлекающим маневром. Флаг предназначен для того, чтобы разрешить плоскую установку одной версии, управляемую каким-либо инструментом, кроме easy_install. Именно для этого pip использует его; тот факт, что автор setuptools изначально (и ошибочно) думал, что только системные упаковщики будут заинтересованы в такой функции, не имеет значения.

Сломка здесь - это неотъемлемая ошибка в методе, который setuptools использует для пакетов пространства имен с этим флагом, и ошибка так же присутствует, когда флаг используется первоначально предполагаемой аудиторией, системными упаковщиками (я впервые увидел ошибку во взаимодействии между setup.py develop "установленный пакет и пакет пространства имен, установленный системным пакетом).

Я тоже столкнулся с этой ошибкой. Думаю, это одна из тех неразрешимых ошибок, которые надолго останутся. Ну что ж.

Я бы принял патч, чтобы избежать --single-version-externally-managed когда задействован пакет пространства имен, который, я думаю, решит эту проблему. В настоящее время я не планирую писать этот патч.

Почему не вариант, который мы можем передать в pip install чтобы не использовать --single-version-externally-managed ? Я тестирую, комментируя это в ./pip/req.py:568 и все пакеты, которые теперь установлены в каталог egg, точно так же, как это делает easy_install. Когда-нибудь я захочу сделать это, если бы я использовал и pip, и easy_install, чтобы мой site-packages не смешивался с некоторыми пакетами, устанавливаемыми плоско, а некоторые нет.

Я не вижу проблем с опцией --egg для отказа от --single-version-externally-managed .

https://github.com/k4ml/pip/commit/93cd6b16207d2eba201a7fc3126624b616f5e6f9

Может кто-нибудь прокомментировать, иду ли я в правильном направлении? Я впервые взламываю pip-код, так что это основано на том, что я за несколько минут заглянул в его часть, просто чтобы pip install --egg somepackages установить все в один каталог яиц.

Может кто-нибудь прокомментировать, иду ли я в правильном направлении?

По-моему, неплохо, нужен тест. Тесты в основном высокого уровня
интеграционные тесты, использующие ScriptTest, должно быть легко написать на основе
существующие примеры. В этом случае вам нужно просто протестировать эту установку
образец пакета приводит к файлу .egg, а не к плоской установке, в
сайт-пакеты. Вы должны установить пакет из локальной файловой системы,
не сеть: tests/packages/FSPkg , вероятно, будет работать нормально. Добавление
тест на tests/test_basic.py в порядке.

Благодаря!

Запросы на вытягивание - https://github.com/pypa/pip/pull/541

Я также думаю о том, чтобы установить этот флаг в pip.conf. Что ты об этом думаешь?

Я также думаю о том, чтобы установить этот флаг в pip.conf. Что ты об этом думаешь?

Обсудим пулреквест.

Объединенный запрос на вытягивание № 541, который предоставляет одно временное решение. Спасибо @ k4ml!

Примечание. Параметр --egg , который был добавлен для устранения этой проблемы, потенциально может быть удален, без каких-либо альтернативных решений. См. Обсуждение в # 1749

Вот сценарий для реального воспроизведения этой проблемы

https://gist.github.com/Ivoz/d9bff05069e0ec53e6ea

Я не большой поклонник решения --egg, но для этого должен быть менее громоздкий обходной путь.

без обходного пути во время разработки я не могу использовать --editable один раз, а затем просто редактировать и тестировать. каждый раз, когда я сохраняю свой код, мне приходится запускать pip install -I --no-deps . который становится очень старым и хрупким (читай: иногда я забываю).

Часть проблемы с тем, как проявляется эта проблема, заключается в том, что она молчит. вы просто не можете импортировать модуль, даже если он установлен, и pip сообщает вам, что он есть.

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

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

Я отправил 2 предложения по исправлению этой проблемы в setuptools https://bitbucket.org/pypa/setuptools/issue/250/develop-and-install-single-version. К вашему сведению.

положить

import pkg_resources; pkg_resources.fixup_namespace_packages ('')

в файле .pth в пакетах сайтов кажется достаточным для правильной работы pip install -e install.

Это также влияет на два пакета с одним и тем же верхним пространством имен, оба из которых установлены как редактируемые. Установка второго пакета не работает.

Мы используем глобальное пространство имен для всех наших приложений, и поэтому эта проблема немного сложна (+ проблема, что setuptools не поддерживает колеса, что необходимо из-за отсутствия компилятора на наших платформах развертывания Windows). Также все рекомендуемые решения, похоже, не работают в нашей настройке с Python 3.4.

Поняв, что pip install -e действительно запускает setup.py develop для проекта, который должен быть редактируемым, я подключился к процедуре setuptools и написал файл * .pth, который "вводит" пакеты пространства имен, когда процесс python начинается. Это решает проблему при использовании setuptools 18 и pip 7.1.0.

Пример файла setup.py, показывающий, как этого можно достичь, можно найти здесь:
https://gist.github.com/cbrand/a1624ac3e9c81ce45fcb

Надеюсь, это будет полезно и для других.

Я столкнулся с этим сегодня, и он не позволяет мне переключаться с buildout на virtualenv + pip.

Я создал небольшую демонстрацию, демонстрирующую проблему. Чтобы проверить это, распакуйте .tar.gz и запустите внутри него скрипт {{run-me}}. Может быть полезно при тестировании исправления.

Я тоже сталкиваюсь с этой проблемой.

Пытаясь разобраться, я наткнулся на решение, предложенное @carljm в https://github.com/pypa/pip/issues/3#issuecomment -1659959, т.е. _have "pip install -e" добавить измененную версию стандарта setuptools ... nspkg.pth для каждого установленного пакета.

Я экспериментировал с этим подходом вручную, и, похоже, он работает хорошо. Похоже, что это в то же время решит вопрос неглубоких исходных деревьев с отсутствующими пакетами пространств имен, как описано в # 3160.

Поэтому мне интересно, считается ли этот подход действительным, предпринимались ли какие-либо попытки его реализовать и будет ли рассматриваться патч для этого?

Итак ... нет надежды на то, что это исправят в ближайшем будущем?

Некоторый побочный эффект pkg_resources.get_distribution() заставляет импорт работать. Мы обнаружили это, когда код, загружающий точки входа, работал правильно, в то время как оболочка python отказала.

Это также может объяснить, почему оболочка ipython не имеет проблем с импортом пакетов.

Я удивлен, что эта ошибка все еще открыта, и через 5 лет ее не удалось решить.

Если ваша работа состоит в том, чтобы склеить фреймворки в одну единую структуру, pip сделает вашу работу отстой. Честно говоря, я не знаю, как продолжить работу из-за этой ошибки.

Эту проблему сложно исправить в проектах, в основном выполняемых волонтерами.
Не стесняйтесь добавлять необходимую поддержку в setuptools, чтобы pip мог сделать это правильно

Брэндон Github [email protected] пишет:

Я удивлен, что эта ошибка все еще открыта, и через 5 лет ее не удалось решить.

Ага, жаль.

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

Недавно я применил хак fixup_namespace_packages (''), упомянутый выше, и
похоже, это работает: я создал z.pth внутри пакетов сайта venv
содержащий только import pkg_resources; pkg_resources.fixup_namespace_packages('')

Стоит попробовать, ИМХО.

Просто еще одна шишка!

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

Подход pip работает, по моему опыту, только если _every_ пакет установлен, доступен для редактирования с диска, который взаимодействует с пространством имен. Если один пакет устанавливается без возможности редактирования через pip, весь клубок пряжи начинает распутываться с некоторыми очень, очень тупыми симптомами для новых пользователей. (Например, периодически импортируемые модули; общая проверка работоспособности при импорте родительского пространства имен и проверке namespace.__path___ быстро определила виновный пакет при тестировании.) Смешивание правильно установленных пакетов и чистых setup.py develop 'd исходные (избегая пипса), однако, работают.

Мы также, кажется, можем попасть в странные ситуации, когда один пакет, вносящий вклад в пространство имен, может быть установлен тремя разными способами, иногда все одновременно. (Повторные вызовы pip uninstall , каждый из которых находит новые файлы, выглядят столь же забавно, сколь и прискорбно.) Установка зависимостей при использовании pip install -e кажется непоследовательной. В большинстве случаев мы получаем правильно распакованные пространства имен (установленные), файлы pth-link (установленные редактируемые), и в одном случае нам каким-то образом удалось установить заархивированный .egg , несмотря на то, что zip_safe является False в этом зависимом пакете, и на Pypi не предоставляется распространение .egg .

Разочарование по поводу проблем с пространством имен достигает пика после четвертого раза, когда виртуальная среда запускается с нуля. ;)

Не решение, но я просто поставил несколько заметок. При смешивании «редактируемых» пакетов, пакетов с пространством имен и обычных пакетов мне больше повезло с buildout + mr.developer.

Хотя упомянутый способ исправления @lelit, похоже, работает для некоторых пакетов, он также ломает некоторые пакеты / сборки для нас.

После некоторой игры с pip install и редактируемым режимом я пришел к той же идее, что и @carljm (добавление файла -nspkg.pth для каждого редактируемого пакета), но, похоже, никто этого не реализовал (или это было теперь устаревшим - -яйцо вариант?).

Это все еще проблема в более новых версиях Python с реализованным PEP420? (читайте: поможет ли перейти на более новую версию python?)

Использование стиля PEP420 эффективно помогло мне несколько раз теперь в редактируемом режиме.

К сожалению, он имеет свои собственные глюки: например, find_packages setuptools не поддерживает его , поэтому мои новые пакеты содержат следующий взлом:

-    packages=find_packages('src'),
+    packages=['toplevel.child.' + package
+              for package in find_packages('src/toplevel/child/')],

Кажется, никто не реализовал добавление -nspkg.pth для каждого редактируемого пакета.

Ознакомьтесь с Setuptools 31, который добавляет поддержку этой функции, а также сосуществует с пакетами PEP-420 на Python 3.5+.

Для всех, кому интересно, вот исчерпывающий список того, как пакеты пространств имен работают в pip install , pip install -e , python setup.py install и python setup.py develop :

https://github.com/jonparrott/namespace-pkg-tests/blob/master/table.md

tl; dr: вы можете использовать pip install -e и python setup.py develop если все остальные пакеты в вашем пространстве имен были установлены с использованием pip .

Я собираюсь закрыть этот выпуск. Похоже, что в setuptools 31 это исправлено для наших сценариев воспроизведения, и кроме этого здесь ничего не может сделать pip.

@jonparrott
Какие версии pip и setuptools использовались для получения результатов на https://github.com/jonparrott/namespace-pkg-tests/blob/master/table.md ?

@dstufft Хотя я понимаю, что это якобы исправлено, я бы хотел увидеть повторное выполнение таблицы совместимости @jonparrott в качестве доказательства. Я надеюсь на лучшее, планирую худшее для билетов, которым почти 7 лет и которые имеют такие широко распространенные сценарии отказа. Уверенность невысока, учитывая обширную историю этой проблемы, и при повторном запуске пакета nox самостоятельно, сбои будут указывать на отсутствие фактического решения.

В примерах @jonparrott случаи сбоя могут быть сокращены до «прямого использования python setup.py install (исключая ожидаемые сбои PEP 420 на Python 2). Это не удается даже в тех случаях, когда pip не задействован. вообще (например, python setup.py install + python setup.py develop ).

Этот билет предназначен для комбинаций pip install . и pip install -e или python setup.py develop .

График, уже опубликованный @jonparrott, свидетельствует о том, что этот тикет решен, и все оставшиеся проблемы здесь python setup.py install а не с pip.

Я только что повторно запустил свои тесты, и все осталось так же, как и вначале. Я согласен с оценкой @dstufft - pip сделал все возможное, чтобы решить эту проблему.

@ piotr-dobrogost в тесте используются последние версии обоих. На момент написания этой статьи pip 9.0.1 и setuptools 34.3.2.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги