bmaptool: assign user-friendly names to file objects
authorArtem Bityutskiy <artem.bityutskiy@intel.com>
Mon, 6 May 2013 09:29:22 +0000 (12:29 +0300)
committerArtem Bityutskiy <artem.bityutskiy@intel.com>
Mon, 6 May 2013 14:58:37 +0000 (17:58 +0300)
Just like many things in python, BmapCopy assumes that file-like objects'
'name' attribute contains something user-frienly. And this is the case in most
of the cases, except one case. If the file object was created using
'os.fdopen()', the name will be '<fdopen>', instead of something user-friendly.
And bmaptool uses 'os.fdopen()' when opening block devices, because we need to
use special open flags. This results in poor error messages like this:

bmaptool: ERROR: wrote 187980 blocks from image
  'ivi-wayland-tizen-2.0a_20130501.1-sdb.raw.bz2' to '<fdopen>' ...

And the problem is that you cannot change the name - it is a read-only
attribute. This problem will probably be resolved in python 3, but not in 2.x,
see http://bugs.python.org/issue1625576

This patch works-around the problem by creating own simple dummy class which
overrides the name.

Change-Id: Ia6c8565c414c5e57d294d83c0fe5758e7b5aa518
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@intel.com>
bmaptool

index c1fd488..395c3d5 100755 (executable)
--- a/bmaptool
+++ b/bmaptool
@@ -32,6 +32,10 @@ all 4GiB of data. We say that it is a bit more than 100MiB because things like
 file-system meta-data (inode tables, superblocks, etc), partition table, etc
 also contribute to the mapped blocks and are also copied. """
 
+# Disable the following pylint recommendations:
+#   * Too few public methods (R0903)
+# pylint: disable=R0903
+
 VERSION = "2.2"
 
 import argparse
@@ -47,6 +51,18 @@ def copy_command_open_blkdev(path, log):
     """ Open a block device specified by 'path' in exclusive mode. Returns
     opened file object. """
 
+    class NamedFile:
+        """ This simple class allows us to override the 'name' attribute of a
+        file object. The problem is that 'os.fdopen()' sets the name to
+        "<fdopen>", which is not very user-friendly. """
+
+        def __init__(self, file_obj, name):
+            self._file_obj = file_obj
+            self.name = name
+
+        def __getattr__(self, name):
+            return getattr(self._file_obj, name)
+
     try:
         descriptor = os.open(path, os.O_WRONLY | os.O_EXCL)
     except OSError as err:
@@ -62,7 +78,7 @@ def copy_command_open_blkdev(path, log):
         log.error("cannot open block device '%s': %s" % (path, err))
         raise SystemExit(1)
 
-    return file_obj
+    return NamedFile(file_obj, path)
 
 def find_and_open_bmap(image_path):
     """ When the user does not specify the bmap file, we try to find it at the