[bmap-tools] [PATCH 6/9] TransRead: provide user-friendly error message for pbzip2
Artem Bityutskiy
dedekind1 at gmail.com
Tue Jan 28 08:45:58 EST 2014
From: Artem Bityutskiy <artem.bityutskiy at intel.com>
If the bz2 file is a multi-stream archive and the 'bz2file' library was not
found, we cannot read the file and just fail with a scary traceback. This patch
adds a nice user-friendly message which suggests what to do in this case.
Change-Id: I41971a58fbe9712162b3ffb294c6f5e0272f34b9
Signed-off-by: Artem Bityutskiy <artem.bityutskiy at intel.com>
---
bmaptools/TransRead.py | 47 ++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 40 insertions(+), 7 deletions(-)
diff --git a/bmaptools/TransRead.py b/bmaptools/TransRead.py
index 950ab7c..89f63f9 100644
--- a/bmaptools/TransRead.py
+++ b/bmaptools/TransRead.py
@@ -239,6 +239,8 @@ class TransRead(object):
self.size = None
# Type of the compression of the file
self.compression_type = 'none'
+ # Whether the 'bz2file' PyPI module was found
+ self.bz2file_found = False
# Whether the file is behind an URL
self.is_url = False
@@ -322,6 +324,7 @@ class TransRead(object):
try:
import bz2file
+ self.bz2file_found = True
f_obj = bz2file.BZ2File(self._f_objs[-1], 'r')
except ImportError:
import bz2
@@ -524,6 +527,22 @@ class TransRead(object):
self.is_url = True
self._f_objs.append(f_obj)
+ def _get_pbzip2_error_string(self):
+ """
+ This is a helper function which returns a string which describes the
+ problem of decompressing multi-stream bzip2 archives.
+ """
+
+ res = "file \"%res\" is a multi-stream bz2 archive " % self.name
+ res += "(pbzip2) and it is not supported by python 2.x\n"
+ res += "Please, install the \"bz2file\" python library from PyPI to "
+ res += "support multi-stream archives. Here is an example of how this "
+ res += "could be done in Fedora:\n"
+ res += "$ yum install python-pip\n"
+ res += "$ pip install bz2file"
+
+ return res
+
def read(self, size=-1):
"""
Read the data from the file or URL and and uncompress it on-the-fly if
@@ -533,18 +552,32 @@ class TransRead(object):
if size < 0:
size = 0xFFFFFFFFFFFFFFFF
- buf = self._f_objs[-1].read(size)
- self._pos += len(buf)
+ try:
+ buf = self._f_objs[-1].read(size)
+ except EOFError:
+ if self.compression_type == 'bzip2' and not self.bz2file_found:
+ # The file is probably compressed with 'pbzip2'
+ raise Error(self._get_pbzip2_error_string())
+ else:
+ raise
+ self._pos += len(buf)
return buf
def seek(self, offset, whence=os.SEEK_SET):
"""The 'seek()' method, similar to the one file objects have."""
- if self._force_fake_seek or not hasattr(self._f_objs[-1], "seek"):
- self._pos = _fake_seek_forward(self._f_objs[-1], self._pos,
- offset, whence)
- else:
- self._f_objs[-1].seek(offset, whence)
+ try:
+ if self._force_fake_seek or not hasattr(self._f_objs[-1], "seek"):
+ self._pos = _fake_seek_forward(self._f_objs[-1], self._pos,
+ offset, whence)
+ else:
+ self._f_objs[-1].seek(offset, whence)
+ except EOFError:
+ if self.compression_type == 'bzip2' and not self.bz2file_found:
+ # The file is probably compressed with 'pbzip2'
+ raise Error(self._get_pbzip2_error_string())
+ else:
+ raise
def tell(self):
"""The 'tell()' method, similar to the one file objects have."""
--
1.8.3.1
More information about the Bmap-tools
mailing list