Source: python-debian
Followup-For: Bug #1120283
Please replace patch 7 with the attached version, which delegates to
architecture_is_concerned and fixes architecture wildcards.
>From 10623540095b666051e5b95718224a7bfa9bc984 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 | 40 ++++++++++++++++++++++++++++++++++++++++
tests/test_deb822.py | 41 ++++++++++++++++++++++++++++++++++++++++-
2 files changed, 80 insertions(+), 1 deletion(-)
diff --git a/src/debian/deb822.py b/src/debian/deb822.py
index 4929583..1fab800 100644
--- a/src/debian/deb822.py
+++ b/src/debian/deb822.py
@@ -1487,6 +1487,46 @@ 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,
+ table: debian_support.DpkgArchTable,
+ ) -> bool:
+ """Is relation active on the given architecture?
+
+ >>> table = DpkgArchTable.load_arch_table()
+ >>> relation = PkgRelation.parse_relations("foo [armel linux-any],")[0][0]
+ >>> PkgRelation.holds_on_arch(relation, "amd64", table)
+ True
+ >>> PkgRelation.holds_on_arch(relation, "hurd-i386", table)
+ False
+ """
+ archs = relation["arch"]
+ return (archs is None
+ or table.architecture_is_concerned(
+ arch,
+ tuple(("" if a.enabled else "!") + 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?
+
+ >>> relation = PkgRelation.parse_relations("foo <a !b> <c>")[0][0]
+ >>> PkgRelation.holds_with_profiles(relation, ("a", "b"))
+ False
+ >>> PkgRelation.holds_with_profiles(relation, ("c", ))
+ True
+ """
+ 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..5909b06 100755
--- a/tests/test_deb822.py
+++ b/tests/test_deb822.py
@@ -59,7 +59,7 @@ except ImportError:
from debian import deb822
-from debian.debian_support import Version
+from debian.debian_support import DpkgArchTable, Version
from typing import (
@@ -1701,6 +1701,45 @@ class TestPkgRelations:
assert term == "native"
assert deb822.PkgRelation.str(rel) == r
+ def test_holds_on_arch(self) -> None:
+ table = DpkgArchTable.load_arch_table()
+ for one_relation, expected in (
+ # no restriction
+ ("foo", True),
+ # architecture membership
+ ("foo [ amd64 armel]", True),
+ ("foo [ armel]", False),
+ # architecture exclusions
+ ("foo [!amd64 !armel]", False),
+ ("foo [ !armel]", True),
+ ):
+ rel = deb822.PkgRelation.parse_relations(one_relation)[0][0]
+ got = deb822.PkgRelation.holds_on_arch(rel, "amd64", table)
+ assert got == expected, one_relation
+
+ def test_holds_with_profiles(self) -> None:
+ 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, ("p1", "p2"))
+ assert got == expected, one_relation
+
class TestVersionAccessor:
--
2.47.3