| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,6 +11,10 @@ Changelog | |||
| 11 | 11 | * **Blob** Type | |
| 12 | 12 | ||
| 13 | 13 | * Added mode constants to ease the manual creation of blobs | |
| 14 | + | ||
| 15 | + * **IterableList** | ||
| 16 | + | ||
| 17 | + * Added __contains__ and __delitem__ methods | ||
| 14 | 18 | ||
| 15 | 19 | * **More Changes** | |
| 16 | 20 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -7,15 +7,24 @@ | |||
| 7 | 7 | import os | |
| 8 | 8 | import tempfile | |
| 9 | 9 | ||
| 10 | - from git.test.lib import * | ||
| 11 | 10 | from git.util import * | |
| 11 | + from git.test.lib import * | ||
| 12 | 12 | from git.objects.util import * | |
| 13 | 13 | from git import * | |
| 14 | 14 | from git.cmd import dashify | |
| 15 | 15 | ||
| 16 | 16 | import time | |
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | + class TestIterableMember(object): | ||
| 20 | + """A member of an iterable list""" | ||
| 21 | + __slots__ = ("name", "prefix_name") | ||
| 22 | + | ||
| 23 | + def __init__(self, name): | ||
| 24 | + self.name = name | ||
| 25 | + self.prefix_name = name | ||
| 26 | + | ||
| 27 | + | ||
| 19 | 28 | class TestUtils(TestBase): | |
| 20 | 29 | def setup(self): | |
| 21 | 30 | self.testdict = { | |
@@ -107,3 +116,51 @@ def test_actor(self): | |||
| 107 | 116 | assert isinstance(Actor.committer(cr), Actor) | |
| 108 | 117 | assert isinstance(Actor.author(cr), Actor) | |
| 109 | 118 | #END assure config reader is handled | |
| 119 | + | ||
| 120 | + def test_iterable_list(self): | ||
| 121 | + for args in (('name',), ('name', 'prefix_')): | ||
| 122 | + l = IterableList('name') | ||
| 123 | + | ||
| 124 | + m1 = TestIterableMember('one') | ||
| 125 | + m2 = TestIterableMember('two') | ||
| 126 | + | ||
| 127 | + l.extend((m1, m2)) | ||
| 128 | + | ||
| 129 | + assert len(l) == 2 | ||
| 130 | + | ||
| 131 | + # contains works with name and identity | ||
| 132 | + assert m1.name in l | ||
| 133 | + assert m2.name in l | ||
| 134 | + assert m2 in l | ||
| 135 | + assert m2 in l | ||
| 136 | + assert 'invalid' not in l | ||
| 137 | + | ||
| 138 | + # with string index | ||
| 139 | + assert l[m1.name] is m1 | ||
| 140 | + assert l[m2.name] is m2 | ||
| 141 | + | ||
| 142 | + # with int index | ||
| 143 | + assert l[0] is m1 | ||
| 144 | + assert l[1] is m2 | ||
| 145 | + | ||
| 146 | + # with getattr | ||
| 147 | + assert l.one is m1 | ||
| 148 | + assert l.two is m2 | ||
| 149 | + | ||
| 150 | + # test exceptions | ||
| 151 | + self.failUnlessRaises(AttributeError, getattr, l, 'something') | ||
| 152 | + self.failUnlessRaises(IndexError, l.__getitem__, 'something') | ||
| 153 | + | ||
| 154 | + # delete by name and index | ||
| 155 | + self.failUnlessRaises(IndexError, l.__delitem__, 'something') | ||
| 156 | + del(l[m2.name]) | ||
| 157 | + assert len(l) == 1 | ||
| 158 | + assert m2.name not in l and m1.name in l | ||
| 159 | + del(l[0]) | ||
| 160 | + assert m1.name not in l | ||
| 161 | + assert len(l) == 0 | ||
| 162 | + | ||
| 163 | + self.failUnlessRaises(IndexError, l.__delitem__, 0) | ||
| 164 | + self.failUnlessRaises(IndexError, l.__delitem__, 'something') | ||
| 165 | + #END for each possible mode | ||
| 166 | + | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -330,7 +330,6 @@ def author(cls, config_reader=None): | |||
| 330 | 330 | but defaults to the committer""" | |
| 331 | 331 | return cls._main_actor(cls.env_author_name, cls.env_author_email, config_reader) | |
| 332 | 332 | ||
| 333 | - | ||
| 334 | 333 | class Stats(object): | |
| 335 | 334 | """ | |
| 336 | 335 | Represents stat information as presented by git at the end of a merge. It is | |
@@ -560,6 +559,21 @@ def __init__(self, id_attr, prefix=''): | |||
| 560 | 559 | raise ValueError("First parameter must be a string identifying the name-property. Extend the list after initialization") | |
| 561 | 560 | # END help debugging ! | |
| 562 | 561 | ||
| 562 | + def __contains__(self, attr): | ||
| 563 | + # first try identy match for performance | ||
| 564 | + rval = list.__contains__(self, attr) | ||
| 565 | + if rval: | ||
| 566 | + return rval | ||
| 567 | + #END handle match | ||
| 568 | + | ||
| 569 | + # otherwise make a full name search | ||
| 570 | + try: | ||
| 571 | + getattr(self, attr) | ||
| 572 | + return True | ||
| 573 | + except (AttributeError, TypeError): | ||
| 574 | + return False | ||
| 575 | + #END handle membership | ||
| 576 | + | ||
| 563 | 577 | def __getattr__(self, attr): | |
| 564 | 578 | attr = self._prefix + attr | |
| 565 | 579 | for item in self: | |
@@ -576,7 +590,25 @@ def __getitem__(self, index): | |||
| 576 | 590 | return getattr(self, index) | |
| 577 | 591 | except AttributeError: | |
| 578 | 592 | raise IndexError( "No item found with id %r" % (self._prefix + index) ) | |
| 593 | + # END handle getattr | ||
| 579 | 594 | ||
| 595 | + def __delitem__(self, index): | ||
| 596 | + delindex = index | ||
| 597 | + if not isinstance(index, int): | ||
| 598 | + delindex = -1 | ||
| 599 | + name = self._prefix + index | ||
| 600 | + for i, item in enumerate(self): | ||
| 601 | + if getattr(item, self._id_attr) == name: | ||
| 602 | + delindex = i | ||
| 603 | + break | ||
| 604 | + #END search index | ||
| 605 | + #END for each item | ||
| 606 | + if delindex == -1: | ||
| 607 | + raise IndexError("Item with name %s not found" % name) | ||
| 608 | + #END handle error | ||
| 609 | + #END get index to delete | ||
| 610 | + list.__delitem__(self, delindex) | ||
| 611 | + | ||
| 580 | 612 | ||
| 581 | 613 | class Iterable(object): | |
| 582 | 614 | """Defines an interface for iterable items which is to assure a uniform | |
| Back | FazBrowse Home | New Git URL |
0 commit comments