• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

shakefu / pytool / 15523286677

08 Jun 2025 10:44PM UTC coverage: 93.87% (+0.8%) from 93.098%
15523286677

push

github

shakefu
ci: removed pip cache, superceded by uv's cache

1669 of 1778 relevant lines covered (93.87%)

3.75 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.15
/pytool/proxy.py
1
"""
2
This module contains implmentations of proxy-list and proxy-dictionary objects.
3
"""
4

5
# flake8: noqa
6
import collections.abc as abc
4✔
7

8

9
def cmp(a, b):
4✔
10
    return (a > b) - (a < b)
×
11

12

13
class ListProxy(abc.MutableSequence):
4✔
14
    """
15
    Proxies all methods for a list instance. This is useful when you want to
16
    modify a list's behavior without copying the list.
17

18
    Methods which do not mutate a list, and instead return a new list will
19
    return a `list` instance rather than a `ListProxy` instance.
20

21
    :param data: A list or list-like object (implements all the \
22
            :class:`collections.MutableSequence` methods)
23

24
    .. versionadded:: 2.2
25

26
    :note: If you intend to use a subclass which modifies the apparent indices
27
           or values of this class with :func:`pytool.json.as_json`, remember
28
           to override :meth:`for_json` to produce the data you desire.
29

30
    Example::
31

32
        from pytool.proxy import ListProxy
33

34
        class SquaredList(ListProxy):
35
            def __setitem__(self, index, value):
36
                if isinstance(value, int):
37
                    value *= value
38
                super(SquaredList, self).__setitem__(index, value)
39

40
        my_list = range(5)
41
        my_proxy = SquaredList(my_list)
42
        my_proxy[3] = 5
43

44
        my_proxy[3] # 25
45
        my_list[3] # 25
46

47
    """
48

49
    def __init__(self, data):
4✔
50
        self._data = data
4✔
51

52
    def __repr__(self):
4✔
53
        return repr(self._data)
4✔
54

55
    def __lt__(self, other):
4✔
56
        return self._data < self.__cast(other)
4✔
57

58
    def __le__(self, other):
4✔
59
        return self._data <= self.__cast(other)
4✔
60

61
    def __eq__(self, other):
4✔
62
        return self._data == self.__cast(other)
4✔
63

64
    def __ne__(self, other):
4✔
65
        return self._data != self.__cast(other)
4✔
66

67
    def __gt__(self, other):
4✔
68
        return self._data > self.__cast(other)
4✔
69

70
    def __ge__(self, other):
4✔
71
        return self._data >= self.__cast(other)
4✔
72

73
    def __cast(self, other):
4✔
74
        if isinstance(other, ListProxy):
4✔
75
            return other._data
4✔
76
        else:
77
            return other
4✔
78

79
    def __cmp__(self, other):
4✔
80
        return cmp(self._data, self.__cast(other))
×
81

82
    __hash__ = None  # Mutable sequence, so not hashable
4✔
83

84
    def __contains__(self, item):
4✔
85
        return item in self._data
4✔
86

87
    def __len__(self):
4✔
88
        return len(self._data)
4✔
89

90
    def __getitem__(self, i):
4✔
91
        return self._data[i]
4✔
92

93
    def __setitem__(self, i, item):
4✔
94
        self._data[i] = item
4✔
95

96
    def __delitem__(self, i):
4✔
97
        del self._data[i]
4✔
98

99
    def __getslice__(self, i, j):
4✔
100
        i = max(i, 0)
×
101
        j = max(j, 0)
×
102
        return self._data[i:j]
×
103

104
    def __setslice__(self, i, j, other):
4✔
105
        i = max(i, 0)
×
106
        j = max(j, 0)
×
107
        if isinstance(other, ListProxy):
×
108
            self._data[i:j] = other._data
×
109
        elif isinstance(other, type(self._data)):
×
110
            self._data[i:j] = other
×
111
        else:
112
            self._data[i:j] = list(other)
×
113

114
    def __delslice__(self, i, j):
4✔
115
        i = max(i, 0)
×
116
        j = max(j, 0)
×
117
        del self._data[i:j]
×
118

119
    def __add__(self, other):
4✔
120
        if isinstance(other, ListProxy):
4✔
121
            return self._data + other._data
4✔
122
        elif isinstance(other, type(self._data)):
4✔
123
            return self._data + other
4✔
124
        else:
125
            return self._data + list(other)
4✔
126

127
    def __radd__(self, other):
4✔
128
        if isinstance(other, ListProxy):
4✔
129
            return other._data + self._data
4✔
130
        elif isinstance(other, type(self._data)):
4✔
131
            return other + self._data
4✔
132
        else:
133
            return list(other) + self._data
4✔
134

135
    def __iadd__(self, other):
4✔
136
        if isinstance(other, ListProxy):
4✔
137
            self._data += other._data
4✔
138
        elif isinstance(other, type(self._data)):
4✔
139
            self._data += other
4✔
140
        else:
141
            self._data += list(other)
4✔
142
        return self
4✔
143

144
    def __mul__(self, n):
4✔
145
        return self._data * n
4✔
146

147
    __rmul__ = __mul__
4✔
148

149
    def __imul__(self, n):
4✔
150
        self._data *= n
4✔
151
        return self
4✔
152

153
    def append(self, item):
4✔
154
        self._data.append(item)
4✔
155

156
    def insert(self, i, item):
