Часто задаваемые вопросы по PythonPolicy

   2004-06-29 03:36:53

Это FAQ составлено по опыту внедрения python-policy в дистрибутивах Alt Linux (Сизифус переведен на ее использования с середины мая 2004 года). Последняя версия FAQ лежит в /usr/share/doc/rpm-build-python и лучше пользоватся ей,эта версия опубликована лишь для удобства.

Q1: Где можно взять текст данной Policy?

A1: В каталоге /usr/share/doc/rpm-build-python хранится последняя актуальная версия полиси. На сайте www.neural.ru публикуется полиси, но это неофициальная версия и она может быть как более новой, так и более старой.

Q2: Как внести изменения в Policy?

A2: Отослать их мне, на python@neural.ru. Я их с вами обсужу. Необходимое условие продуктивности обсуждения - вы подписаны на devel@altlinux.ru. Все остальные просьбы прочитываются и принимаются к сведенью;

Q3: Кто автор Policy и почему? Какова история ее возникновения?

A3: Автор - комьюнити. Идея полиси возникла летом 2003-го года (cray, doc, ldv и др), когда некоторые основные идеи были согласованы, но в дальнейшем не развивалась - все что-то тихо клепали, но особого взаимного интереса не проявляли. Существенный вклад сделал Алексей Морозов, заставивший меня начать шевелится и Алексей Любимов, заставивший меня увидеть некоторую проблему.

Поддерживаю полиси я, Андрей Орлов, мантейнер пакета python & Zope. Я же обладаю (наверно) каким-то решающим голосом. Почему я? Потому что логично поручить это мантейнеру python. Будет другой мантейнер python - видимо, он же будет рулить и полиси. Почему решающим? Потому что должен же кто-то выбрать из двух стогов сена один ;), а я достаточно туп и ленив, чбы :

a) Не делать лишних шагов;

b) Не вдаватся в многочисленный тонкости: лучше удовлетворительное решение сегодня, чем замечательное - через год (тем более, что через год оно так и так будет);

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

Q4: Я считаю что макрос такой-то и сякой-то, используемый при сборке "стандартного" модуля неудачный. К кому мне обратится?

A4: К Алексею Морозову. Он кашу с макросами заварил - ему и расхлебывать. Я рад, что нашелся человек, который это сделал, и заглянув в эти макросы, я подумал - что он знает, что делает. Мне про макросы лучше не писать, результат может быть неадекватный (разве что в рамках п.QA2).

Q5: Почему бы не сделать тоже самое на основе Distutils ?

A5: Основная идея Distutils - собрать по некоторому универсальному конфигурационному файлу информацию об использумемой операционной системе и (в случае rpm) сгенерировать под нее спецификацию. Спецификация генерируется по некоторому "умозрительнному" темплейту. Пакет rpm-build-python добавляет в инсталляцию Distutils команду bdist_altrpm, выполняющую генерацию спецификации, соответствующей данной полиси, но ее лучше пока рассматривать как бета-версию (правда, я-то ей пользуюсь). К сожалению, использование Distutils не предполагает удобного способа поддержки пакета в рамках репозитория, так как нет технологичного способа сливать изменения, сделанные в setup.py разработчиками пакета и изменения, внесенные в него (и особенно - сгенерированную спецификацию) мантейнерами.

Q9: Почему питонов много, а python-doc - один.

A9: Черт его знает. До недавнего обращения мантейнера python-doc с просьбой забрать пакет я об этом не задумывался, и на самом деле было даже два python-doc - второй в рамках python23 и под названием python23-info. Наверно, держать доки под каждый python все-таки неразумно и python23-info откочует в python-doc.

Q10: Одно время говорили о разрезании пакетов на подпакеты с модулями py, pyo, pyc, что в этом направлении делается и на что это будет похоже? И, кстати, когда это начнется?

