diff options
Diffstat (limited to 'pym/portage/util/SlotObject.py')
-rw-r--r-- | pym/portage/util/SlotObject.py | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/pym/portage/util/SlotObject.py b/pym/portage/util/SlotObject.py new file mode 100644 index 000000000..a59dfc199 --- /dev/null +++ b/pym/portage/util/SlotObject.py @@ -0,0 +1,51 @@ +# Copyright 1999-2012 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +class SlotObject(object): + __slots__ = ("__weakref__",) + + def __init__(self, **kwargs): + classes = [self.__class__] + while classes: + c = classes.pop() + if c is SlotObject: + continue + classes.extend(c.__bases__) + slots = getattr(c, "__slots__", None) + if not slots: + continue + for myattr in slots: + myvalue = kwargs.pop(myattr, None) + if myvalue is None and getattr(self, myattr, None) is not None: + raise AssertionError( + "class '%s' duplicates '%s' value in __slots__ of base class '%s'" % + (self.__class__.__name__, myattr, c.__name__)) + setattr(self, myattr, myvalue) + + if kwargs: + raise TypeError( + "'%s' is an invalid keyword argument for this constructor" % + (next(iter(kwargs)),)) + + def copy(self): + """ + Create a new instance and copy all attributes + defined from __slots__ (including those from + inherited classes). + """ + obj = self.__class__() + + classes = [self.__class__] + while classes: + c = classes.pop() + if c is SlotObject: + continue + classes.extend(c.__bases__) + slots = getattr(c, "__slots__", None) + if not slots: + continue + for myattr in slots: + setattr(obj, myattr, getattr(self, myattr)) + + return obj + |