Skip to content

Commit 9892c95

Browse files
authored
Merge pull request #1414 from apdavison/prevent-duplicates
Prevent the same object being added more than once to a given list
2 parents 39d48ec + 1d1d8ae commit 9892c95

File tree

1 file changed

+34
-23
lines changed

1 file changed

+34
-23
lines changed

neo/core/objectlist.py

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def __init__(self, allowed_contents, parent=None):
2121
for item in allowed_contents:
2222
assert issubclass(item, BaseNeo)
2323
self.allowed_contents = tuple(allowed_contents)
24-
self.contents = []
24+
self._items = []
2525
self.parent = parent
2626

2727
def _handle_append(self, obj):
@@ -32,6 +32,10 @@ def _handle_append(self, obj):
3232
)
3333
):
3434
raise TypeError(f"Object is a {type(obj)}. It should be one of {self.allowed_contents}.")
35+
36+
if self._contains(obj):
37+
raise ValueError("Cannot add this object because it is already contained within the list")
38+
3539
# set the child-parent relationship
3640
if self.parent:
3741
relationship_name = self.parent.__class__.__name__.lower()
@@ -42,76 +46,83 @@ def _handle_append(self, obj):
4246
# use weakref here? - see https://github.com/NeuralEnsemble/python-neo/issues/684
4347
setattr(obj, relationship_name, self.parent)
4448

49+
def _contains(self, obj):
50+
if self._items is None:
51+
obj_ids = []
52+
else:
53+
obj_ids = [id(item) for item in self._items]
54+
return id(obj) in obj_ids
55+
4556
def __str__(self):
46-
return str(self.contents)
57+
return str(self._items)
4758

4859
def __repr__(self):
49-
return repr(self.contents)
60+
return repr(self._items)
5061

5162
def __add__(self, objects):
5263
# todo: decision: return a list, or a new DataObjectList?
5364
if isinstance(objects, ObjectList):
54-
return self.contents + objects.contents
65+
return self._items + objects._items
5566
else:
56-
return self.contents + objects
67+
return self._items + objects
5768

5869
def __radd__(self, objects):
5970
if isinstance(objects, ObjectList):
60-
return objects.contents + self.contents
71+
return objects._items + self._items
6172
else:
62-
return objects + self.contents
73+
return objects + self._items
6374

6475
def __contains__(self, key):
65-
return key in self.contents
76+
return key in self._items
6677

6778
def __iadd__(self, objects):
6879
for obj in objects:
6980
self._handle_append(obj)
70-
self.contents.extend(objects)
81+
self._items.extend(objects)
7182
return self
7283

7384
def __iter__(self):
74-
return iter(self.contents)
85+
return iter(self._items)
7586

7687
def __getitem__(self, i):
77-
return self.contents[i]
88+
return self._items[i]
7889

7990
def __len__(self):
80-
return len(self.contents)
91+
return len(self._items)
8192

8293
def __setitem__(self, key, value):
83-
self.contents[key] = value
94+
self._items[key] = value
8495

8596
def append(self, obj):
8697
self._handle_append(obj)
87-
self.contents.append(obj)
98+
self._items.append(obj)
8899

89100
def extend(self, objects):
90101
for obj in objects:
91102
self._handle_append(obj)
92-
self.contents.extend(objects)
103+
self._items.extend(objects)
93104

94105
def clear(self):
95-
self.contents = []
106+
self._items = []
96107

97108
def count(self, value):
98-
return self.contents.count(value)
109+
return self._items.count(value)
99110

100111
def index(self, value, start=0, stop=sys.maxsize):
101-
return self.contents.index(value, start, stop)
112+
return self._items.index(value, start, stop)
102113

103114
def insert(self, index, obj):
104115
self._handle_append(obj)
105-
self.contents.insert(index, obj)
116+
self._items.insert(index, obj)
106117

107118
def pop(self, index=-1):
108-
return self.contents.pop(index)
119+
return self._items.pop(index)
109120

110121
def remove(self, value):
111-
return self.contents.remove(value)
122+
return self._items.remove(value)
112123

113124
def reverse(self):
114-
raise self.contents.reverse()
125+
raise self._items.reverse()
115126

116127
def sort(self, *args, key=None, reverse=False):
117-
self.contents.sort(*args, key=key, reverse=reverse)
128+
self._items.sort(*args, key=key, reverse=reverse)

0 commit comments

Comments
 (0)