A10: Эксперименты ведутся уже сейчас, но это с собой несет столько подводных камней, что не является частью настоящего перехода к новой схеме питоновских модулей. Тем не менее некоторые вопросы могут быть отвечены уже сейчас (пожалуста, обратите внимание, это мое личное мнение и оно не имеет на сегодняшний день никакого отношения к полиси):

  1. Всегда будет возможность установить файлы py, pyc и pyo, так как все они имеют свою, очень важную, область применимости.

Замечание про файлы pyc & pyo:

  • Установка только файлов py, pyc - при старте питон с ключом -O (работа с оптимизированными файлами байткода) будет приводить к перекомплиции, что непохоже на оптимальную работу;
  • Установка только файлов py (выборочная), pyo - при старте без ключа -O имеющиеся в наличии файлы pyo будут игнорироваться, поэтому потребуется установко py для всех модулей, хотя имеет смысл только выборочная установка в целях отладки, в тоже время, при старте с ключом -O нормальная отладка невозможна;
  • Установка только pyc - работа с ключом -O (оптимизированная) невозможна;
  • Установка только py - перекомпиляция при каждом старте и серъезный объем на диске;

Чбы еще более напугать желающих неподумавши выбросить файлы pyc, добавлю: Zope, в норме, стартует два раза: рестарт делается при отсутствии отладочного режима с ключом -O.

И, наконец, если кто не знает: "а еще их можно зиповать", фича новая (python23), непроверенная, но для серверов приложений, типа Zope, которые однажды стартуют и месяц работают, довольно перспективная. В некоторых вариантах использования (Live CD например), просто незаменимая.

  1. Файлы py, pyc, pyo при полной установке, кладутся точно в то место, куда бы они легли при обычной установке, никакого специального выделения файлов py (в каталог /usr/share/doc, /usr/src, еще куда-либо) не будет: это создаст проблемы.
  2. Видимо, пакеты будут разрезаны на python- & python--src, при этом python- содержит файлы pyo и (или) pyc, а ...-src - файлы py.
  3. Что касается включение файлов pyc или pyo, то возможны три варианта:
    • Включение обеих (сейчас этот вариант представляется - единстенным возможным);
    • Включение на стадии сборки одного из типов файлов (требует спеиальных макросов, что Алексей обещает сделать, или ручной работы, также требует патчить питон);
    • Включение политики установки по аналогии с %_install_langs (я стою за этот вариант, так как у потребителя остается выбор, который он может сделать в зависимости от своих потребностей, но это требует патчить не только python, но и rpm;
  4. Зависимости ставятся только на основной пакет т.е. python-, пакет с исходными текстами используется только разработчиками или теми, кому нужна "грязная" настройка (ставим -src, редактируем один из файлов, все остальное сносим, один файл оставляем, кажется это можно автоматизировать, но я не пробовал);
  5. Никогда не удаляются *py c головными модулями.

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

Q11: Когда будет python24 и где его взять?

A11: До выхода релиза - только в дедале. Сейчас его там нет ;), но по завершении возни с переходом на новую схему сборки я его соберу.

Q12: Когда появится Zope27?

A12: Offtopic! offtopic! На самом деле, я не знаю чем 27 лучше чем 264. Хотя, конечно, какие-то отличия есть. Именно из-за них мягкий переход на 27 невозможен (придется кой-че переписать в обвязке), но к концу апреля можно ждать сборку в дедале. Мы держим сервер разработки синхронный с сизифом, так что внезапное обрушение коммерческих проектов компании Freehand, которая любезно финансирует поддержку python & Zope мной, крайне нежелательно, поэтому появление Z27 в сизифе возможно только после того, как я буду убежден, что он реально работает. До сих пор (на примере 2.3.0, 2.4.0, 2.5.0, 2.6.0, и мбть даже 2.1.0 & 2.2.0 (но это было очень давно и я уже не помню)) ни одна версия с нулевым минором не работала корректно. На возможные возражения отвечу: сложность Zope такова, что WEB-разработчик, не знающий коды Zope досконально, обнаружить некорректность может только чудом. Тем более, что редкий WEB-разработчик использует возможности собственно Zope хотя бы на 5%.

