Skip to content

Commit

Permalink
dep: support modifying category and package with Dep.modify()
Browse files Browse the repository at this point in the history
  • Loading branch information
radhermit committed Nov 29, 2023
1 parent b1fa5c4 commit 1bfc981
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 12 deletions.
20 changes: 12 additions & 8 deletions src/pkgcraft/C.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ cdef extern from "pkgcraft.h":
BLOCKER_WEAK,

cdef enum:
DEP_FIELD_BLOCKER # = 1,
DEP_FIELD_VERSION # = (1 << 1),
DEP_FIELD_SLOT # = (1 << 2),
DEP_FIELD_SUBSLOT # = (1 << 3),
DEP_FIELD_SLOT_OP # = (1 << 4),
DEP_FIELD_USE_DEPS # = (1 << 5),
DEP_FIELD_REPO # = (1 << 6),
DEP_FIELD_CATEGORY # = 1,
DEP_FIELD_PACKAGE,
DEP_FIELD_BLOCKER,
DEP_FIELD_VERSION,
DEP_FIELD_SLOT,
DEP_FIELD_SUBSLOT,
DEP_FIELD_SLOT_OP,
DEP_FIELD_USE_DEPS,
DEP_FIELD_REPO,
ctypedef uint32_t DepField

# DepSet variants.
Expand Down Expand Up @@ -985,7 +987,9 @@ cdef extern from "pkgcraft.h":
# The argument must be a non-null Dep pointer.
Version *pkgcraft_dep_version(Dep *d)

# Return a package dependency without the specified fields
# Return a package dependency without the specified fields.
#
# Returns NULL on error.
#
# # Safety
# The arguments must a valid Dep pointer and DepField values.
Expand Down
6 changes: 5 additions & 1 deletion src/pkgcraft/dep/pkg.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ class SlotOperator(IntEnum):

# mapping of field names to values for Dep.without()
_DEP_FIELDS = MappingProxyType({
'category': C.DEP_FIELD_CATEGORY,
'package': C.DEP_FIELD_PACKAGE,
'blocker': C.DEP_FIELD_BLOCKER,
'version': C.DEP_FIELD_VERSION,
'slot': C.DEP_FIELD_SLOT,
Expand Down Expand Up @@ -179,7 +181,9 @@ cdef class Dep:
ptr = C.pkgcraft_dep_without(self.ptr, dep_fields, len(fields))
PyMem_Free(dep_fields)

if ptr != self.ptr:
if ptr is NULL:
raise InvalidDep
elif ptr != self.ptr:
return Dep.from_ptr(ptr)

return self
Expand Down
27 changes: 24 additions & 3 deletions tests/dep/test_pkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ def test_valid(self):
Dep.valid(obj)

def test_without(self):
fields = ("blocker", "version", "slot", "subslot", "slot_op", "use_deps", "repo")
optional_fields = ("blocker", "version", "slot", "subslot", "slot_op", "use_deps", "repo")
dep = Dep("!!>=cat/pkg-1.2-r3:4/5=::repo[u]")

# no args returns the same object
Expand All @@ -153,20 +153,26 @@ def test_without(self):
assert str(dep.without("slot_op")) == "!!>=cat/pkg-1.2-r3:4/5::repo[u]"
assert str(dep.without("use_deps")) == "!!>=cat/pkg-1.2-r3:4/5=::repo"
assert str(dep.without("repo")) == "!!>=cat/pkg-1.2-r3:4/5=[u]"
assert str(dep.without(*fields)) == "cat/pkg"
assert str(dep.without(*optional_fields)) == "cat/pkg"

# returns the same object when no fields are removed
dep = Dep(">=cat/pkg-1.2-r3::repo")
assert dep.without("use_deps") is dep

# category and package can't be unset
for field in ["category", "package"]:
with pytest.raises(InvalidDep):
dep.without(field)

# invalid fields
for obj in [object(), None, "field"]:
with pytest.raises(ValueError):
dep.without(obj)

# verify all combinations of dep fields create valid deps
dep = Dep("!!>=cat/pkg-1.2-r3:4/5=::repo[a,b]")
for vals in chain.from_iterable(combinations(fields, r) for r in range(len(fields) + 1)):
lengths = range(len(optional_fields) + 1)
for vals in chain.from_iterable(combinations(optional_fields, r) for r in lengths):
d = dep.without(*vals)
assert d == Dep(str(d))

Expand All @@ -175,12 +181,27 @@ def test_modify(self):
# no args returns the same object
assert dep.modify() is dep

# category
dep = Dep("cat/pkg")
dep = dep.modify(category="a")
assert str(dep) == "a/pkg"
with pytest.raises(InvalidDep):
dep.modify(category=None)

# package
dep = Dep("cat/pkg")
dep = dep.modify(package="b")
assert str(dep) == "cat/b"
with pytest.raises(InvalidDep):
dep.modify(package=None)

# version
dep = Dep("cat/pkg")
dep = dep.modify(version=">1")
assert str(dep) == ">cat/pkg-1"
dep = dep.modify(version=None)
assert str(dep) == "cat/pkg"
assert dep.modify(version=None) is dep

# invalid version values
for s in ("", "1.2.3-r4"):
Expand Down

0 comments on commit 1bfc981

Please sign in to comment.