Source code for pkgcore.restrictions.restriction

"""
base restriction class
"""

from functools import partial

from snakeoil import caching, klass
from snakeoil.currying import pretty_docs


[docs] class base(klass.SlotsPicklingMixin, metaclass=caching.WeakInstMeta): """base restriction matching object. all derivatives *should* be __slots__ based (lot of instances may wind up in memory). """ __inst_caching__ = True # __weakref__ here is implicit via the metaclass __slots__ = () package_matching = False klass.inject_immutable_instance(locals())
[docs] def match(self, *arg, **kwargs): raise NotImplementedError
[docs] def force_False(self, *arg, **kwargs): return not self.match(*arg, **kwargs)
[docs] def force_True(self, *arg, **kwargs): return self.match(*arg, **kwargs)
def __len__(self): return 1
[docs] class AlwaysBool(base): """restriction that always yields a specific boolean""" __slots__ = ("type", "negate") __inst_caching__ = True def __init__(self, node_type=None, negate=False): """ :param node_type: the restriction type the instance should be, typically :obj:`pkgcore.restrictions.restriction.package_type` or :obj:`pkgcore.restrictions.restriction.value_type` :param negate: boolean to return for the match """ object.__setattr__(self, "negate", negate) object.__setattr__(self, "type", node_type)
[docs] def match(self, *a, **kw): return self.negate
[docs] def force_True(self, *a, **kw): return self.negate
[docs] def force_False(self, *a, **kw): return not self.negate
def __iter__(self): return iter(()) def __str__(self): return f"always '{self.negate}'" def __repr__(self): return "<%s always %r @%#8x>" % (self.__class__.__name__, self.negate, id(self)) def __getstate__(self): return self.negate, self.type def __setstate__(self, state): negate, node_type = state object.__setattr__(self, "negate", negate) object.__setattr__(self, "type", node_type)
[docs] class Negate(base): """wrap and negate a restriction instance""" __slots__ = ("type", "_restrict") __inst_caching__ = False def __init__(self, restrict): """ :param restrict: :obj:`pkgcore.restrictions.restriction.base` instance to negate """ sf = object.__setattr__ sf(self, "type", restrict.type) sf(self, "_restrict", restrict)
[docs] def match(self, *a, **kw): return not self._restrict.match(*a, **kw)
def __str__(self): return "not (%s)" % self._restrict
[docs] class FakeType(base): """wrapper to wrap and fake a node_type""" __slots__ = ("type", "_restrict") __inst_caching__ = False def __init__(self, restrict, new_type): """ :param restrict: :obj:`pkgcore.restrictions.restriction.base` instance to wrap :param new_type: new node_type """ sf = object.__setattr__ sf(self, "type", new_type) sf(self, "_restrict", restrict)
[docs] def match(self, *a, **kw): return self._restrict.match(*a, **kw)
def __str__(self): return f"Faked type({self.type}): {self._restrict}"
[docs] class AnyMatch(base): """Apply a nested restriction to every item in a sequence.""" __slots__ = ("restriction", "type", "negate") def __init__(self, childrestriction, node_type, negate=False): """Initialize. :type childrestriction: restriction :param childrestriction: child restriction applied to every value. :type node_type: string :param node_type: type of this restriction. """ sf = object.__setattr__ sf(self, "negate", negate) sf(self, "restriction", childrestriction) sf(self, "type", node_type)
[docs] def match(self, val): for x in val: if self.restriction.match(x): return not self.negate return self.negate
def __str__(self): return f"any: {self.restriction} match" def __repr__(self): return f"<{self.__class__.__name__} restriction={self.restriction!r} @{id(self):#8x}>"
[docs] def curry_node_type(cls, node_type, extradoc=None): """Helper function for creating restrictions of a certain type. This uses :obj:`partial` to pass a node_type to the wrapped class, and extends the docstring. :param cls: callable (usually a class) that is wrapped. :param node_type: value passed as node_type. :param extradoc: addition to the docstring. Defaults to "Automatically set to %s type." % node_type :return: a wrapped callable. """ if extradoc is None: extradoc = f"Automatically set to {node_type} type." doc = cls.__doc__ result = partial(cls, node_type=node_type) if doc is None: doc = "" else: # do this so indentation on pydoc __doc__ is sane doc = "\n".join(line.lstrip() for line in doc.split("\n")) + "\n" doc += extradoc return pretty_docs(result, doc)
value_type = "values" package_type = "package" valid_types = (value_type, package_type)