def setDataForPath(data, path: PathType, value, *, undefined=ImmutableDict()): if not path: if value is Undefined: return undefined else: return sanitize(value) p, path = path[0], path[1:] if type(p) is str: if data is Undefined: data = ImmutableDict() elif type(data) is not ImmutableDict: raise PathElementTypeMismatch(p, data) if value is Undefined and not path: return data.discard(p) elif type(p) is int: if data is Undefined: data = ImmutableList() elif type(data) is not ImmutableList: raise PathElementTypeMismatch(p, data) if value is Undefined and not path: if 0 <= p < len(data): return data[0:p] + data[p + 1:] else: return data if p < 0 or p > len(data): raise IndexError if p == len(data): return data.append(setDataForPath(Undefined, path, value)) else: raise InvalidPathElement(p) return data.set(p, setDataForPath(data.get(p, Undefined), path, value))
def test_getset(self): d = ImmutableDict() with self.assertRaises(KeyError): d["foo"] self.assertEqual(d.get("foo"), None) e = d.set("foo", "bar") with self.assertRaises(KeyError): d["foo"] self.assertEqual(e.get("foo"), "bar")
def test_tuple(self): key1 = ("x" * 10000,) key2 = (("x" * 9999 + "x"),) self.assertTrue(type(key1) is tuple) self.assertTrue(type(key2) is tuple) self.assertEqual(key1, key2) if key1 is key2: self.skipTest( "failed to construct two different tuple objects " "with same value" ) d = ImmutableDict({key1: 123}) self.assertEqual(d.get(key1), 123) self.assertEqual(d.get(key2), 123) self.assertTrue(key1 in d) self.assertTrue(key2 in d)
def test_bytes(self): key1 = b"x" * 10000 key2 = b"x" * 9999 + b"x" self.assertTrue(type(key1) is bytes) self.assertTrue(type(key2) is bytes) self.assertEqual(key1, key2) if key1 is key2: self.skipTest( "failed to construct two different bytes objects " "with same value" ) d = ImmutableDict({key1: 123}) self.assertEqual(d.get(key1), 123) self.assertEqual(d.get(key2), 123) self.assertTrue(key1 in d) self.assertTrue(key2 in d) self.assertFalse(key1.decode("ascii") in d)