Q13: Как собирать пакеты под Zope?

A13: Пакеты под Zope - это пакеты под Zope. К пакетам под python имеют довольно отдаленное отношение. Главный сборщик пакетов под Zope, сейчас, Генадий Ковалев, мантейнер Plone, наверно его опыт будет вам более полезен чем мой, тем более, что то что мы с ним делаем мы между собой согласовали.

Q14: Если апгрейд модуля/приложения требует python = 2.3, почему бы не иметь в дистрибутиве python23, который благополучно вытянется, если он такое предоставляет?

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

A14:Текущая схема с несколькими семействами пакетов обладает рядом недостатков, основной из которых - невозможность "прозрачного" для потребителя перехода с одной версии питона на другую: гипотетический потребитель вынужден составить список всех пакетов одной версии, аккуратно их снести и поставить вместо них пакеты другой версии, причем зависимость на python = 2.3 помогает в этом очень слабо : в лучшем случае образуется разрозненная установка смеси двух питонов, которая не особенно работоспособна, в худшем - ручной апгрейд.

Ситуация усугубляется тем, что мы разрезали python на мелкие подпакеты.

В тоже время, при новой схеме семейств пакетов, всегда есть только один основной пакет - python--X.Y - и при появлении python--X.Y+1 (плюс - знак арифиметической операции, а не элемент названия) его апгрейд будет выполнен в обычном порядке. Подробнее об этом можно прочитать в notes/Names.txt.

Да, и по поводу велосипедов: я считаю, что наш велосипед лучше, поэтому стоит.

Q15: > The following packages have unmet dependencies: > solfege: Depends: python2.3(gnome) but it is not installable > Depends: python2.3(gobject) but it is not installable > Depends: python2.3(gtk) but it is not installable > Depends: python2.3(mpd) but it is not installable > Depends: python2.3(pango) but it is not installable > Depends: python2.3(soundcard) but it is not installable > Depends: python2.3(src) but it is not installable

A15:

Надо разбиратся с конкретными пакетами, которые провайдят эти дела и разбираться почему они не встают. Типовой вариант один: автоматический поиск зависимостей нашел такие зависимости, которые не могут быть удовлетворены в принципе - напремер, на модули для MAC-оса.

Методы борьбы зависят от причин возникновения:

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

Решение: прибить такие файлы

  1. Зависимости порождаются тестовыми модулями.

    Решение: вынести тестовые модули в отдельный подпакет (python-module-SOMETHAT-test) и поставить на нем AutoReqProv: nopython. Еще вариант - стереть.

  2. Зависимости порождаются условными конструкциями:

    Пример такой конструкции:

    if EXPR : import MACOSMODULE

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

%add_python_req_skip <ИМЯ_МОДУЛЯ>

  1. Наверно, в поиске зависимостей и провайдес есть ошибки.

    В этом случае нужно удалять зависимости или проставлять провайдес вручную:

    %add_python_req_skip <ИМЯ_МОДУЛЯ>

    Provide: python%__python_version( <ИМЯ_МОДУЛЯ> )

После этого подвесте баг на пакет rpm-build-python с указанием пакета и проблемной зависимости.

  1. Можно попробовать "собирать как раньше".

    Это плохой, неправильный, противоречащий полиси, но очень быстрый способ решить проблему "временно": отключить поиск зависимостей:

    AutoReqProv: yes, nopython

    Requires: python-strict

По зависимости python-strict вытянется "стандартная установка python", а поиск зависимостей будет отключен. Помните, что в этом случае предполагается что все необходимые зависимости вы проставите сами (скорее всего, они у вас уже стоят, только на сами пакеты, а не на автоматически найденные Provides, только обратите внимание еще и на то, что для подавляющегео большинства пакетов-модулей изменилось имя (например MySQL-python -> python-module-MySQLdb))).

