LINUX.ORG.RU

Баг в питоне?

 


1

1

Привет, ЛОР!

Натолкнулся я тут на забавный артефакт. Вкратце, если в директории есть файл, совпадающий по имени со встроенными модулями питона, то некоторые программы пытаются загрузить его вместо встроенного модуля.

Я на это напоролся при использовании pipenv. Например:

~/trash/test> find .
.
./Pipfile.lock
./derp
./derp/__init__.py
./derp/types.py
./Pipfile
/trash/test> pipenv --venv
/home/void/.local/share/virtualenvs/test-qwpSrWlE
~/trash/test> cd derp 
~/trash/test/derp> cat types.py 
raise Exception("Python is retarded")
~/trash/test/derp> pipenv --venv
Fatal Python error: initsite: Failed to import the site module
Traceback (most recent call last):
  File "/nix/store/yf4i32dx953p2dv2agfdyxdwg6ba0l61-python3.7-setuptools-41.0.1/lib/python3.7/site-packages/site.py", line 73, in <module>
    __boot()
  File "/nix/store/yf4i32dx953p2dv2agfdyxdwg6ba0l61-python3.7-setuptools-41.0.1/lib/python3.7/site-packages/site.py", line 26, in __boot
    import imp  # Avoid import loop in Python 3
  File "/nix/store/s5f3vpmig33nk4zyk228q55wdydd3pc2-python3-3.7.3/lib/python3.7/imp.py", line 19, in <module>
    from importlib._bootstrap import _ERR_MSG, _exec, _load, _builtin_from_name
  File "/nix/store/s5f3vpmig33nk4zyk228q55wdydd3pc2-python3-3.7.3/lib/python3.7/importlib/__init__.py", line 57, in <module>
    import types
  File "./types.py", line 1, in <module>
    raise Exception("Python is retarded")
Exception: Python is retarded

Скажи, ЛОР, это вообще нормально? Если нет, то это баг в самом пистоне или это баг в pipenv? Или я чего-то не понимаю и мне просто нельзя называть свои модули types.py, re.py и т.д.?

Скажи, ЛОР, это вообще нормально?

Нет. Питон ищет модули в директориях из списка sys.path. Рабочей директории там по умолчанию нет.

то это баг в самом пистоне

Нет.

или это баг в pipenv?

Дерьмом не пользуюсь.

мне просто нельзя называть свои модули types.py

Разрешаю, смотри при импорте не перепутай.

anonymous ()
Ответ на: комментарий от anonymous

Нет. Питон ищет модули в директориях из списка sys.path. Рабочей директории там по умолчанию нет.

Мне почему-то кажется, что это — очень плохой дизайн, но тем не менее. Там действительно первый же элемент sys.path — это '.'. Быстрый grep по сырцам pipenv показывает какие-то странные манипуляции с sys.path. На этом я пока закончу и пойду спать. Спасибо.

Дерьмом не пользуюсь.

Какие альтернативы есть? Я взял pipenv потому что для него есть нормальный модуль под имагз. Из альтернатив я только poetry видел.

Разрешаю, смотри при импорте не перепутай.

Почему я должен их перепутать? import project.module.types и всё ок.

hateyoufeel ★★★★★ ()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

Мне почему-то кажется, что это — очень плохой дизайн, но тем не менее.

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

Какие альтернативы есть?

python3 -m venv чтобы создать окружение, pip чтобы устанавливать пакеты.

Почему я должен их перепутать? import project.module.types и всё ок.

Тогда ок.

anonymous ()

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

Virtuos86 ★★★★★ ()
Ответ на: комментарий от anonymous

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

Я про это же. А тут какая-нибудь библиотека просунет тебе '.' в sys.path и привет.

python3 -m venv чтобы создать окружение, pip чтобы устанавливать пакеты.

Я хочу воспроизводимую сборку. Или в питоне так не принято?

