<?xml version="1.0" encoding="UTF-8" ?>

<bugzilla version="5.2"
          urlbase="https://bugzilla.altlinux.org/"
          
          maintainer="jenya@basealt.ru"
>

    <bug>
          <bug_id>43521</bug_id>
          
          <creation_ts>2022-08-13 15:29:16 +0300</creation_ts>
          <short_desc>Изменения в релизе 4.5.0-alt2 ломают сборку (тесты) zope.server</short_desc>
          <delta_ts>2022-08-17 16:10:32 +0300</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>4</classification_id>
          <classification>Development</classification>
          <product>Sisyphus</product>
          <component>python3-module-zope.contenttype</component>
          <version>unstable</version>
          <rep_platform>x86_64</rep_platform>
          <op_sys>Linux</op_sys>
          <bug_status>CLOSED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P5</priority>
          <bug_severity>normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Николай Костригин">nickel</reporter>
          <assigned_to name="root@altlinux.org">root</assigned_to>
          <cc>grenka</cc>
    
    <cc>root</cc>
    
    <cc>slev</cc>
          
          <qa_contact>qa-sisyphus</qa_contact>

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>213674</commentid>
    <comment_count>0</comment_count>
    <who name="Николай Костригин">nickel</who>
    <bug_when>2022-08-13 15:29:16 +0300</bug_when>
    <thetext>Test-module import failures:

Module: zope.server.http.tests.test_wsgiserver

Traceback (most recent call last):
  File &quot;/usr/src/RPM/BUILD/python3-module-zope.server-4.0.2/.tox/py310/lib/python3/site-packages/zope/server/http/tests/test_wsgiserver.py&quot;, line 33, in &lt;module&gt;
    from zope.publisher.http import IHTTPRequest
  File &quot;/usr/lib64/python3/site-packages/zope/publisher/http.py&quot;, line 39, in &lt;module&gt;
    import zope.contenttype.parse
ModuleNotFoundError: No module named &apos;zope.contenttype&apos;


Откат к релизу alt1 делает возможность импорта соответствующего модуля возможной.
Насколько я помню, виной всему перевод пакетов из архитектурозависимых в noarch.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>213675</commentid>
    <comment_count>1</comment_count>
    <who name="Николай Костригин">nickel</who>
    <bug_when>2022-08-13 15:43:21 +0300</bug_when>
    <thetext>Простите за тавтологию в предыдущем комментарии...

По существу: заодно упомянутые изменения ломают тесты с такими же симптомами в


1. python3-module-zope.i18n

[...]
----------------------------------------------------------------------
File &quot;/usr/src/RPM/BUILD/python3-module-zope.i18n-4.8.0/src/zope/i18n/testing.py&quot;, line 48, in zope.i18n.testing.PlacelessSetup.setUp
Failed example:
    from zope.publisher.browser import TestRequest
