From 9856fb1180bd00e2949a308331005f3c46e35874 Mon Sep 17 00:00:00 2001 From: "Vgr E. Barry" Date: Thu, 21 Jun 2018 17:58:22 -0400 Subject: [PATCH] Rework the User containers a bit. Also add a friendlier string repr. --- src/containers.py | 72 +++++++++++++++-------------------------------- 1 file changed, 23 insertions(+), 49 deletions(-) diff --git a/src/containers.py b/src/containers.py index d911982..8edda72 100644 --- a/src/containers.py +++ b/src/containers.py @@ -31,15 +31,8 @@ files to get an idea of how those containers should be used. """ -class UserList(list): - def __init__(self, iterable=()): - super().__init__() - try: - for item in iterable: - self.append(item) - except: - self.clear() - raise +class Container: + """Base container class for all containers.""" def __enter__(self): return self @@ -47,6 +40,10 @@ class UserList(list): def __exit__(self, exc_type, exc_value, tb): self.clear() + def __str__(self): + vars = [format(x) for x in self] + return "{0}({1})".format(self.__class__.__name__, ", ".join(vars)) + def __eq__(self, other): return self is other @@ -56,6 +53,18 @@ class UserList(list): def __deepcopy__(self, memo): return type(self)(copy.deepcopy(x, memo) for x in self) + copy = __copy__ + +class UserList(Container, list): + def __init__(self, iterable=()): + super().__init__() + try: + for item in iterable: + self.append(item) + except: + self.clear() + raise + def __add__(self, other): if not isinstance(other, list): return NotImplemented @@ -104,9 +113,6 @@ class UserList(list): super().clear() - def copy(self): - return type(self)(self) - def extend(self, iterable): for item in iterable: self.append(item) @@ -136,7 +142,7 @@ class UserList(list): if item not in self: item.lists.remove(self) -class UserSet(set): +class UserSet(Container, set): def __init__(self, iterable=()): super().__init__() try: @@ -146,24 +152,6 @@ class UserSet(set): self.clear() raise - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_value, tb): - self.clear() - - def __copy__(self): - return type(self)(self) - - def __deepcopy__(self, memo): - return type(self)(copy.deepcopy(x, memo) for x in self) - - # Comparing UserSet instances for equality doesn't make much sense in our context - # However, if there are identical instances in a list, we only want to remove ourselves - - def __eq__(self, other): - return self is other - # Operators are not overloaded - 'user_set & other_set' will return a regular set # This is a deliberate design decision. To get a UserSet out of them, use the named ones @@ -212,9 +200,6 @@ class UserSet(set): super().clear() - def copy(self): - return type(self)(self) - def difference(self, iterable): return type(self)(super().difference(iterable)) @@ -265,7 +250,7 @@ class UserSet(set): if item not in self: self.add(item) -class UserDict(dict): +class UserDict(Container, dict): def __init__(_self, _it=(), **kwargs): super().__init__() if hasattr(_it, "items"): @@ -280,17 +265,9 @@ class UserDict(dict): self.popitem() # don't clear, as it's recursive (we might not want that) raise - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_value, tb): - self.clear() - - def __eq__(self, other): - return self is other - - def __copy__(self): - return type(self)(self) + def __str__(self): + vars = ["{0}: {1}".format(x, y) for x, y in self.items()] + return "{0}({1})".format(self.__class__.__name__, ", ".join(vars)) def __deepcopy__(self, memo): new = type(self)() @@ -347,9 +324,6 @@ class UserDict(dict): super().clear() - def copy(self): - return type(self)(self.items()) - @classmethod def fromkeys(cls, iterable, value=None): return cls(dict.fromkeys(iterable, value))