commit: 92c15c0f33a24fbf1bd673bc3dc5526e021e5c47 Author: Jannik Glückert <jannik.glueckert <AT> gmail <DOT> com> AuthorDate: Sat Jun 14 19:40:57 2025 +0000 Commit: Sam James <sam <AT> gentoo <DOT> org> CommitDate: Mon Oct 20 17:31:52 2025 +0000 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=92c15c0f
portage.dep.Atom: improve slot regex We would previously allow slots without a main slot name, such as ":/subslot". This has never been allowed in PMS. Signed-off-by: Jannik Glückert <jannik.glueckert <AT> gmail.com> Part-of: https://github.com/gentoo/portage/pull/1445 Closes: https://github.com/gentoo/portage/pull/1445 Signed-off-by: Sam James <sam <AT> gentoo.org> lib/portage/dep/__init__.py | 31 +++++++++++++++---------------- lib/portage/tests/dep/test_atom.py | 1 + 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/portage/dep/__init__.py b/lib/portage/dep/__init__.py index ecd1b522cf..31d0900f90 100644 --- a/lib/portage/dep/__init__.py +++ b/lib/portage/dep/__init__.py @@ -90,11 +90,18 @@ def _get_slot_dep_re(eapi_attrs: portage.eapi._eapi_attrs) -> re.Pattern: return slot_re if eapi_attrs.slot_operator: - slot_re = _slot + r"?(\*|=|/" + _slot + r"=?)?" + slot_re = ( + "(" + # we don't want to name this group "slot", + # as that group name is already used in _get_atom_re() + + f"(?P<main_slot>{_slot})" + + ("(/" + f"(?P<sub_slot>{_slot})" + ")?") + + ")?" + ) + "(?P<slot_operator>[*=])?" else: slot_re = _slot - slot_re = re.compile("^" + slot_re + "$", re.VERBOSE | re.ASCII) + slot_re = re.compile(rf"^{slot_re}\Z", re.VERBOSE | re.ASCII) _slot_dep_re_cache[cache_key] = slot_re return slot_re @@ -1628,22 +1635,14 @@ class Atom(str): if slot_match is None: raise InvalidAtom(self) if eapi_attrs.slot_operator: - self.__dict__["slot"] = slot_match.group(1) - sub_slot = slot_match.group(2) - if sub_slot is not None: - sub_slot = sub_slot.lstrip("/") - if sub_slot in ("*", "="): - self.__dict__["sub_slot"] = None - self.__dict__["slot_operator"] = sub_slot - else: - slot_operator = None - if sub_slot is not None and sub_slot[-1:] == "=": - slot_operator = sub_slot[-1:] - sub_slot = sub_slot[:-1] - self.__dict__["sub_slot"] = sub_slot - self.__dict__["slot_operator"] = slot_operator + self.__dict__["slot"] = slot_match.group("main_slot") + self.__dict__["sub_slot"] = slot_match.group("sub_slot") + self.__dict__["slot_operator"] = slot_match.group("slot_operator") if self.slot is not None and self.slot_operator == "*": raise InvalidAtom(self) + # since both parts are optional, we could theoretically match on nothing + if self.slot is None and self.slot_operator is None: + raise InvalidAtom(self) else: self.__dict__["slot"] = slot self.__dict__["sub_slot"] = None diff --git a/lib/portage/tests/dep/test_atom.py b/lib/portage/tests/dep/test_atom.py index 2b29f20ccb..09b4e1c649 100644 --- a/lib/portage/tests/dep/test_atom.py +++ b/lib/portage/tests/dep/test_atom.py @@ -154,6 +154,7 @@ class TestAtom(TestCase): (Atom("sys-apps/portage"), False, False), ("cat/pkg\n", False, False), ("cat/Ҙ", False, False), + ("cat/pkg:/slot", False, False), ("+cat/pkg", False, False), ("-cat/pkg", False, False), (".cat/pkg", False, False),