Exception raised:
    Traceback (most recent call last):
      File &quot;/usr/lib64/python3.10/doctest.py&quot;, line 1350, in __run
        exec(compile(example.source, filename, &quot;single&quot;,
      File &quot;&lt;doctest zope.i18n.testing.PlacelessSetup.setUp[1]&gt;&quot;, line 1, in &lt;module&gt;
        from zope.publisher.browser import TestRequest
      File &quot;/usr/lib64/python3/site-packages/zope/publisher/browser.py&quot;, line 42, in &lt;module&gt;
        from zope.publisher.http import HTTPRequest
      File &quot;/usr/lib64/python3/site-packages/zope/publisher/http.py&quot;, line 39, in &lt;module&gt;
        import zope.contenttype.parse
    ModuleNotFoundError: No module named &apos;zope.contenttype&apos;
[...]

2. python3-module-zope.publisher

[...]
----------------------------------------------------------------------
File &quot;/usr/src/RPM/BUILD/python3-module-zope.publisher-6.0.1/src/zope/publisher/tests/../paste.txt&quot;, line 49, in paste.txt
Failed example:
    app_factory = pkg_resources.load_entry_point(
        &apos;zope.publisher&apos;, &apos;paste.app_factory&apos;, &apos;main&apos;)
Exception raised:
    Traceback (most recent call last):
      File &quot;/usr/lib64/python3.10/doctest.py&quot;, line 1350, in __run
        exec(compile(example.source, filename, &quot;single&quot;,
      File &quot;&lt;doctest paste.txt[2]&gt;&quot;, line 1, in &lt;module&gt;
        app_factory = pkg_resources.load_entry_point(
      File &quot;/usr/lib64/python3/site-packages/pkg_resources/__init__.py&quot;, line 486, in load_entry_point
        return get_distribution(dist).load_entry_point(group, name)
      File &quot;/usr/lib64/python3/site-packages/pkg_resources/__init__.py&quot;, line 2867, in load_entry_point
        return ep.load()
      File &quot;/usr/lib64/python3/site-packages/pkg_resources/__init__.py&quot;, line 2471, in load
        return self.resolve()
      File &quot;/usr/lib64/python3/site-packages/pkg_resources/__init__.py&quot;, line 2477, in resolve
        module = __import__(self.module_name, fromlist=[&apos;__name__&apos;], level=0)
      File &quot;/usr/src/RPM/BUILD/python3-module-zope.publisher-6.0.1/src/zope/publisher/paste.py&quot;, line 16, in &lt;module&gt;
        import zope.publisher.browser
      File &quot;/usr/src/RPM/BUILD/python3-module-zope.publisher-6.0.1/src/zope/publisher/browser.py&quot;, line 42, in &lt;module&gt;
        from zope.publisher.http import HTTPRequest
      File &quot;/usr/src/RPM/BUILD/python3-module-zope.publisher-6.0.1/src/zope/publisher/http.py&quot;, line 39, in &lt;module&gt;
        import zope.contenttype.parse
    ModuleNotFoundError: No module named &apos;zope.contenttype&apos;
[...]

Если нет веских причин сохранять внесенные изменения, я предлагаю автору их откатить.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>213676</commentid>
    <comment_count>2</comment_count>
    <who name="Grigory Ustinov">grenka</who>
    <bug_when>2022-08-13 15:46:01 +0300</bug_when>
    <thetext>Да, я прекрасно помню, что я это сломал. Надо разобраться в том, что же там такого архитектурозависимого. Ну то есть у нас много пакетов, которые собираются таким образом ошибочно, некоторые исправились хорошо, а вот этот сломал 3 пакета, если я не ошибаюсь. Исправлю в ближайшее время, а потом подумаю.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>213679</commentid>
    <comment_count>3</comment_count>
    <who name="Ivan Zakharyaschev">imz</who>
    <bug_when>2022-08-14 13:53:15 +0300</bug_when>
    <thetext>(In reply to Николай Костригин from comment #0)

&gt;   File &quot;/usr/lib64/python3/site-packages/zope/publisher/http.py&quot;, line 39,
&gt; in &lt;module&gt;
&gt;     import zope.contenttype.parse
&gt; ModuleNotFoundError: No module named &apos;zope.contenttype&apos;
&gt; 
&gt; 
&gt; Откат к релизу alt1 делает возможность импорта соответствующего модуля
&gt; возможной.
&gt; Насколько я помню, виной всему перевод пакетов из архитектурозависимых в
&gt; noarch.

Насколько я помню, это объясняется как-то так, что zope оформлен как модуль со своим __init__.py :

/ALT/Sisyphus/x86_64/base/contents_index:/usr/lib64/python3/site-packages/zope/__init__.py      python3-module-zope

поэтому при import zope.contenttype.parse сначала ищется и находится этот модуль и загружается, и всё остальное может быть найдено только внутри него.

В современном питоне, начиная с 3.x что-то, есть возможность, если я правильно помню, оформлять более настоящие namespaces, без __init__.py -- тогда поиск вложенных в namespace модулей должен быть по всем подходящим путям.

Можно пофантазировать о каком-то автоматическом способе избежать таких ошибок с помощью зависимостей, но это как-то не так просто придумать, потому что в современном питоне есть два варианта, когда это будет работать, насолько я понимаю: требуется файл __init__.py на уровне выше /usr/lib/python3/site-packages/zope/__init__.py , или его отсутствие по всем путям, т.е. нет ни одного из: /usr/lib64/python3/site-packages/zope/__init__.py , /usr/lib/python3/site-packages/zope/__init__.py  и прочих.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>213680</commentid>
    <comment_count>4</comment_count>
    <who name="Ivan Zakharyaschev">imz</who>
    <bug_when>2022-08-14 14:06:36 +0300</bug_when>
    <thetext>(In reply to Ivan Zakharyaschev from comment #3)

&gt; В современном питоне, начиная с 3.x что-то, есть возможность, если я
&gt; правильно помню, оформлять более настоящие namespaces, без __init__.py --
&gt; тогда поиск вложенных в namespace модулей должен быть по всем подходящим
&gt; путям.
&gt; 
&gt; Можно пофантазировать о каком-то автоматическом способе избежать таких
&gt; ошибок с помощью зависимостей, но это как-то не так просто придумать, потому
&gt; что в современном питоне есть два варианта, когда это будет работать,
&gt; насолько я понимаю: требуется файл __init__.py на уровне выше
&gt; /usr/lib/python3/site-packages/zope/__init__.py , или его отсутствие по всем
&gt; путям, т.е. нет ни одного из:
&gt; /usr/lib64/python3/site-packages/zope/__init__.py ,
&gt; /usr/lib/python3/site-packages/zope/__init__.py  и прочих.

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

В случае с zope.contenttype почему-то, правда, я такого эффекта не наблюдаю. Они на месте:

$ rpm -qp /ALT/Sisyphus/noarch/RPMS.classic/python3-module-zope.contenttype-4.5.0-alt2.noarch.rpm --provides
python3(zope.contenttype)
python3(zope.contenttype.__main__)
python3(zope.contenttype.parse)
python3-module-zope.contenttype = 4.5.0-alt2:sisyphus+301404.100.1.1

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

Skipping installation of /usr/src/tmp/python3-module-zope.contenttype-buildroot/usr/lib/python3/site-packages/zope/__init__.py (namespace package)</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>213681</commentid>
    <comment_count>5</comment_count>
    <who name="Ivan Zakharyaschev">imz</who>
    <bug_when>2022-08-14 14:11:25 +0300</bug_when>
    <thetext>(In reply to Ivan Zakharyaschev from comment #3)

&gt; Можно пофантазировать о каком-то автоматическом способе избежать таких
&gt; ошибок с помощью зависимостей, но это как-то не так просто придумать, потому
&gt; что в современном питоне есть два варианта, когда это будет работать,
&gt; насолько я понимаю: требуется файл __init__.py на уровне выше
&gt; /usr/lib/python3/site-packages/zope/__init__.py

и его отсутствие по всем остальным таким путям.

&gt; , или его отсутствие по всем
&gt; путям, т.е. нет ни одного из:
&gt; /usr/lib64/python3/site-packages/zope/__init__.py ,
&gt; /usr/lib/python3/site-packages/zope/__init__.py  и прочих.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>213798</commentid>
    <comment_count>6</comment_count>
    <who name="Repository Robot">repository-robot</who>
    <bug_when>2022-08-17 15:12:35 +0300</bug_when>
    <thetext>python3-module-zope.contenttype-4.5.0-alt3 -&gt; sisyphus:

 Wed Aug 17 2022 Grigory Ustinov &lt;grenka@altlinux&gt; 4.5.0-alt3
 - Make package arch dependent back (Closes: #43521).</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>213803</commentid>
    <comment_count>7</comment_count>
    <who name="Stanislav Levin">slev</who>
    <bug_when>2022-08-17 16:10:32 +0300</bug_when>
    <thetext>TL;DR
Все файловые руты namespaсe package должны быть в python3-module-zope
(и архитектурно-зависимые, и архитектурно-независимые).

Сама идея namespace пакета подразумевает возможность разнесения частей одного пакета по различным файловым иерархиям (хотя это может быть и не только файловая система) с возможными *вложенными* namespace пакетами:
https://docs.python.org/3/reference/import.html#namespace-packages

zope - это namespace package, у которого есть как архитектурно-зависимые подпакеты, так и архитектурно-независимые. Upstream zope выбрал pkg_resources-style для namespace packages:
https://packaging.python.org/en/latest/guides/packaging-namespace-packages/#creating-a-namespace-package

Это буквально означает, что *каждый* возможный устанавливаемый рут для подпакета *должен* иметь __init__.py cо следующим содержимым:
&gt; __import__(&apos;pkg_resources&apos;).declare_namespace(__name__)

В текущей схеме пакетирования zope в ALT distro количество возможных рутов ограничено одним. Реализовано это как принудительное заархитектуривание *всех* подпакетов zope, то есть все такие подпакеты *должны* устанавливаться в /usr/lib64/python3/site-packages/zope/ (для x86_64). В противном случае, импорт таких подпакетов может не работать (зависит от многих факторов).

Например, разберем проблему сборки данного пакета (zope.server).

На файловой системе лежат:
[user@host dir]# ls -1 /usr/lib{,64}/python3/site-packages/zope/
/usr/lib/python3/site-packages/zope/:
__pycache__
contenttype

/usr/lib64/python3/site-packages/zope/:
__init__.py
__pycache__
browser
component
configuration
deferredimport
deprecation
event
exceptions
hookable
i18n
i18nmessageid
interface
location
proxy
publisher
schema
security
testing
testrunner

Что происходит при импорте zope:
[root@localhost .in]# echo -e &quot;import sys\nfor f in sys.meta_path:\n    spec = f.find_spec(&apos;zope&apos;, path=None)\n    if spec is not None:\n        print(f, spec.submodule_search_locations)\n        break&quot; | python3 -
&lt;class &apos;_frozen_importlib_external.PathFinder&apos;&gt; [&apos;/usr/lib64/python3/site-packages/zope&apos;]

то есть path-based finder (https://docs.python.org/3/reference/import.html#the-path-based-finder) находит нам спек для zope.

При этом и path entry finder для архитектурно-зависимых sitepackages, и path entry finder для архитектурно-независимых sitepackages могут найти спек для zope:
[root@localhost .in]# python3 -c &apos;import sys, zope; print(sys.path_importer_cache[&quot;/usr/lib/python3/site-packages&quot;].find_spec(&quot;zope&quot;)); print(sys.path_importer_cache[&quot;/usr/lib64/python3/site-packages&quot;].find_spec(&quot;zope&quot;))&apos;
ModuleSpec(name=&apos;zope&apos;, loader=None, submodule_search_locations=[&apos;/usr/lib/python3/site-packages/zope&apos;])
ModuleSpec(name=&apos;zope&apos;, loader=&lt;_frozen_importlib_external.SourceFileLoader object at 0x7f70b478ab60&gt;, origin=&apos;/usr/lib64/python3/site-packages/zope/__init__.py&apos;, submodule_search_locations=[&apos;/usr/lib64/python3/site-packages/zope&apos;])

Но так как согласно https://peps.python.org/pep-0420/#specification
&gt; During import processing, the import machinery will continue to iterate over each directory in the parent path as it does in Python 3.2. While looking for a module or package named “foo”, for each directory in the parent path:
&gt; If &lt;directory&gt;/foo/__init__.py is found, a regular package is imported and returned.
&gt; If not, but &lt;directory&gt;/foo.{py,pyc,so,pyd} is found, a module is imported and returned. The exact list of extension varies by platform and whether the -O flag is specified. The list here is representative.
&gt; If not, but &lt;directory&gt;/foo is found and is a directory, it is recorded and the scan continues with the next directory in the parent path.
&gt; Otherwise the scan continues with the next directory in the parent path.
&gt; If the scan completes without returning a module or package, and at least one directory was recorded, then a namespace package is created.

(детали тут: importlib/_bootstrap_external.py::FileFinder::find_spec)
native namespace package (&quot;/usr/lib/python3/site-packages/zope&quot;) и все его содержимое игнорируется.

С точки зрения Python zope - это регулярный пакет (наличие zope/__init__.py), но инициализация этого пакета создает имитацию namespace пакета с помощью pkg_resources. pkg_resources.declare_namespace из /usr/lib64/python3/site-packages/zope/__init__.py, о котором говорилось ранее, патчит __path__ пакета zope:
https://github.com/pypa/setuptools/blob/d03da04e024ad4289342077eef6de40013630a44/pkg_resources/__init__.py#L2289

[user@host dir]# python3 -c &quot;import zope, sys; print(sys.modules[&apos;zope&apos;].__path__)&quot;
[&apos;/usr/lib64/python3/site-packages/zope&apos;]

Поэтому, если эта *обязательная* инициализация отсутствует во всех возможных рутах namespace пакета zope, то импорты могу не работать. Какие варианты пакетирования:
- упаковать два рута, перевести все на native namespacе, удалив zope.__init__.py, и следить, чтобы никто и никогда не упаковал zope/__init__.py.
- упаковать два рута, использовать схему upstream c pkg_resources, сделав зависимость обязательной</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>