[PATCH 5 of 9] opener: add read & write utility methods

Dan Villiom Podlaski Christiansen danchr at gmail.com
Sun Dec 26 05:51:21 CST 2010


# HG changeset patch
# User Dan Villiom Podlaski Christiansen <danchr at gmail.com>
# Date 1293364212 -3600
# Node ID 3b29e00516d7b79cbac6fdd5a9c0e71746bf6df6
# Parent  43f605f94f8570b15d768a58179dd43620520a4c
opener: add read & write utility methods

The two new methods are useful for quickly opening a file for reading
or writing. Unlike 'opener(...).read()', they ensure they the file is
immediately closed without relying on CPython reference counting.

A similar method for reading is added to the opener used by static
HTTP repositories. It doesn't do any actual closing, as the opener
doesn't have access to any underlying files.

diff --git a/mercurial/statichttprepo.py b/mercurial/statichttprepo.py
--- a/mercurial/statichttprepo.py
+++ b/mercurial/statichttprepo.py
@@ -75,6 +75,8 @@ def build_opener(ui, authinfo):
                 raise IOError('Permission denied')
             f = "/".join((p, urllib.quote(path)))
             return httprangereader(f, urlopener)
+        # for compatibility with regular file openers
+        o.read = lambda *args, **kwargs: o(*args, **kwargs).read()
         return o
 
     opener.options = {'nonlazy': 1}
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -879,6 +879,20 @@ class opener(object):
             return
         os.chmod(name, self.createmode & 0666)
 
+    def read(self, *args, **kwargs):
+        fp = self(*args, **kwargs)
+        try:
+            return fp.read()
+        finally:
+            fp.close()
+
+    def write(self, data, *args, **kwargs):
+        fp = self(*args, **kwargs)
+        try:
+            return fp.write(data)
+        finally:
+            fp.close()
+
     def __call__(self, path, mode="r", text=False, atomictemp=False):
         self.auditor(path)
         f = os.path.join(self.base, path)
@@ -953,6 +967,12 @@ class filteropener(object):
     def __call__(self, path, *args, **kwargs):
         return self.orig(self._filter(path), *args, **kwargs)
 
+    def read(self, path, *args, **kwargs):
+        return self._orig.read(self._filter(path), *args, **kwargs)
+
+    def write(self, data, path, *args, **kwargs):
+        return self._orig.write(self._filter(path), *args, **kwargs)
+
 class chunkbuffer(object):
     """Allow arbitrary sized chunks of data to be efficiently read from an
     iterator over chunks of arbitrary size."""


More information about the Mercurial-devel mailing list