def test_weak_array_key_map(): def assert_empty_after_gc_collect(container, retries=3): for i in range(retries): if len(container) == 0: return gc.collect() assert len(container) == 0 a = np.ones(42) m = _WeakArrayKeyMap() m.set(a, 'a') assert m.get(a) == 'a' b = a assert m.get(b) == 'a' m.set(b, 'b') assert m.get(a) == 'b' del a gc.collect() assert len(m._data) == 1 assert m.get(b) == 'b' del b assert_empty_after_gc_collect(m._data) c = np.ones(42) m.set(c, 'c') assert len(m._data) == 1 assert m.get(c) == 'c' with raises(KeyError): m.get(np.ones(42)) del c assert_empty_after_gc_collect(m._data) # Check that creating and dropping numpy arrays with potentially the same # object id will not cause the map to get confused. def get_set_get_collect(m, i): a = np.ones(42) with raises(KeyError): m.get(a) m.set(a, i) assert m.get(a) == i return id(a) unique_ids = set([get_set_get_collect(m, i) for i in range(1000)]) if platform.python_implementation() == 'CPython': # On CPython (at least) the same id is often reused many times for the # temporary arrays created under the local scope of the # get_set_get_collect function without causing any spurious lookups / # insertions in the map. assert len(unique_ids) < 100
def test_weak_array_key_map_no_pickling(): m = _WeakArrayKeyMap() with raises(pickle.PicklingError): pickle.dumps(m)