hateyoufeel ★★★★★ ()
Ответ на: комментарий от ggrn

ОП, скажи пожалуйста чем оно лучше virtualenvwrapper ?

Это разные инструменты. Virtualenvwrapper — это просто управление venv'ами. Pipenv позволяет делать более-менее вопроизводимую сборку.

hateyoufeel ★★★★★ ()
Ответ на: комментарий от anonymous

pip freeze > requirements.txt pip install -r requirements.txt

Оно уже diamond dependencies научилось корректно обрабатывать? Мне тут говорили, что нет.

Плюс, у pipenv есть полезные фичи. Отдельные зависимости, нужные только для разработки, например. Чтобы pylint не деплоить.

hateyoufeel ★★★★★ ()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

Оно уже diamond dependencies научилось корректно обрабатывать? Мне тут говорили, что нет.

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

Ты из жабоскрипта сбежал, где каждая трёхстрочная функция отдельно опакечивается?

Отдельные зависимости, нужные только для разработки, например. Чтобы pylint не деплоить.

requirements-dev.txt

anonymous ()
Ответ на: комментарий от anonymous

Ты из жабоскрипта сбежал, где каждая трёхстрочная функция отдельно опакечивается?

Хуже. Из хацкелла с рустом.

requirements-dev.txt

И руками дёргать сначала одно, а потом другое? Я просто хочу, чтобы всё за меня было сделано и работало, и чтобы мне не приходилось думать о таких банальных вещах. В других языках такой тулинг уже есть. Почему нельзя так сделать для пистона, кроме как потому что деды страдали и нам завещали, я не понимаю.

hateyoufeel ★★★★★ ()
Ответ на: комментарий от hateyoufeel

И руками дёргать сначала одно, а потом другое?

В чём проблема?

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

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

anonymous ()
Ответ на: комментарий от anonymous

В чём проблема?

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

hateyoufeel ★★★★★ ()
Ответ на: комментарий от hateyoufeel

В идеале я хочу, чтобы после git clone я мог запустить максимум одну команду и получить готовое рабочее окружение.

python3 -m venv venv && source venv/bin/activate && pip install -r requirements-dev.txt
anonymous ()
Ответ на: комментарий от hateyoufeel

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

А изначально проблема-то какая? Или просто принципиально хочется чтобы вот «максимум одна команда для локальной развёртки, и чтобы никаких вложений»?

Anyway, я использую direnv, мне нравится.

true_admin ★★★★★ ()
Ответ на: комментарий от true_admin

А изначально проблема-то какая? Или просто принципиально хочется чтобы вот «максимум одна команда для локальной развёртки, и чтобы никаких вложений»?

Изначально я подумал, что вряд ли питоносообщество настолько убого, чтобы не было рабочих аналогов cabal или cargo.

hateyoufeel ★★★★★ ()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от t184256

Да, когда ты сам себе в ногу и пальнул - нормальное.

Каким образом я себе в ногу пальнул?

ненужно, убивать, выжечь огнем.

Ты тоже успокой свою боль.

hateyoufeel ★★★★★ ()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

Каким образом я себе в ногу пальнул?

создал файл, совпадающий по имени со используемым модулем питона в частности.

начал писать на языке, не прочитав даже официальный туториал в целом.

Ты тоже успокой свою боль.

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

t184256 ★★★★★ ()
Ответ на: комментарий от t184256

создал файл, совпадающий по имени со используемым модулем питона в частности.

Так а почему так делать нельзя? Если завтра в питон добавят модуль X, а у меня X уже в проекте есть, мне переименовывать свой?

Вообще, с виду в питоне действительно какая-то срань с модулями.

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

Что ж поделать, если альтернативы нет.

hateyoufeel ★★★★★ ()
Ответ на: комментарий от hateyoufeel

Так а почему так делать нельзя?

https://docs.python.org/3/tutorial

Если завтра в питон добавят модуль X, а у меня X уже в проекте есть, мне переименовывать свой?

Ты чем слушаешь? Только если завтра в зависимости твоего проекта добавится одноименный с имеющимся модуль X.

Что ж поделать, если альтернативы нет.

Есть. Не юзать эту дрянь, а опакечивать.

t184256 ★★★★★ ()
Последнее исправление: t184256 (всего исправлений: 1)
Ответ на: комментарий от t184256

Ты чем слушаешь? Только если завтра в зависимости твоего проекта добавится одноименный с имеющимся модуль X.

Ну, то есть вместо вменяемых пространств имён, как в нормальных языках, мы имеем срань.

Есть. Не юзать эту дрянь, а опакечивать.

Опакечивать во что? Deb? RPM? Nix? Ебилды писать? А для венды и макоси что? И что делать с тем фактом, что у разных языков разные модели распространения зависимостей, и где-то есть статическая линковка, а где-то нужно всё таскать с собой?

К слову, зачем опакечивать, например, зависимости в Haskell или Rust, если наружу выйдет всё равно один единственный бинарник? Какой от этого смысл?

hateyoufeel ★★★★★ ()
Последнее исправление: hateyoufeel (всего исправлений: 2)
Ответ на: комментарий от hateyoufeel

Ну, то есть вместо вменяемых пространств имён, как в нормальных языках, мы имеем срань.

Нет совершенных языков. Но орать про «баг в питоне», не дочитав туториал, тебе это не позволяет.

Опакечивать во что? … Nix?

Именно.

А для венды

Портировать Nix

макоси

Ni-ix.

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

Засунуть поглубже и не мешать Nix’у. Проблема не в модели, а в долбанутых инструментах типа cargo.

К слову, зачем опакечивать, например, зависимости в Haskell или Rust, если наружу выйдет всё равно один единственный бинарник?

Для сборки, етить.

t184256 ★★★★★ ()
Ответ на: комментарий от t184256

Но орать про «баг в питоне», не дочитав туториал, тебе это не позволяет.

Никто ничего не орал. Я вежливо спросил, анонимус выше мне всё пояснил. Уйми свою анальную боль, говорю же.

Засунуть поглубже и не мешать Nix’у

Да у тебя же Nix головного мозга!

hateyoufeel ★★★★★ ()
Ответ на: комментарий от Shadow

Даже в сишечке есть #include «smth.h» из текущей директории.

Совсем дурак что-ли? Сишечка не подтягивает «smth.h» из, блядь, РАБОЧЕЙ директории, при запуске скомпилированой программы.

anonymous ()
Ответ на: комментарий от hateyoufeel

Придуриваюсь.
Но глобально - это в обоих случаях метод расширения языка.
От того, что в Цэ для работы с сокетами я подключу библиотеку, а в питоне - модуль, работа моя как кодера сильно отличаться не будет. Но да, под капотом питона встречаетсч неприятное.

Shadow ★★★★★ ()
Ответ на: комментарий от hateyoufeel

Я ненастоящий сварщик, но если автор программы на C захардкодил относительный путь к .so, — разве программа не рухнет с сегфолтом?

Я про это же. А тут какая-нибудь библиотека просунет тебе '.' в sys.path и привет.

Ну, а какая-нибудь другая кривулина пропихнёт LD_PRELOAD в окружение. Или ещё что-нибудь.

beresk_let ★★★★ ()
Последнее исправление: beresk_let (всего исправлений: 1)
Ответ на: комментарий от beresk_let

Я ненастоящий сварщик, но если автор программы на C захардкодил относительный путь к .so, — разве программа не рухнет с сегфолтом?

Нет, не рухнет.

Ну, а какая-нибудь другая кривулина пропихнёт LD_PRELOAD в окружение. Или ещё что-нибудь.

А ещё можно себе яйца дверью прищемить.

hateyoufeel ★★★★★ ()