[Zodb-checkins] SVN: ZODB/trunk/src/Z Read-only files can't be removed on Windows. :(

Jim Fulton jim at zope.com
Mon Jun 11 15:07:29 EDT 2007


Log message for revision 76617:
  Read-only files can't be removed on Windows. :(
  
  Added APIs for removing committed blob data that makes files writable
  before removing them and updated code that removes committed blobs or
  blob directories to use them.
  

Changed:
  U   ZODB/trunk/src/ZEO/tests/testZEO.py
  U   ZODB/trunk/src/ZODB/Connection.py
  U   ZODB/trunk/src/ZODB/blob.py
  U   ZODB/trunk/src/ZODB/tests/blob_connection.txt
  U   ZODB/trunk/src/ZODB/tests/blob_importexport.txt
  U   ZODB/trunk/src/ZODB/tests/blob_transaction.txt
  U   ZODB/trunk/src/ZODB/tests/testblob.py

-=-
Modified: ZODB/trunk/src/ZEO/tests/testZEO.py
===================================================================
--- ZODB/trunk/src/ZEO/tests/testZEO.py	2007-06-11 17:55:37 UTC (rev 76616)
+++ ZODB/trunk/src/ZEO/tests/testZEO.py	2007-06-11 19:07:28 UTC (rev 76617)
@@ -30,6 +30,7 @@
 
 # ZODB test support
 import ZODB
+import ZODB.blob
 import ZODB.tests.util
 from ZODB.tests.MinPO import MinPO
 from ZODB.tests.StorageTestBase import zodb_unpickle
@@ -164,7 +165,7 @@
     def tearDown(self):
         self._storage.close()
         os.remove(self._conf_path)
-        shutil.rmtree(self.blob_cache_dir)
+        ZODB.blob.remove_committed_dir(self.blob_cache_dir)
         for server in self._servers:
             forker.shutdown_zeo_server(server)
         if hasattr(os, 'waitpid'):
@@ -616,7 +617,7 @@
             calls.append((oid, serial))
             sendBlob_org(self, oid, serial)
 