4✔
157
        self._data.insert(i, item)
4✔
158

159
    def pop(self, i=-1):
4✔
160
        return self._data.pop(i)
4✔
161

162
    def remove(self, item):
4✔
163
        self._data.remove(item)
×
164

165
    def count(self, item):
4✔
166
        return self._data.count(item)
×
167

168
    def index(self, item, *args):
4✔
169
        return self._data.index(item, *args)
×
170

171
    def reverse(self):
4✔
172
        self._data.reverse()
×
173

174
    def sort(self, *args, **kwds):
4✔
175
        self._data.sort(*args, **kwds)
×
176

177
    def extend(self, other):
4✔
178
        if isinstance(other, ListProxy):
4✔
179
            self._data.extend(other._data)
4✔
180
        else:
181
            self._data.extend(other)
4✔
182

183
    def for_json(self):
4✔
184
        return self._data
4✔
185

186

187
class DictProxy(abc.MutableMapping):
4✔
188
    """
189
    Proxies all methods for a dict instance.
190

191
    This is useful when you want to modify a dictionary's behavior through
192
    subclassing without copying the dictionary or if you want to be able to
193
    modify the original dictionary.
194

195
    :param data: A dict or dict-like object (implements all the \
196
        :class:`collections.MutableMapping` methods)
197

198
    .. versionadded:: 2.2
199

200
    :note: If you intend to use a subclass which modifies the apparent keys
201
           or values of this class with :func:`pytool.json.as_json`, remember
202
           to override :meth:`for_json` to produce the data you desire.
203

204
    Example::
205

206
        from pytool.proxy import DictProxy
207

208
        class SquaredDict(DictProxy):
209
            def __getitem__(self, key):
210
                value = super(SquaredDict, self).__getitem__(key)
211
                if isinstance(value, int):
212
                    value *= value
213
                return value
214

215
        my_dict = {}
216
        my_proxy = SquaredDict(my_dict)
217
        my_proxy['val'] = 5
218

219
        my_proxy['val'] # 25
220
        my_dict['val'] # 5
221

222
    """
223

224
    def __init__(self, data):
4✔
225
        self._data = data
4✔
226

227
    def __repr__(self):
4✔
228
        return repr(self._data)
4✔
229

230
    def __cmp__(self, other):
4✔
231
        if isinstance(other, DictProxy):
×
232
            return cmp(self._data, other._data)
×
233
        else:
234
            return cmp(self._data, other)
×
235

236
    __hash__ = None  # Avoid Py3k warning
4✔
237

238
    def __len__(self):
4✔
239
        return len(self._data)
×
240

241
    def __getitem__(self, key):
4✔
242
        if key in self._data:
4✔
243
            return self._data[key]
4✔
244
        if hasattr(self.__class__, "__missing__"):
4✔
245
            return self.__class__.__missing__(self, key)
4✔
246
        raise KeyError(key)
4✔
247

248
    def __setitem__(self, key, item):
4✔
249
        self._data[key] = item
4✔
250

251
    def __delitem__(self, key):
4✔
252
        del self._data[key]
4✔
253

254
    def clear(self):
4✔
255
        self._data.clear()
4✔
256

257
    def copy(self):
4✔
258
        if self.__class__ is DictProxy:
4✔
259
            return self._data.copy()
4✔
260
        import copy
4✔
261

262
        data = self._data
4✔
263
        try:
4✔
264
            self._data = {}
4✔
265
            c = copy.copy(self)
4✔
266
        finally:
267
            self._data = data
4✔
268
        c.update(self)
4✔
269
        return c
4✔
270

271
    def keys(self):
4✔
272
        return self._data.keys()
×
273

274
    def items(self):
4✔
275
        return self._data.items()
4✔
276

277
    def iteritems(self):
4✔
278
        return self._data.iteritems()
×
279

280
    def iterkeys(self):
4✔
281
        return self._data.iterkeys()
×
282

283
    def itervalues(self):
4✔
284
        return self._data.itervalues()
×
285

286
    def values(self):
4✔
287
        return self._data.values()
×
288

289
    def has_key(self, key):
4✔
290
        return key in self._data
×
291

292
    def update(self, other=None, **kwargs):
4✔
293
        if other is None:
4✔
294
            pass
4✔
295
        elif isinstance(other, DictProxy):
4✔
296
            self._data.update(other._data)
4✔
297
        elif isinstance(other, type({})) or not hasattr(other, "items"):
4✔
298
            self._data.update(other)
4✔
299
        else:
300
            for k, v in other.items():
4✔
301
                self[k] = v
4✔
302
        if len(kwargs):
4✔
303
            self._data.update(kwargs)
4✔
304

305
    def get(self, key, failobj=None):
4✔
306
        if key not in self:
4✔
307
            return failobj
4✔
308
        return self[key]
4✔
309

310
    def setdefault(self, key, failobj=None):
4✔
311
        if key not in self:
4✔
312
            self[key] = failobj
4✔
313
        return self[key]
4✔
314

315
    def pop(self, key, *args):
4✔
316
        return self._data.pop(key, *args)
4✔
317

318
    def popitem(self):
4✔
319
        return self._data.popitem()
4✔
320

321
    def __contains__(self, key):
4✔
322
        return key in self._data
4✔
323

324
    def __iter__(self):
4✔
325
        return iter(self._data)
4✔
326

327
    def for_json(self):
4✔
328
        return self._data
4✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc