Пакет пространства имен, установленный с возможностью редактирования, и другой, установленный регулярно, не работают вместе.
Такая же проблема здесь :(
Я разместил код для проверки этой ошибки: 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
Вот сценарий для реального воспроизведения этой проблемы
Я не большой поклонник решения --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.
Самый полезный комментарий
Для всех, кому интересно, вот исчерпывающий список того, как пакеты пространств имен работают в
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
.