Repository: blaze/blaze

Issue:
blz storage r/w mode is wrong
if you run the array_creation.py script in samples, you will write data to the specified blz location

however the repr of that storage says mode='r', even though it clearly isn't, because we just wrote some data to it



Discussion:

Resolving patch:
diff --git a/blaze/io/storage.py b/blaze/io/storage.py
--- a/blaze/io/storage.py
+++ b/blaze/io/storage.py
@@ -86,10 +86,10 @@ def permanent(self):
 
     @property
     def path(self):
-        """ returns a blz path for a given uri """
+        """Returns a blz path for a given uri."""
         return self._path
 
-    def __init__(self, uri, mode='r', permanent=True, format=None):
+    def __init__(self, uri, mode='a', permanent=True, format=None):
         if not isinstance(uri, str):
             raise ValueError("`uri` must be a string.")
         self._uri = uri
@@ -245,13 +245,8 @@ def drop(persist):
     persist = _persist_convert(persist)
 
     if persist.format == 'blz':
-        try:
-            blz.open(rootdir=persist.path)
-            from shutil import rmtree
-            rmtree(persist.path)
-        except RuntimeError:
-            # Maybe BLZ should throw other exceptions for this!
-            raise Exception("No data set at uri '%s'" % persist.uri)
+        from shutil import rmtree
+        rmtree(persist.path)
     elif persist.format in ('csv', 'json', 'hdf5'):
         import os
         os.unlink(persist.path)
diff --git a/blaze/objects/constructors.py b/blaze/objects/constructors.py
--- a/blaze/objects/constructors.py
+++ b/blaze/objects/constructors.py
@@ -104,10 +104,13 @@ def array(obj, dshape=None, caps={'efficient-write': True},
         if inspect.isgenerator(obj):
             # TODO: Generator logic can go inside barray
             dd = BLZDataDescriptor(blz.barray(obj, dtype=dt, count=-1,
-                                              rootdir=storage.path))
+                                              rootdir=storage.path,
+                                              mode=storage.mode))
         else:
             dd = BLZDataDescriptor(
-                blz.barray(obj, dtype=dt, rootdir=storage.path))
+                blz.barray(obj, dtype=dt,
+                           rootdir=storage.path,
+                           mode=storage.mode))
     elif 'efficient-write' in caps and caps['efficient-write'] is True:
         # In-Memory array
         if dshape is None:
@@ -175,7 +178,8 @@ def empty(dshape, caps={'efficient-write': True}, storage=None):
     if storage is not None:
         shape, dt = to_numpy(dshape)
         dd = BLZDataDescriptor(blz.zeros(shape, dt,
-                                         rootdir=storage.path))
+                                         rootdir=storage.path,
+                                         mode=storage.mode))
     elif 'efficient-write' in caps:
         dd = DyNDDataDescriptor(nd.empty(str(dshape)))
     elif 'compress' in caps:
@@ -208,7 +212,8 @@ def zeros(dshape, caps={'efficient-write': True}, storage=None):
     if storage is not None:
         shape, dt = to_numpy(dshape)
         dd = BLZDataDescriptor(blz.zeros(shape, dt,
-                                         rootdir=storage.path))
+                                         rootdir=storage.path,
+                                         mode=storage.mode))
     elif 'efficient-write' in caps:
         # TODO: Handle var dimension properly (raise exception?)
         dyndarr = nd.empty(str(dshape))
@@ -245,7 +250,8 @@ def ones(dshape, caps={'efficient-write': True}, storage=None):
     if storage is not None:
         shape, dt = to_numpy(dshape)
         dd = BLZDataDescriptor(blz.ones(shape, dt,
-                                        rootdir=storage.path))
+                                        rootdir=storage.path,
+                                        mode=storage.mode))
     elif 'efficient-write' in caps:
         # TODO: Handle var dimension properly (raise exception?)
         dyndarr = nd.empty(str(dshape))
diff --git a/samples/basics/array_creation.py b/samples/basics/array_creation.py
--- a/samples/basics/array_creation.py
+++ b/samples/basics/array_creation.py
@@ -128,12 +128,13 @@ def maybe_remove(persist):
 
 # Create an empty array on-disk
 dname = 'blz://persisted.blz'
-store = blaze.Storage(dname)
+store = blaze.Storage(dname, mode='a')
 maybe_remove(store)
 p = blaze.zeros('0 * float64', storage=store)
 # Feed it with some data
 blaze.append(p, range(10))
 
+print(repr(store))
 print('Before re-opening:', p)
 
 # Re-open the dataset in URI


Test patch:
diff --git a/blaze/tests/test_array_creation.py b/blaze/tests/test_array_creation.py
--- a/blaze/tests/test_array_creation.py
+++ b/blaze/tests/test_array_creation.py
@@ -125,6 +125,7 @@ def test_create_record(self):
         aflt = a.flt
         self.assertEqual(dd_as_py(aflt._data), [3.5, 2.25])
 
+
 class TestPersistent(MayBeUriTest, unittest.TestCase):
 
     uri = True
@@ -155,12 +156,21 @@ def test_append2(self):
 
     def test_open(self):
         persist = blaze.Storage(self.rooturi, format="blz")
+        self.assertTrue(persist.mode == 'a')
         a = blaze.ones('0 * float64', storage=persist)
         append(a,range(10))
         # Re-open the dataset in URI
+        persist = blaze.Storage(self.rooturi, format="blz", mode='r')
+        self.assertTrue(persist.mode == 'r')
         a2 = blaze.from_blz(persist)
         self.assertTrue(isinstance(a2, blaze.Array))
         self.assertEqual(dd_as_py(a2._data), list(range(10)))
 
+    def test_wrong_open_mode(self):
+        persist = blaze.Storage(self.rooturi, format="blz", mode='r')
+        self.assertRaises(IOError, blaze.ones,
+                          '10 * float64', storage=persist)
+
+
 if __name__ == '__main__':
     unittest.main(verbosity=2)