Иными словами, вы возвращаетесь к ситуации, которая была до введения полиси. Разумеется, т.о., ваш пакет будет ее нарушать, но это даст вам время решить проблемы одним из более правильных способов, изложенных выше. Я должен подчеркнуть, что пакеты с зависимостью на python-strict - временное решение и в будущем обязательно должны быть пофиксены.

Q16: Если установлено только python-base-2.3.3-alt9 и python-relaxed-2.3.3.alt9, python.prov.py не работает: rpm-build-python должен требовать python2.3(__future__);

A16: Это был текст ошибки, которая уже исправлена.

Тем не менее, исправлена она совсем не так, как предлагалось, поэтому требуется данное разъяснение.

  1. Я не могу вставить в rpm-build-python требование любой конкретной версии python - а Require: python2.3(__future__) это именно такое требование. Не могу, потому что сборка может идти с любым питоном.
  2. Я не хочу вставлять в rpm-build-python требование установки python вообще - т.к. такое требование приведет к обязательной установке питона в рамках сброчно среды ни в чем ни повинным людям. Их отношение к этому я предвижу, по аналогии с тем, что лично меня раздражет необходимость регулярного обновление перла для сборочной среды, который мне на хрен не нужен - я не нем не пишу так давно, что даже его забыл.

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

Я ввожу в полиси два постулата:

  1. Сборка любого питон-пакета должна проводится в средде, содержащей python-devel;
  2. В отсутствие каких-либо компонент python, необходимых для работы, скрипты из пакета rpm-build-python завершаются коррекно, но ничего не делают.

Собственно исправление ошибки свелось к обеспечению выполнения условия-2. Я это проверил, на паре пакетов - они действительно раньше падали при сборке, тогда как теперь не падают.

Тем, кому интересны технические детали - все необходимые зависимости вынесены из модули rpm-build-python в модуль python-devel или python-base (который требует python-devel), тогда как в скрипты rpm-build-python добавлены обработчики аварийных ситуаций, завершающие скрипты с кодом SUCCESS.

Q17: Почему бы не убрать умолчание на опцию python в AutoReqProv? Пусть там стоит nopython, все пакеты собираются как раньше и работают, а особо продвинутые пользователи ставят опцию python и разбираются с зависимостями? Тогда все старые пакеты работа ли бы, а новые - собирали бы уже правильно и переход не был бы так болезнен?

A17: Самое неприятное - это не поможет. До перехода на новую python-policy, поиска зависимостей не было, и все зависимости на __пакеты__ были проставлены вручную. Например, зависимость на пакет python. Но, пакет python сильно изменился - в частности, был разрезан на куски. И поэтому больше не провайдит того, что провайдил тогда. Т.о. стали возможны два варианта:

  1. Обязательный автоматический поиск зависимостей, который либо находит все нужные зависимости, либо дает ошибку. В результате мы получаем либо багрепорт, либо работающий пакет.
  2. Просьба к мантейнерам пересобрать и протестировать пакеты. Мало того, что такая просьба может быть проигнорирована, в силу отсутствия мантейнера, так еще и сама работа тяжелая и может приводить к ошибкам, в результате чего мы получаем репозиторий, полный пакетов с неизвестной работоспособностью.

Существует, правда, упрощенное решение в поиске зависимостей - поставить зависимость на python-strict. Это более-менее гарантирует работоспособность, но не дает полной гарантии;

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

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

Q18: Почему в перле не возникает таких проблем?

A18: Не знаю. Осмелюсь предположить, что просто с перлом нет ситуации переходного переиода, и когда переходный период закончится - у нас тоже не будут возникать проблемы. Во всяком случае, в рассылке иногда проскакивают репорты для perl, с проблемами, сходным с нашими. Но они идут не так густо и относятся, преимущественно, к вновь добавляемым модулям.

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

Q19: Почему мы ставим зависимостть на python-devel = 2.3, а не на python-devel ?

A19: Мы ставим зависимость на python-devel = 2.3, т.е. с указанием мажорной и минорной версии, т.к. это принятая в альтлинуксе практика в течении по крайней мере последних полутора лет - это не я придумал.

