Your message dated Sun, 08 Feb 2026 14:51:37 +0000
with message-id <[email protected]>
and subject line Bug#1120283: fixed in python-debian 1.1.0
has caused the Debian Bug report #1120283,
regarding python-debian: please add deb822.PkgRelation.holds_on_arch and 
holds_with_profiles predicates
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact [email protected]
immediately.)


-- 
1120283: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1120283
Debian Bug Tracking System
Contact [email protected] with problems
--- Begin Message ---
Source: python-debian
Version: 1.0.1
Severity: wishlist
Tags: patch

Hello.

The next concern after deb822.PkgRelation.parse_relations() is
probably to check that the relation holds in a given context.  The
last commit enables callers to do that without depending on the
internal representation of arch and profiles restrictions.

The 6 first commits are suggestions inspired by 'debian/rules qa' and
lintian.
>From 4e7ba5499d0944df734f4f52dea4adeb8025be96 Mon Sep 17 00:00:00 2001
From: Nicolas Boulenguez <[email protected]>
Date: Thu, 6 Nov 2025 21:30:03 +0100
Subject: [PATCH 1/7] style: Remove trailing whitespaces in test_deb822.py

---
 tests/test_deb822.py | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/tests/test_deb822.py b/tests/test_deb822.py
index 6a6e584..97623dd 100755
--- a/tests/test_deb822.py
+++ b/tests/test_deb822.py
@@ -143,7 +143,7 @@ Description: text-based mailreader supporting MIME, GPG, PGP and threading
 Tag: interface::text-mode, made-of::lang:c, mail::imap, mail::pop, mail::user-agent, protocol::imap, protocol::ipv6, protocol::pop, protocol::ssl, role::sw:client, uitoolkit::ncurses, use::editing, works-with::mail
 Task: mail-server
 '''
-        
+
 
 PARSED_PACKAGE = deb822.Deb822Dict([
     ('Package', 'mutt'),
@@ -841,7 +841,7 @@ with open("test_deb822.pickle", "wb") as fh:
                               cls: Type[deb822.Deb822],
                               **kwargs: Any) -> None:
         """Ensure iter_paragraphs consistency"""
-        
+
         with open(filename, 'rb') as fh:
             packages_content = fh.read()
 
@@ -968,7 +968,7 @@ with open("test_deb822.pickle", "wb") as fh:
 
         for k, v in deb822_.items():
             assert dict_[k] == v
-    
+
     def test_case_insensitive(self) -> None:
         # PARSED_PACKAGE is a deb822.Deb822Dict object, so we can test
         # it directly
@@ -998,7 +998,7 @@ with open("test_deb822.pickle", "wb") as fh:
         with a newline (e.g. the control file Description field), then there
         should be a space after the colon, as with non-multiline fields.
         """
-        
+
         # bad_re: match a line that starts with a "Field:", and ends in
         # whitespace
         bad_re = re.compile(r"^\S+:\s+$")
@@ -1010,7 +1010,7 @@ with open("test_deb822.pickle", "wb") as fh:
                                 "after the colon in a multiline field " \
                                 "starting with a newline"
 
-        
+
         control_paragraph = """Package: python-debian
 Architecture: all
 Depends: ${python:Depends}
@@ -1047,12 +1047,12 @@ Description: python modules to work with Debian-related data formats
         d['Foo'] = 'bar'
         d['Baz'] = ''
         d['Another-Key'] = 'another value'
-        
+
         # Previous versions would raise an exception here -- this makes the
         # test fail and gives useful information, so I won't try to wrap around
         # it.
         dumped = d.dump()
-        
+
         # May as well make sure the resulting string is what we want
         expected = "Foo: bar\nBaz:\nAnother-Key: another value\n"
         assert dumped == expected
-- 
2.47.3

>From 0d81af5066bac24d3fca2e67c428e7e998d9a06f Mon Sep 17 00:00:00 2001
From: Nicolas Boulenguez <[email protected]>
Date: Thu, 6 Nov 2025 22:14:09 +0100
Subject: [PATCH 2/7] style: clean src/python_debian.egg-info/

---
 debian/clean | 1 +
 1 file changed, 1 insertion(+)

diff --git a/debian/clean b/debian/clean
index 3651b9c..714eafc 100644
--- a/debian/clean
+++ b/debian/clean
@@ -7,3 +7,4 @@ build/sphinx/
 .mypy_cache/
 src/debian/.mypy_cache/
 .coverage
+src/python_debian.egg-info/
-- 
2.47.3

>From 1de870f52150693cbd51eab0ace24bb81ddf2de3 Mon Sep 17 00:00:00 2001
From: Nicolas Boulenguez <[email protected]>
Date: Thu, 6 Nov 2025 22:27:41 +0100
Subject: [PATCH 3/7] style: replace physical address to the FSF with an URL

---
 debian/copyright | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/debian/copyright b/debian/copyright
index d1187b0..032123a 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -117,8 +117,7 @@ License: GPL-2+
  GNU General Public License for more details.
  .
  You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  .
  On Debian systems, the complete text of the GNU General Public License
  version 2 can be found in `/usr/share/common-licenses/GPL-2'.
-- 
2.47.3

>From 495b78728d344bb13897c81a138101887ef4dec4 Mon Sep 17 00:00:00 2001
From: Nicolas Boulenguez <[email protected]>
Date: Thu, 6 Nov 2025 22:31:54 +0100
Subject: [PATCH 4/7] style: drop obsolete Rules-Requires-Root: no from
 debian/control

---
 debian/control | 1 -
 1 file changed, 1 deletion(-)

diff --git a/debian/control b/debian/control
index 32be789..9d101b2 100644
--- a/debian/control
+++ b/debian/control
@@ -29,7 +29,6 @@ Standards-Version: 4.7.0
 Vcs-Browser: https://salsa.debian.org/python-debian-team/python-debian
 Vcs-Git: https://salsa.debian.org/python-debian-team/python-debian.git
 Homepage: https://salsa.debian.org/python-debian-team/python-debian
-Rules-Requires-Root: no
 
 Package: python3-debian
 Architecture: all
-- 
2.47.3

>From ead04b68884de73f7ae5fcf77ed87dee5612b9ee Mon Sep 17 00:00:00 2001
From: Nicolas Boulenguez <[email protected]>
Date: Thu, 6 Nov 2025 22:33:25 +0100
Subject: [PATCH 5/7] style: Update Standards-Version to 4.7.2

---
 debian/control | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/debian/control b/debian/control
index 9d101b2..3986786 100644
--- a/debian/control
+++ b/debian/control
@@ -25,7 +25,7 @@ Build-Depends:
  zstd <!nocheck>,
 Build-Conflicts:
   gpgv-from-sq,
-Standards-Version: 4.7.0
+Standards-Version: 4.7.2
 Vcs-Browser: https://salsa.debian.org/python-debian-team/python-debian
 Vcs-Git: https://salsa.debian.org/python-debian-team/python-debian.git
 Homepage: https://salsa.debian.org/python-debian-team/python-debian
-- 
2.47.3

>From 058da4f4835ad594bf54842926e0f7a8ca36e488 Mon Sep 17 00:00:00 2001
From: Nicolas Boulenguez <[email protected]>
Date: Thu, 6 Nov 2025 21:32:47 +0100
Subject: [PATCH 6/7] style: replace collections.namedtuple with
 typing.NamedTuple in deb822.py

---
 src/debian/deb822.py | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/src/debian/deb822.py b/src/debian/deb822.py
index 1592ec9..4929583 100644
--- a/src/debian/deb822.py
+++ b/src/debian/deb822.py
@@ -257,6 +257,7 @@ from typing import (
     List,
     Mapping,
     MutableMapping,
+    NamedTuple,
     Optional,
     overload,
     Text,
@@ -1393,10 +1394,13 @@ class PkgRelation:
         r'(?P<enabled>\!)?'
         r'(?P<profile>[^\s]+)')
 
-    ArchRestriction = collections.namedtuple('ArchRestriction',
-                                             ['enabled', 'arch'])
-    BuildRestriction = collections.namedtuple('BuildRestriction',
-                                              ['enabled', 'profile'])
+    class ArchRestriction(NamedTuple):
+        enabled: bool
+        arch: str
+
+    class BuildRestriction(NamedTuple):
+        enabled: bool
+        profile: str
 
     if TYPE_CHECKING:
         class ParsedRelation(TypedDict):
-- 
2.47.3

>From a63e7044b93d56cc3d029912e7befcb657726fb1 Mon Sep 17 00:00:00 2001
From: Nicolas Boulenguez <[email protected]>
Date: Thu, 6 Nov 2025 21:28:36 +0100
Subject: [PATCH 7/7] Add deb822.PkgRelation.{holds_on_arch,
 holds_with_profiles}

The next concern after parse_relations is probably to check that the
relation holds in a given context.  Enable callers to do that without
depending on the internal representation of arch and profiles
restrictions.
---
 src/debian/deb822.py | 27 +++++++++++++++++++++++++++
 tests/test_deb822.py | 40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+)

diff --git a/src/debian/deb822.py b/src/debian/deb822.py
index 4929583..b230e30 100644
--- a/src/debian/deb822.py
+++ b/src/debian/deb822.py
@@ -1487,6 +1487,33 @@ class PkgRelation:
         cnf = map(cls.__pipe_sep_RE.split, tl_deps)
         return [[parse_rel(or_dep) for or_dep in or_deps] for or_deps in cnf]
 
+    @staticmethod
+    def holds_on_arch(relation: ParsedRelation, arch: str) -> bool:
+        """Is relation active on the given architecture?
+
+        Check arch against a disjunction like [amd64 armel]
+        or a conjonction of exclusions like [!amd64 !armel].
+
+        Per policy, the list is non empty and ! affects all names or none."""
+        archs = relation["arch"]
+        return (archs is None
+                or archs[0].enabled == any(arch == a.arch for a in archs))
+
+    @staticmethod
+    def holds_with_profiles(
+        relation: ParsedRelation,
+        profiles: collections.abc.Container[str],
+    ) -> bool:
+        """Is relation active under the given profiles?
+
+        In the relation, '<a !b> <c>' requires that profiles
+        either contains a but not b, or contains c."""
+        restrictions = relation["restrictions"]
+        return (restrictions is None
+                or any(all(term.enabled == (term.profile in profiles)
+                           for term in restriction_list)
+                       for restriction_list in restrictions))
+
     @staticmethod
     def str(rels: List[List[PkgRelation.ParsedRelation]]) -> builtins.str:
         """Format to string structured inter-package relationships
diff --git a/tests/test_deb822.py b/tests/test_deb822.py
index 97623dd..a632e4f 100755
--- a/tests/test_deb822.py
+++ b/tests/test_deb822.py
@@ -1701,6 +1701,46 @@ class TestPkgRelations:
         assert term == "native"
         assert deb822.PkgRelation.str(rel) == r
 
+    def test_holds_on_arch(self) -> None:
+        A = "a"                 # the current architecture
+        for one_relation, expected in (
+            # no restriction
+            ("foo",                     True),
+            # architecture membership
+            ("foo [ a1  a   a2]",       True),
+            ("foo [ a1      a2]",       False),
+            # architecture exclusions
+            ("foo [!a1    !a2]",        True),
+            ("foo [!a1 !a !a2]",        False),
+        ):
+            rel = deb822.PkgRelation.parse_relations(one_relation)[0][0]
+            got = deb822.PkgRelation.holds_on_arch(rel, A)
+            assert got == expected, one_relation
+
+    def test_holds_with_profiles(self) -> None:
+        P = ("p1", "p2")        # the current profiles
+        for one_relation, expected in (
+            # no restriction
+            ("foo",                     True),
+            # profile membership
+            ("foo <p1>",                True),
+            ("foo <p>",                 False),
+            # profile negation
+            ("foo <!p1>",               False),
+            ("foo <!p>",                True),
+            # profile conjunction
+            ("foo <p p1>",              False),
+            ("foo <p1 p2>",             True),
+            ("foo <p1 p2 p>",           False),
+            # profile disjunction
+            ("foo <p> <p1>",            True),
+            ("foo <p> <q>",             False),
+            ("foo <p1> <p2>",           True),
+        ):
+            rel = deb822.PkgRelation.parse_relations(one_relation)[0][0]
+            got = deb822.PkgRelation.holds_with_profiles(rel, P)
+            assert got == expected, one_relation
+
 
 class TestVersionAccessor:
 
-- 
2.47.3


--- End Message ---
--- Begin Message ---
Source: python-debian
Source-Version: 1.1.0
Done: Niels Thykier <[email protected]>

We believe that the bug you reported is fixed in the latest version of
python-debian, which is due to be installed in the Debian FTP archive.

A summary of the changes between this version and the previous one is
attached.

Thank you for reporting the bug, which will now be closed.  If you
have further comments please address them to [email protected],
and the maintainer will reopen the bug report if appropriate.

Debian distribution maintenance software
pp.
Niels Thykier <[email protected]> (supplier of updated python-debian package)

(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing [email protected])


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Format: 1.8
Date: Sun, 08 Feb 2026 13:31:49 +0000
Source: python-debian
Architecture: source
Version: 1.1.0
Distribution: unstable
Urgency: medium
Maintainer: Debian python-debian Maintainers 
<[email protected]>
Changed-By: Niels Thykier <[email protected]>
Closes: 1095138 1120283
Changes:
 python-debian (1.1.0) unstable; urgency=medium
 .
   [ Colin Watson ]
   * Add support for merging Changes objects
   * Fix merging of multi-line fields
 .
   [ Sébastien Noel ]
   * gitlab-ci: Trixie has been released
   * Provide a new dpkg_arch_to_multiarch() function
     (Closes: #1095138)
 .
   [ Stuart Prescott ]
   * Mutliple test, type and annotation related changes
     including running `pyupgrade` with `py37` as target
     version.
 .
   [ Nicolas Boulenguez ]
   * Add deb822.PkgRelation.{holds_on_arch, holds_with_profiles}
     (Closes: #1120283)
   * Replace physical address to the FSF with an URL in the license text
   * Update Standards-Version to 4.7.3
   * Replace collections.namedtuple with typing.NamedTuple in deb822.py
Checksums-Sha1:
 1f0c31215e86934c3ac07ac97749d793a19d00d3 2689 python-debian_1.1.0.dsc
 821c2b40a4d6158da78fc3321d07ddecdb5f8f14 200940 python-debian_1.1.0.tar.xz
 ce32f0c56f153fe291da3ef92ba4785a0dca2bf5 342996 python-debian_1.1.0.git.tar.xz
 49c1ab6dffd605207267b0919fef550c8c592cd3 17310 
python-debian_1.1.0_source.buildinfo
Checksums-Sha256:
 c212d64cb9715849ebc7f4b3c14b3c5286c104387f0396455c536d7520a97c29 2689 
python-debian_1.1.0.dsc
 7c7396ffc7bd3e3d6b740c5e9c156a18a5641a06a96b65580ff2a97457b8d2f2 200940 
python-debian_1.1.0.tar.xz
 b50e50ceca7921d87ebef6338db1df44799052d25a23c53cd9471a2eec40c14b 342996 
python-debian_1.1.0.git.tar.xz
 42e58709eb11103b8f778459ae89468622c6532fc8a0d8eac525a45c4a6c46b8 17310 
python-debian_1.1.0_source.buildinfo
Files:
 7011a4e5f6d08e288201f52179de8449 2689 python optional python-debian_1.1.0.dsc
 a31978354a82fc03ef8f1e3b4d36b513 200940 python optional 
python-debian_1.1.0.tar.xz
 84b8cf6d4b1b83abcc5ab851d9bced0d 342996 python None 
python-debian_1.1.0.git.tar.xz
 0a807c68fb2b26334b5c60fa38c2d241 17310 python optional 
python-debian_1.1.0_source.buildinfo
Git-Tag-Info: tag=e29931b2701d0fc69219838cfe919c7692b5faa4 
fp=f5e7199aef5e5c67e555873f740d68888365d289
Git-Tag-Tagger: Niels Thykier <[email protected]>

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEN02M5NuW6cvUwJcqYG0ITkaDwHkFAmmIlgoACgkQYG0ITkaD
wHlE1xAAlQkbrfMbxdYojaFZ8WHn1/S8bd3HYWCt+P+0g5ZjHhVq6Egyq3C5CW/G
GgMKZV/hatXzrU6oon9yNDcPg1OV/XKBkLEMIiCFZIMu3jh3M7FhjDQx/1WyVx9n
uxWFx4faItRn3HyzYx5CLkNIwDUdc+t7Z7lDcozo/O4so+RBSN+3tHprTjA9J0St
7nNvRkaU4JdMd4e6rrReSqhDvEQ6xF3oMpyTofC25KAY3HXqR689U4yoayGI1m3w
xsDZBgsQ6CK6h/nq3Wf/xxD3izuv3VLgf//61Sa2VzriLHy2d3ZSxBvjTucOLc94
W9XHkokdYjrbOcpMEcfVBqP1VQ92KUVzHNJPfzO3hJi1fojbSKTI6cFtP21D8VfY
y+pYFhGGLJzKRnSiWRmlsAFjak2mCS9Cotb0blawoRj0JLseZmcfUaYlkmEKPyCh
mJDuZTbMdxDMRPUbzZZDp7+7NzJuXx8I+/qKH2MO6H3tKotaW1yEX+IVqAskOAVm
3aTWDGBOB+zyfGp+/mDd4/OUTadrm8Sp0zBOKjTc+9l+vyL4jQxwjEYTjW6TNqzT
lSSj7Mir2/tYH9XRtEwRhIWrvBtSQ3GR8eVIY3U5kJh5TYcH1J2c2yEQg7gTjGmV
obT28WoqVH12DBHDUGpatiRbzFll0BJLSeEcKjS/0ulwEhMs1Lo=
=mhUy
-----END PGP SIGNATURE-----

Attachment: pgpKdEYpxFo48.pgp
Description: PGP signature


--- End Message ---
-- 
https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/pkg-python-debian-maint

Reply via email to