Skip to content

Commit 913572c

Browse files
authored
Accept None as a key in pure python module (#42)
1 parent 469ae74 commit 913572c

File tree

2 files changed

+530
-12
lines changed

2 files changed

+530
-12
lines changed

immutables/map.py

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ def map_bitindex(bitmap, bit):
4646
W_EMPTY, W_NEWNODE, W_NOT_FOUND = range(3)
4747
void = object()
4848

49+
class _Unhashable:
50+
__slots__ = ()
51+
__hash__ = None
52+
53+
_NULL = _Unhashable()
54+
del _Unhashable
55+
4956

5057
class BitmapNode:
5158

@@ -70,7 +77,7 @@ def assoc(self, shift, hash, key, val, mutid):
7077
key_or_null = self.array[key_idx]
7178
val_or_node = self.array[val_idx]
7279

73-
if key_or_null is None:
80+
if key_or_null is _NULL:
7481
sub_node, added = val_or_node.assoc(
7582
shift + 5, hash, key, val, mutid)
7683
if val_or_node is sub_node:
@@ -111,12 +118,12 @@ def assoc(self, shift, hash, key, val, mutid):
111118
mutid)
112119

113120
if mutid and mutid == self.mutid:
114-
self.array[key_idx] = None
121+
self.array[key_idx] = _NULL
115122
self.array[val_idx] = sub_node
116123
return self, True
117124
else:
118125
ret = self.clone(mutid)
119-
ret.array[key_idx] = None
126+
ret.array[key_idx] = _NULL
120127
ret.array[val_idx] = sub_node
121128
return ret, True
122129

@@ -153,7 +160,7 @@ def find(self, shift, hash, key):
153160
key_or_null = self.array[key_idx]
154161
val_or_node = self.array[val_idx]
155162

156-
if key_or_null is None:
163+
if key_or_null is _NULL:
157164
return val_or_node.find(shift + 5, hash, key)
158165

159166
if key == key_or_null:
@@ -173,7 +180,7 @@ def without(self, shift, hash, key, mutid):
173180
key_or_null = self.array[key_idx]
174181
val_or_node = self.array[val_idx]
175182

176-
if key_or_null is None:
183+
if key_or_null is _NULL:
177184
res, sub_node = val_or_node.without(shift + 5, hash, key, mutid)
178185

179186
if res is W_EMPTY:
@@ -182,7 +189,7 @@ def without(self, shift, hash, key, mutid):
182189
elif res is W_NEWNODE:
183190
if (type(sub_node) is BitmapNode and
184191
sub_node.size == 2 and
185-
sub_node.array[0] is not None):
192+
sub_node.array[0] is not _NULL):
186193

187194
if mutid and mutid == self.mutid:
188195
self.array[key_idx] = sub_node.array[0]
@@ -231,7 +238,7 @@ def keys(self):
231238
for i in range(0, self.size, 2):
232239
key_or_null = self.array[i]
233240

234-
if key_or_null is None:
241+
if key_or_null is _NULL:
235242
val_or_node = self.array[i + 1]
236243
yield from val_or_node.keys()
237244
else:
@@ -242,7 +249,7 @@ def values(self):
242249
key_or_null = self.array[i]
243250
val_or_node = self.array[i + 1]
244251

245-
if key_or_null is None:
252+
if key_or_null is _NULL:
246253
yield from val_or_node.values()
247254
else:
248255
yield val_or_node
@@ -252,7 +259,7 @@ def items(self):
252259
key_or_null = self.array[i]
253260
val_or_node = self.array[i + 1]
254261

255-
if key_or_null is None:
262+
if key_or_null is _NULL:
256263
yield from val_or_node.items()
257264
else:
258265
yield key_or_null, val_or_node
@@ -269,8 +276,8 @@ def dump(self, buf, level): # pragma: no cover
269276

270277
pad = ' ' * (level + 2)
271278

272-
if key_or_null is None:
273-
buf.append(pad + 'None:')
279+
if key_or_null is _NULL:
280+
buf.append(pad + 'NULL:')
274281
val_or_node.dump(buf, level + 2)
275282
else:
276283
buf.append(pad + '{!r}: {!r}'.format(key_or_null, val_or_node))
@@ -328,7 +335,7 @@ def assoc(self, shift, hash, key, val, mutid):
328335

329336
else:
330337
new_node = BitmapNode(
331-
2, map_bitpos(self.hash, shift), [None, self], mutid)
338+
2, map_bitpos(self.hash, shift), [_NULL, self], mutid)
332339
return new_node.assoc(shift, hash, key, val, mutid)
333340

334341
def without(self, shift, hash, key, mutid):

0 commit comments

Comments
 (0)