В то же время, отказ от явного указания версии, из-за ряда проблем с apt или каких-то иных причин, приводит к тому, что пакет либо не пересобирается вообще, либо, что значительно хуже, пересобирается с альтернативным питоном (например, при наличии в репозитории, используемом сборочной средой двух и более сборок одного питона, такая ситуация, как показывает практика, типовая после размещения новой сборки). Такой пакет пересобранный с альтернативным питоном оказывается полностью работоспособен, но не полностю функционален (например, вместо зависимости python2.3(some) провайдит python2.2(some), которая конечно работает - но на хрен никому не нужна), в результате возникают unmets и неработоспособность десятков других пакетов, что вызывает понятные нарекания.

Возможный выигрыш от того, что без указания такой зависимости сборка всегда будет происходит с последним имеющимся питоном, на самом деле, оборачивается проигрышем: известна масса случаев, когда при пересборке со сменой минора пакет терял работоспособность из-за изменения в синтаксисе python. Наглядные примеры - None, которая став встроенным объектом в 2.3 (утеряна возможность присваивания), полностью разрушила работу Zope и ряда других пакетов, введение обязательости указания кодировки. Про кошмар с изменением API модулей я просто промолчу. Я понимаю, что не надо так писать, но и вы поймите - так пишут. И не всегда дело мантейнера исправлять такие ляпы в программировании.

Таким образом, только мантейнер может решить что пересборка пакета с новым питоном необходима и возможна, и только мантейнер может выполнить необходимые проверки. Никакой автоматизации здесь быть не может, если мы хотим иметь работоспособные пакеты.

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

Q20: Почему нет пакета python-devel, но python-devel провайдится пакетом с дурацким названием python-dev? Почему нужно ставить зависимость именно на python-devel, а не на python-dev?

A20: Точнее, на python-devel = 2.3. Если бы мы создали пакет python-devel, то он бы имел Provides: python-devel = 2.3 и python-devel = 2.3.4. Хотя rpm нормально отрабатывает такую ситуацию, с ней не справиляется apt и по Requires: python-devel = 2.3 не находит ничего. Поэтому python-devel пришлось сделать виртуальным пакетом, а сам пакет переименовать во что-то другое. Если вам не нравится название python-dev - предложите свое. Я честно говоря в тот момент просто устал разруливать недокументированные траблы apt и на выдумывание названия сил уже не было. Наверно, python-build был бы лучше.

(Я сейчас уже не очень точно помню, но кажется проблема была именно с apt, а не с rpm, впрочем, не так важно с кем).

Собственно, на python-dev зависимость поставить нельзя по той же причине: это не сработает, так как python-dev = 2.3 не провайдится, а ставить зависимость на python-dev = 2.3.4 не имеет смысла - необправдано сильное требование.

Q21: У меня есть пакет, в котором поиск зависимостей находит модуль karamba (kiki, etc), но я не знаю где его взять! Такого модуля нет, но все работает!

A21: Есть, но вы его не видите. Дело в том, что в данном случае вы имеете дело не с самим питоном, а с ембеддед питоном, который может отличатся от обычного питона, в частности, дополнительными builtin - модулями (см. Q22).

Есть единственный правильный способ борьбы с этим - скипнуть эту зависимость, указав::

%add_python_req_skip <имя модуля>,

например:

            %add_python_req_skip karamba                    

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

Q22: Что такое builtin модули? Почему я его нигде не могу найти?

A22: Builtin - это модуль, встроенный внутрь ембеддед интерпретатора, в виде питоновских скриптов не может быть по определению. Кроме того, ни один скрипт запущенный без именно этого ембеддед интерпретатор никогда и никаких образом не может получить доступ к этому модулю. Единственный способ решить проблему в этом случае - это поставить %add_python_req_skip и поствить явную зависимость на указанный ембеддед интерпретатор. В принципе, это едва ли не единственный случай, когда add_python_req_skip не является костылем, а есть единственно верное решение.

Если вы собираете пакет с embedded питоном, то неплохо получить список таких модулей. В этом вам может помочь следующий код (not tested)::

import sys

print sys.builtin_module_names

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

Разумеется, если у данного интерпетатора нет доступного stdout - задача серьезно осложняется.

Q24: Мой пакет содержит примеры и тестовые модули, я не хочу выделять их в отдельный пакет, но поиск зависимостей находит в них зависимости, которые не могут быть удовлетворены, потому что это примеры!

A24: Лучше всего их вынести в отдельный пакет, ибо нафига? Нужно двоим - страдают все. В то же время, решение есть.

Поиск зависимостей просматривает не все файлы, а только те, которые лежат в директории %_findreq_topdir, за исключением директорий, перечисленных в макросе %_findreq_skiplist. Изменить эти макросы можно макросами set_findreq_topdir, set_findreq_skiplist, add_findreq_skiplist, которые описаны в документации на rpm. Ее на самом деле стоит прочитать, до того, как задавать вопросы о python-policy.

Q26: Мой пакет ставит модули в каталог /usr/lib/mypackage, и использует их только сам. Но поиск зависимостей находит в этих модулях зависимости на их же самих, в то время как эти модули не провайдятся (не входят в python-path), и из-за этого возникает unmets. Что делать?

A26: Хорошего решения, на самом деле, нет. В данный момент, общей практикой является указание %add_python_lib_path, в котором перечисляются все такие каталоги. Это не очень хорошее решение, так как модуль может быть недоступен другим приложениям без специальной настройки этого приложения. В принципе, этого надо избегать, хотя это не всегда возможно. Если модулей относительно немного - можно написать длинный add_python_req_skip. Тоже вариант, хотя и не самый простой. Чбы упростить последнюю задачу, можно воспользоваться командой:

            find <ПУТЬ К КАТАЛОГУ> | /usr/lib/rpm/python.req.py | sort | uniq

которая выведит список всех зависимостей, нужных скриптам в указанном каталоге, или командой:

            RPM_PYTHON_LIB_PATH=<СПИСОК ПУТЕЙ К ДОПОЛНИТЕЛЬНЫМ КАТАЛОГАМ С МОДУЛЯМИ>

            (пути в списке разделяются пробелом)

            export RPM_PYTHON_LIB_PATH

            find <ПУТЬ К КАТАЛОГУ> | /usr/lib/rpm/python.prov.py | sort | uniq

которая выведит список зависимостей. Вопрос дальнейшей автоматизации решается.

Q27: Как создать питоновский подпакет внутри другого, не питоновского пакета?

Q28: Я хочу разбить модуль на две подпакета, только одна из которых содержит файл __init__.py, но искалка Provides находит только зависимости из одного пакета (в который входит __init__.py). Что делать?

A28: Нужно воспользоваться макросом python_module_declare , где - путь к каталогу содержащему файл __init__.py :

            python_module_declare /usr/lib/python2.3/email/

Тогда поиск Provides для любого подпакета будет считать, что он обнаружил в каталоге файл __init__.py, а для пакета, в который включена такая декларация автоматически добавится зависимость на модуль, соответствующий пути ;

(в текущей версии макрос python_module_declare может не работать)

Q29: Что такое иерархическая зависимость?

A29: Иерархическая зависимость - это зависимость на модуль, вложенный внутрь другого модуля. Такая зависимтость записывается как :

            "python" <N> "." <M> "(" <NAME> [ "." <NAME> ] * ")"

И порождается синтаксической конструкцией вида :

            "import" " " <NAME> [ "." <NAME> ]*

Имеющий смысл "импортировать модуль NAME (2) из модуля NAME (1)".

Q30: Почему конструкция from import не порождает иерархическую зависимость?

A30: Потому что в этой конструкции не обязательно соответствует модулю - т.е. файлу (каталогу), а может соответствовать любому имени, определенному в модуле MODULE. Для языка Python не существует способа составить полный список таких имен до исполнения программы (хотя бы потому, что их список может изменятся в процессе выполнения программы произвольным образом).