-        os.remove(filename)
+        ZODB.blob.remove_committed(filename)
         returns = []
         threads = [
             threading.Thread(

Modified: ZODB/trunk/src/ZODB/Connection.py
===================================================================
--- ZODB/trunk/src/ZODB/Connection.py	2007-06-11 17:55:37 UTC (rev 76616)
+++ ZODB/trunk/src/ZODB/Connection.py	2007-06-11 19:07:28 UTC (rev 76617)
@@ -1245,7 +1245,7 @@
             os.makedirs(targetpath, 0700)
 
         targetname = self._getCleanFilename(oid, serial)
-        rename_or_copy_blob(blobfilename, targetname)
+        rename_or_copy_blob(blobfilename, targetname, chmod=False)
 
     def loadBlob(self, oid, serial):
         """Return the filename where the blob file can be found.

Modified: ZODB/trunk/src/ZODB/blob.py
===================================================================
--- ZODB/trunk/src/ZODB/blob.py	2007-06-11 17:55:37 UTC (rev 76616)
+++ ZODB/trunk/src/ZODB/blob.py	2007-06-11 19:07:28 UTC (rev 76617)
@@ -189,7 +189,7 @@
             target = self._create_uncommitted_file()
             # We need to unlink the freshly created target again
             # to allow link() to do its job
-            os.unlink(target)
+            os.remove(target)
 
         try:
             rename_or_copy_blob(filename, target, chmod=False)
@@ -198,7 +198,7 @@
             # might exist and mark the pointer to the uncommitted file.
             self._p_blob_uncommitted = None
             if os.path.exists(target):
-                os.unlink(target)
+                os.remove(target)
 
             # If there was a file moved aside, bring it back including the
             # pointer to the uncommitted file.
@@ -212,7 +212,7 @@
             if previous_uncommitted:
                 # The relinking worked so we can remove the data that we had 
                 # set aside.
-                os.unlink(target_aside)
+                os.remove(target_aside)
 
             # We changed the blob state and have to make sure we join the
             # transaction.
@@ -448,7 +448,7 @@
             oid, serial = self.dirty_oids.pop()
             clean = self.fshelper.getBlobFilename(oid, serial)
             if os.exists(clean):
-                os.unlink(clean) 
+                remove_committed(clean) 
 
     @non_overridable
     def loadBlob(self, oid, serial):
@@ -487,7 +487,7 @@
                     fn = self.fshelper.getBlobFilename(oid, serial)
                     self.loadSerial(oid, serial)
                 except POSKeyError:
-                    os.unlink(filepath)
+                    remove_committed(filepath)
 
             if not os.listdir(oid_path):
                 shutil.rmtree(oid_path)
@@ -511,9 +511,9 @@
                 latest = files[-1] # depends on ever-increasing tids
                 files.remove(latest)
                 for file in files:
-                    os.unlink(os.path.join(oid_path, file))
+                    remove_committed(os.path.join(oid_path, file))
             else:
-                shutil.rmtree(oid_path)
+                remove_committed_dir(oid_path)
                 continue
 
             if not os.listdir(oid_path):
@@ -630,6 +630,24 @@
         finally:
             file1.close()
             file2.close()
-        os.unlink(f1)
+        remove_committed(f1)
     if chmod:
         os.chmod(f2, stat.S_IREAD)
+
+if sys.platform == 'win32':
+    # On Windows, you can't remove read-only files, so make the
+    # file writable first.
+
+    def remove_committed(filename):
+        os.chmod(filename, stat.S_IWRITE)
+        os.remove(filename)
+
+    def remove_committed_dir(path):
+        for (dirpath, dirnames, filenames) in os.walk(path):
+            for filename in filenames:
+                filename = os.path.join(dirpath, filename)
+                remove_committed(filename)
+        shutil.rmtree(path)
+else:
+    remove_committed = os.remove
+    remove_committed_dir = shutil.rmtree

Modified: ZODB/trunk/src/ZODB/tests/blob_connection.txt
===================================================================
--- ZODB/trunk/src/ZODB/tests/blob_connection.txt	2007-06-11 17:55:37 UTC (rev 76616)
+++ ZODB/trunk/src/ZODB/tests/blob_connection.txt	2007-06-11 19:07:28 UTC (rev 76617)
@@ -76,8 +76,6 @@
 While we are testing this, we don't need the storage directory and
 databases anymore:
 
-    >>> import shutil
-    >>> shutil.rmtree(blob_dir)
     >>> transaction.abort()
     >>> database.close()
     >>> database2.close()

Modified: ZODB/trunk/src/ZODB/tests/blob_importexport.txt
===================================================================
--- ZODB/trunk/src/ZODB/tests/blob_importexport.txt	2007-06-11 17:55:37 UTC (rev 76616)
+++ ZODB/trunk/src/ZODB/tests/blob_importexport.txt	2007-06-11 19:07:28 UTC (rev 76617)
@@ -90,8 +90,9 @@
 
     >>> base_storage1.close()
     >>> base_storage2.close()
-    >>> shutil.rmtree(blob_dir1)
-    >>> shutil.rmtree(blob_dir2)
+    >>> import ZODB.blob
+    >>> ZODB.blob.remove_committed_dir(blob_dir1)
+    >>> ZODB.blob.remove_committed_dir(blob_dir2)
     >>> os.unlink(exportfile)
     >>> os.unlink(storagefile1)
     >>> os.unlink(storagefile1+".index")

Modified: ZODB/trunk/src/ZODB/tests/blob_transaction.txt
===================================================================
--- ZODB/trunk/src/ZODB/tests/blob_transaction.txt	2007-06-11 17:55:37 UTC (rev 76616)
+++ ZODB/trunk/src/ZODB/tests/blob_transaction.txt	2007-06-11 19:07:28 UTC (rev 76617)
@@ -316,8 +316,6 @@
 
 We don't need the storage directory and databases anymore::
 
-    >>> import shutil
-    >>> shutil.rmtree(blob_dir)
     >>> tm1.abort()
     >>> tm2.abort()
     >>> database.close()

Modified: ZODB/trunk/src/ZODB/tests/testblob.py
===================================================================
--- ZODB/trunk/src/ZODB/tests/testblob.py	2007-06-11 17:55:37 UTC (rev 76616)
+++ ZODB/trunk/src/ZODB/tests/testblob.py	2007-06-11 19:07:28 UTC (rev 76617)
@@ -19,6 +19,7 @@
 from ZODB import utils
 from ZODB.FileStorage import FileStorage
 from ZODB.blob import Blob, BlobStorage
+import ZODB.blob
 from ZODB.DB import DB
 import transaction
 
@@ -92,7 +93,7 @@
 
     def tearDown(self):
         os.chdir(self.here)
-        shutil.rmtree(self.test_dir)
+        ZODB.blob.remove_committed_dir(self.test_dir)
 
     def testUndoWithoutPreviousVersion(self):
         base_storage = FileStorage(self.storagefile)



More information about the Zodb-checkins mailing list