Source code for pkgcore.resolver.pigeonholes
__all__ = ("PigeonHoledSlots",)
from ..restrictions import restriction
# lil too getter/setter like for my tastes...
[docs]
class PigeonHoledSlots:
"""class for tracking slotting to a specific atom/obj key
no atoms present, just prevents conflicts of obj.key; atom present, assumes
it's a blocker and ensures no obj matches the atom for that key
"""
def __init__(self):
self.slot_dict = {}
self.limiters = {}
[docs]
def fill_slotting(self, obj, force=False):
"""Try to insert obj in.
:return: any conflicting objs (empty list if inserted successfully).
"""
l = self.check_limiters(obj)
key = obj.key
dslot = obj.slot
l.extend(x for x in self.slot_dict.get(key, ()) if x.slot == dslot)
if not l or force:
self.slot_dict.setdefault(key, []).append(obj)
return l
[docs]
def get_conflicting_slot(self, pkg):
for x in self.slot_dict.get(pkg.key, ()):
if pkg.slot == x.slot:
return x
return None
[docs]
def find_atom_matches(self, atom, key=None):
if key is None:
key = atom.key
return list(filter(atom.match, self.slot_dict.get(key, ())))
[docs]
def add_limiter(self, atom, key=None):
"""add a limiter, returning any conflicting objs"""
if not isinstance(atom, restriction.base):
raise TypeError(
f"atom must be a restriction.base derivative: got {atom!r}, key={key!r}"
)
# debug.
if key is None:
key = atom.key
self.limiters.setdefault(key, []).append(atom)
return self.find_atom_matches(atom, key=key)
[docs]
def check_limiters(self, obj):
"""return any limiters conflicting w/ the passed in obj"""
key = obj.key
return [x for x in self.limiters.get(key, ()) if x.match(obj)]
[docs]
def remove_slotting(self, obj):
key = obj.key
# let the key error be thrown if they screwed up.
slots = self.slot_dict.get(key, ())
l = [x for x in slots if x is not obj]
if len(l) == len(slots):
raise KeyError(f"obj {obj} isn't slotted")
if l:
self.slot_dict[key] = l
else:
del self.slot_dict[key]
[docs]
def remove_limiter(self, atom, key=None):
if key is None:
key = atom.key
l = [x for x in self.limiters[key] if x is not atom]
if len(l) == len(self.limiters[key]):
raise KeyError(f"obj {atom} isn't slotted")
if not l:
del self.limiters[key]
else:
self.limiters[key] = l
def __contains__(self, obj):
if isinstance(obj, restriction.base):
return obj in self.limiters.get(obj.key, ())
return obj in self.slot_dict.get(obj.key, ())