Skip to content

Commit 57a8aa5

Browse files
committed
FIX: Make GiftiMetaData.data a list proxy
The way to modify a metadata object used to be manipulating the .data list. Proxy calls to the list to ensure updates to the dict-like object now.
1 parent a7cd91f commit 57a8aa5

File tree

1 file changed

+72
-3
lines changed

1 file changed

+72
-3
lines changed

nibabel/gifti/gifti.py

+72-3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,42 @@
2626
from ..deprecated import deprecate_with_version
2727

2828

29+
class _GiftiMDList(list):
30+
"""List view of GiftiMetaData object that will translate most operations"""
31+
def __init__(self, metadata):
32+
self._md = metadata
33+
super().__init__(
34+
GiftiNVPairs._private_init(k, v, metadata)
35+
for k, v in metadata.items()
36+
)
37+
38+
def append(self, nvpair, /):
39+
self._md[nvpair.name] = nvpair.value
40+
super().append(nvpair)
41+
42+
def clear(self, /):
43+
super().clear()
44+
self._md.clear()
45+
46+
def extend(self, iterable, /):
47+
for nvpair in iterable:
48+
self.append(nvpair)
49+
50+
def insert(self, index, nvpair, /):
51+
self._md[nvpair.name] = nvpair.value
52+
super().insert(index, nvpair)
53+
54+
def pop(self, index=-1, /):
55+
nvpair = super().pop(index)
56+
nvpair._container = None
57+
del self._md[nvpair.name]
58+
return nvpair
59+
60+
def remove(self, nvpair, /):
61+
super().remove(nvpair)
62+
del self._md[nvpair.name]
63+
64+
2965
class GiftiMetaData(CaretMetaData):
3066
""" A sequence of GiftiNVPairs containing metadata for a gifti data array
3167
"""
@@ -76,7 +112,7 @@ def data(self):
76112
warnings.warn(
77113
"GiftiMetaData.data will be a dict in NiBabel 6.0.",
78114
FutureWarning, stacklevel=2)
79-
return [GiftiNVPairs(k, v) for k, v in self._data.items()]
115+
return _GiftiMDList(self)
80116

81117
@classmethod
82118
@deprecate_with_version(
@@ -114,8 +150,41 @@ class GiftiNVPairs:
114150
value : str
115151
"""
116152
def __init__(self, name=u'', value=u''):
117-
self.name = name
118-
self.value = value
153+
self._name = name
154+
self._value = value
155+
self._container = None
156+
157+
@classmethod
158+
def _private_init(cls, name, value, md):
159+
self = cls(name, value)
160+
self._container = md
161+
return self
162+
163+
def __eq__(self, other):
164+
if not isinstance(other, GiftiNVPairs):
165+
return NotImplemented
166+
return self.name == other.name and self.value == other.value
167+
168+
@property
169+
def name(self):
170+
return self._name
171+
172+
@name.setter
173+
def name(self, key):
174+
oldname = self._name
175+
if self._container:
176+
self._container[key] = self._container.pop(self._name)
177+
self._name = key
178+
179+
@property
180+
def value(self):
181+
return self._value
182+
183+
@value.setter
184+
def value(self, val):
185+
if self._container:
186+
self._container[self._name] = val
187+
self._value = val
119188

120189

121190
class GiftiLabelTable(xml.XmlSerializable):

0 commit comments

Comments
 (0)