diff options
author | Sebastian Thiel <byronimo@gmail.com> | 2011-06-08 10:43:47 +0200 |
---|---|---|
committer | Sebastian Thiel <byronimo@gmail.com> | 2011-06-08 11:07:47 +0200 |
commit | b7071ce13476cae789377c280aa274e6242fd756 (patch) | |
tree | 9cabdc2dfb6dd5c9e2d5d7d7fbd22686d42dbf5c | |
parent | fcc166d3a6e235933e823e82e1fcf6160a32a5d3 (diff) | |
download | gitpython-b7071ce13476cae789377c280aa274e6242fd756.tar.gz |
util: Added test for iterable list, and implemented __contains__ and __del__ functionality
-rw-r--r-- | doc/source/changes.rst | 4 | ||||
-rw-r--r-- | git/test/test_util.py | 59 | ||||
-rw-r--r-- | git/util.py | 34 |
3 files changed, 95 insertions, 2 deletions
diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 22568e3d..0cb6d065 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -11,6 +11,10 @@ Changelog * **Blob** Type * Added mode constants to ease the manual creation of blobs + +* **IterableList** + + * Added __contains__ and __delitem__ methods * **More Changes** diff --git a/git/test/test_util.py b/git/test/test_util.py index e55a6d15..a11c15c3 100644 --- a/git/test/test_util.py +++ b/git/test/test_util.py @@ -7,8 +7,8 @@ import os import tempfile -from git.test.lib import * from git.util import * +from git.test.lib import * from git.objects.util import * from git import * from git.cmd import dashify @@ -16,6 +16,15 @@ from git.cmd import dashify import time +class TestIterableMember(object): + """A member of an iterable list""" + __slots__ = ("name", "prefix_name") + + def __init__(self, name): + self.name = name + self.prefix_name = name + + class TestUtils(TestBase): def setup(self): self.testdict = { @@ -107,3 +116,51 @@ class TestUtils(TestBase): assert isinstance(Actor.committer(cr), Actor) assert isinstance(Actor.author(cr), Actor) #END assure config reader is handled + + def test_iterable_list(self): + for args in (('name',), ('name', 'prefix_')): + l = IterableList('name') + + m1 = TestIterableMember('one') + m2 = TestIterableMember('two') + + l.extend((m1, m2)) + + assert len(l) == 2 + + # contains works with name and identity + assert m1.name in l + assert m2.name in l + assert m2 in l + assert m2 in l + assert 'invalid' not in l + + # with string index + assert l[m1.name] is m1 + assert l[m2.name] is m2 + + # with int index + assert l[0] is m1 + assert l[1] is m2 + + # with getattr + assert l.one is m1 + assert l.two is m2 + + # test exceptions + self.failUnlessRaises(AttributeError, getattr, l, 'something') + self.failUnlessRaises(IndexError, l.__getitem__, 'something') + + # delete by name and index + self.failUnlessRaises(IndexError, l.__delitem__, 'something') + del(l[m2.name]) + assert len(l) == 1 + assert m2.name not in l and m1.name in l + del(l[0]) + assert m1.name not in l + assert len(l) == 0 + + self.failUnlessRaises(IndexError, l.__delitem__, 0) + self.failUnlessRaises(IndexError, l.__delitem__, 'something') + #END for each possible mode + diff --git a/git/util.py b/git/util.py index 00085ae0..71bf6977 100644 --- a/git/util.py +++ b/git/util.py @@ -330,7 +330,6 @@ class Actor(object): but defaults to the committer""" return cls._main_actor(cls.env_author_name, cls.env_author_email, config_reader) - class Stats(object): """ Represents stat information as presented by git at the end of a merge. It is @@ -560,6 +559,21 @@ class IterableList(list): raise ValueError("First parameter must be a string identifying the name-property. Extend the list after initialization") # END help debugging ! + def __contains__(self, attr): + # first try identy match for performance + rval = list.__contains__(self, attr) + if rval: + return rval + #END handle match + + # otherwise make a full name search + try: + getattr(self, attr) + return True + except (AttributeError, TypeError): + return False + #END handle membership + def __getattr__(self, attr): attr = self._prefix + attr for item in self: @@ -576,7 +590,25 @@ class IterableList(list): return getattr(self, index) except AttributeError: raise IndexError( "No item found with id %r" % (self._prefix + index) ) + # END handle getattr + def __delitem__(self, index): + delindex = index + if not isinstance(index, int): + delindex = -1 + name = self._prefix + index + for i, item in enumerate(self): + if getattr(item, self._id_attr) == name: + delindex = i + break + #END search index + #END for each item + if delindex == -1: + raise IndexError("Item with name %s not found" % name) + #END handle error + #END get index to delete + list.__delitem__(self, delindex) + class Iterable(object): """Defines an interface for iterable items which is to assure a uniform |