diff --git a/xbob/io/__init__.py b/xbob/io/__init__.py
index 41e67e055a69b0f8f90f64ba69efac99b808fc2a..5eba6567e1c2beb4b6ba7ca175bde9354f7dc7cd 100644
--- a/xbob/io/__init__.py
+++ b/xbob/io/__init__.py
@@ -1,4 +1,4 @@
-from ._library import __version__, __api_version__, File, VideoReader, VideoWriter
+from ._library import __version__, __api_version__, File, VideoReader, VideoWriter, HDF5File
 from . import _externals
 
 import os
diff --git a/xbob/io/file.cpp b/xbob/io/file.cpp
index c8245899e0bfa1524b5c91e6390070fe10f6e0c6..867d5be82ba16a8cd2c071ed7e2086b0e8fa8dcd 100644
--- a/xbob/io/file.cpp
+++ b/xbob/io/file.cpp
@@ -89,7 +89,7 @@ static int PyBobIoFile_Init(PyBobIoFileObject* self, PyObject *args, PyObject* k
     }
   }
   catch (std::exception& e) {
-    PyErr_Format(PyExc_RuntimeError, "cannot open file `%s' with mode `%c': %s", filename, mode, e.what());
+    PyErr_SetString(PyExc_RuntimeError, e.what());
     return -1;
   }
   catch (...) {
@@ -224,7 +224,7 @@ static PyObject* PyBobIoFile_GetIndex (PyBobIoFileObject* self, Py_ssize_t i) {
     self->f->read(skin, i);
   }
   catch (std::exception& e) {
-    if (!PyErr_Occurred()) PyErr_Format(PyExc_RuntimeError, "caught std::exception while reading object #%" PY_FORMAT_SIZE_T "d from file `%s': %s", i, self->f->filename().c_str(), e.what());
+    if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, e.what());
     Py_DECREF(retval);
     return 0;
   }
@@ -281,7 +281,7 @@ static PyObject* PyBobIoFile_GetSlice (PyBobIoFileObject* self, PySliceObject* s
       self->f->read(skin, i);
     }
     catch (std::exception& e) {
-      if (!PyErr_Occurred()) PyErr_Format(PyExc_RuntimeError, "caught std::exception while reading object #%" PY_FORMAT_SIZE_T "d from file `%s': %s", i, self->f->filename().c_str(), e.what());
+      if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, e.what());
       Py_DECREF(retval);
       Py_DECREF(item);
       return 0;
@@ -368,7 +368,7 @@ static PyObject* PyBobIoFile_Read(PyBobIoFileObject* self, PyObject *args, PyObj
     return 0;
   }
   catch (std::exception& e) {
-    if (!PyErr_Occurred()) PyErr_Format(PyExc_RuntimeError, "caught std::exception while reading all contents of file `%s': %s", self->f->filename().c_str(), e.what());
+    if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, e.what());
     Py_DECREF(retval);
     return 0;
   }
@@ -421,7 +421,7 @@ static PyObject* PyBobIoFile_Write(PyBobIoFileObject* self, PyObject *args, PyOb
     return 0;
   }
   catch (std::exception& e) {
-    if (!PyErr_Occurred()) PyErr_Format(PyExc_RuntimeError, "caught std::exception while writing to file `%s': %s", self->f->filename().c_str(), e.what());
+    if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, e.what());
     return 0;
   }
   catch (...) {
@@ -474,7 +474,7 @@ static PyObject* PyBobIoFile_Append(PyBobIoFileObject* self, PyObject *args, PyO
     return 0;
   }
   catch (std::exception& e) {
-    if (!PyErr_Occurred()) PyErr_Format(PyExc_RuntimeError, "caught std::exception while appending to file `%s': %s", self->f->filename().c_str(), e.what());
+    if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, e.what());
     return 0;
   }
   catch (...) {
diff --git a/xbob/io/hdf5.cpp b/xbob/io/hdf5.cpp
index 1a4d62e3f2d5c1bde32502217620924626f09c83..9c57816a55c42a9e636767c9f4283da937a7316a 100644
--- a/xbob/io/hdf5.cpp
+++ b/xbob/io/hdf5.cpp
@@ -83,7 +83,7 @@ static int PyBobIoHDF5File_Init(PyBobIoHDF5FileObject* self,
   static char** kwlist = const_cast<char**>(const_kwlist);
 
   char* filename = 0;
-  char mode = 0;
+  char mode = 'r';
   if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|c", kwlist, &filename, &mode))
     return -1;
 
@@ -96,7 +96,7 @@ static int PyBobIoHDF5File_Init(PyBobIoHDF5FileObject* self,
     self->f.reset(new bob::io::HDF5File(filename, mode));
   }
   catch (std::exception& e) {
-    PyErr_Format(PyExc_RuntimeError, "cannot open file `%s' with mode `%c': %s", filename, mode, e.what());
+    PyErr_SetString(PyExc_RuntimeError, e.what());
     return -1;
   }
   catch (...) {
@@ -130,7 +130,7 @@ static PyObject* PyBobIoHDF5File_ChangeDirectory(PyBobIoHDF5FileObject* self, Py
     self->f->cd(path);
   }
   catch (std::exception& e) {
-    PyErr_Format(PyExc_RuntimeError, "cannot change directory to `%s' in file `%s': %s", path, self->f->filename().c_str(), e.what());
+    PyErr_SetString(PyExc_RuntimeError, e.what());
     return 0;
   }
   catch (...) {
@@ -178,7 +178,7 @@ static PyObject* PyBobIoHDF5File_HasGroup(PyBobIoHDF5FileObject* self, PyObject
     if (self->f->hasGroup(path)) Py_RETURN_TRUE;
   }
   catch (std::exception& e) {
-    PyErr_Format(PyExc_RuntimeError, "could not check for group `%s' in file `%s': %s", path, self->f->filename().c_str(), e.what());
+    PyErr_SetString(PyExc_RuntimeError, e.what());
     return 0;
   }
   catch (...) {
@@ -219,7 +219,7 @@ static PyObject* PyBobIoHDF5File_CreateGroup(PyBobIoHDF5FileObject* self, PyObje
     self->f->createGroup(path);
   }
   catch (std::exception& e) {
-    PyErr_Format(PyExc_RuntimeError, "could not create group `%s' in file `%s': %s", path, self->f->filename().c_str(), e.what());
+    PyErr_SetString(PyExc_RuntimeError, e.what());
     return 0;
   }
   catch (...) {
@@ -260,7 +260,7 @@ static PyObject* PyBobIoHDF5File_HasDataset(PyBobIoHDF5FileObject* self, PyObjec
     if (self->f->contains(key)) Py_RETURN_TRUE;
   }
   catch (std::exception& e) {
-    PyErr_Format(PyExc_RuntimeError, "could not check for dataset `%s' in file `%s': %s", key, self->f->filename().c_str(), e.what());
+    PyErr_SetString(PyExc_RuntimeError, e.what());
     return 0;
   }
   catch (...) {
@@ -396,7 +396,7 @@ static PyObject* PyBobIoHDF5File_Describe(PyBobIoHDF5FileObject* self, PyObject
     }
   }
   catch (std::exception& e) {
-    PyErr_Format(PyExc_RuntimeError, "could not get description for dataset `%s' in file `%s': %s", key, self->f->filename().c_str(), e.what());
+    PyErr_SetString(PyExc_RuntimeError, e.what());
   }
   catch (...) {
     PyErr_Format(PyExc_RuntimeError, "unknown exception caught while getting description for dataset `%s' in HDF5 file `%s'", key, self->f->filename().c_str());
@@ -437,7 +437,7 @@ static PyObject* PyBobIoHDF5File_Unlink(PyBobIoHDF5FileObject* self, PyObject *a
     self->f->unlink(key);
   }
   catch (std::exception& e) {
-    PyErr_Format(PyExc_RuntimeError, "could unlink dataset `%s' in file `%s': %s", key, self->f->filename().c_str(), e.what());
+    PyErr_SetString(PyExc_RuntimeError, e.what());
     return 0;
   }
   catch (...) {
@@ -480,7 +480,7 @@ static PyObject* PyBobIoHDF5File_Rename(PyBobIoHDF5FileObject* self, PyObject *a
     self->f->rename(from, to);
   }
   catch (std::exception& e) {
-    PyErr_Format(PyExc_RuntimeError, "could rename dataset `%s' to `%s' in file `%s': %s", from, to, self->f->filename().c_str(), e.what());
+    PyErr_SetString(PyExc_RuntimeError, e.what());
     return 0;
   }
   catch (...) {
@@ -530,7 +530,7 @@ static PyObject* PyBobIoHDF5File_Paths(PyBobIoHDF5FileObject* self, PyObject *ar
     }
   }
   catch (std::exception& e) {
-    PyErr_Format(PyExc_RuntimeError, "could read dataset names from file `%s': %s", self->f->filename().c_str(), e.what());
+    PyErr_SetString(PyExc_RuntimeError, e.what());
     return 0;
   }
   catch (...) {
@@ -587,7 +587,7 @@ static PyObject* PyBobIoHDF5File_SubGroups(PyBobIoHDF5FileObject* self, PyObject
     }
   }
   catch (std::exception& e) {
-    PyErr_Format(PyExc_RuntimeError, "could read group names from file `%s': %s", self->f->filename().c_str(), e.what());
+    PyErr_SetString(PyExc_RuntimeError, e.what());
     return 0;
   }
   catch (...) {
@@ -621,10 +621,21 @@ recursive\n\
 static PyObject* PyBobIoHDF5File_Xread(PyBobIoHDF5FileObject* self, 
     const char* p, int descriptor, int pos) {
 
-  const std::vector<bob::io::HDF5Descriptor>& D = self->f->describe(p);
+  const std::vector<bob::io::HDF5Descriptor>* D = 0;
+  try {
+    D = &self->f->describe(p);
+  }
+  catch (std::exception& e) {
+    PyErr_SetString(PyExc_RuntimeError, e.what());
+    return 0;
+  }
+  catch (...) {
+    PyErr_Format(PyExc_RuntimeError, "caught unknown exception while trying to describe dataset `%s' from HDF5 file `%s'", p, self->f->filename().c_str());
+    return 0;
+  }
 
   //last descriptor always contains the full readout.
-  const bob::io::HDF5Type& type = D[descriptor].type;
+  const bob::io::HDF5Type& type = (*D)[descriptor].type;
   const bob::io::HDF5Shape& shape = type.shape();
 
   if (shape.n() == 1 && shape[0] == 1) { //read as scalar
@@ -668,7 +679,7 @@ static PyObject* PyBobIoHDF5File_Xread(PyBobIoHDF5FileObject* self,
       }
     }
     catch (std::exception& e) {
-      PyErr_Format(PyExc_RuntimeError, "cannot read %s scalar from dataset `%s' at position %d from HDF5 file `%s': %s", bob::io::stringize(type.type()), p, pos, self->f->filename().c_str(), e.what());
+      PyErr_SetString(PyExc_RuntimeError, e.what());
       return 0;
     }
     catch (...) {
@@ -694,7 +705,7 @@ static PyObject* PyBobIoHDF5File_Xread(PyBobIoHDF5FileObject* self,
     self->f->read_buffer(p, pos, atype, PyArray_DATA((PyArrayObject*)retval));
   }
   catch (std::exception& e) {
-    PyErr_Format(PyExc_RuntimeError, "cannot read dataset `%s' at position %d with descriptor `%s' from HDF5 file `%s': %s", p, pos, type.str().c_str(), self->f->filename().c_str(), e.what());
+    PyErr_SetString(PyExc_RuntimeError, e.what());
     Py_DECREF(retval);
     return 0;
   }
@@ -748,12 +759,23 @@ static PyObject* PyBobIoHDF5File_ListRead(PyBobIoHDF5FileObject* self, PyObject
   if (pos >= 0) return PyBobIoHDF5File_Xread(self, key, 1, pos);
 
   //otherwise returns as a list
-  const std::vector<bob::io::HDF5Descriptor>& D = self->f->describe(key);
+  const std::vector<bob::io::HDF5Descriptor>* D = 0;
+  try {
+    D = &self->f->describe(key);
+  }
+  catch (std::exception& e) {
+    PyErr_Format(PyExc_RuntimeError, "%s", e.what());
+    return 0;
+  }
+  catch (...) {
+    PyErr_Format(PyExc_RuntimeError, "caught unknown exception while trying to describe dataset `%s' from HDF5 file `%s'", key, self->f->filename().c_str());
+    return 0;
+  }
 
-  PyObject* retval = PyTuple_New(D[0].size);
+  PyObject* retval = PyTuple_New((*D)[0].size);
   if (!retval) return 0;
 
-  for (uint64_t k=0; k<D[0].size; ++k) {
+  for (uint64_t k=0; k<(*D)[0].size; ++k) {
     PyObject* item = PyBobIoHDF5File_Xread(self, key, 0, k);
     if (!item) {
       Py_DECREF(retval);
diff --git a/xbob/io/test/test_hdf5.py b/xbob/io/test/test_hdf5.py
index 939a9993706f3fe3cbb175a313a03389b95e868c..42f56b8ffe879ddc53fd55031373792072d0e9af 100644
--- a/xbob/io/test/test_hdf5.py
+++ b/xbob/io/test/test_hdf5.py
@@ -27,7 +27,7 @@ import random
 import nose.tools
 
 from .. import HDF5File, load, save, peek_all
-from ...test import utils as testutils
+from . import utils as testutils
 
 def read_write_check(outfile, dname, data, dtype=None):
   """Tests scalar input/output on HDF5 files"""
@@ -100,7 +100,7 @@ def test_can_create():
     # Data that is thrown in the file is immediately accessible, so you can
     # interleave read and write operations without any problems.
     # There is a single variable in the file, which is a bob arrayset:
-    assert outfile.paths() == ['/testdata']
+    assert outfile.paths() == ('/testdata',)
 
     # And all the data is *exactly* the same recorded, bit by bit
     back = outfile.lread('testdata') # this is how to read the whole data back
@@ -115,7 +115,7 @@ def test_can_create():
     readonly = HDF5File(tmpname, 'r')
 
     # There is a single variable in the file, which is a bob arrayset:
-    assert readonly.paths() == ['/testdata']
+    assert readonly.paths() == ('/testdata',)
 
     # You can get an overview of what is in the HDF5 dataset using the
     # describe() method
@@ -231,14 +231,14 @@ def test_dataset_management():
     outfile.rename('NewDirectory1/Dir2/MyDataset', 'Test2/Bla')
 
     # So, now the original dataset name does not exist anymore
-    assert outfile.paths() == ['/Test2/Bla']
+    assert outfile.paths() == ('/Test2/Bla',)
 
     # We can also unlink the dataset from the file. Please note this will not
     # erase the data in the file, just make it inaccessible
     outfile.unlink('Test2/Bla')
 
     # Finally, nothing is there anymore
-    assert outfile.paths() == []
+    assert outfile.paths() == tuple()
 
   finally:
     os.unlink(tmpname)
@@ -290,7 +290,7 @@ def test_matlab_import():
 
   # This test verifies we can import HDF5 datasets generated in Matlab
   mfile = HDF5File(testutils.datafile('matlab_1d.hdf5', __name__))
-  assert mfile.paths() == ['/array']
+  assert mfile.paths() == ('/array',)
 
 def test_ioload_unlimited():
 
diff --git a/xbob/io/videoreader.cpp b/xbob/io/videoreader.cpp
index d4f1625acf48e77482a15a5cd46d1d39336c33ac..24216e2b2368f709fd85947e09ed7c241b362023 100644
--- a/xbob/io/videoreader.cpp
+++ b/xbob/io/videoreader.cpp
@@ -89,7 +89,7 @@ static int PyBobIoVideoReader_Init(PyBobIoVideoReaderObject* self,
     self->v = boost::make_shared<bob::io::VideoReader>(filename, check);
   }
   catch (std::exception& e) {
-    PyErr_Format(PyExc_RuntimeError, "cannot open video file `%s' for reading: %s", filename, e.what());
+    PyErr_SetString(PyExc_RuntimeError, e.what());
     return -1;
   }
   catch (...) {
@@ -350,7 +350,7 @@ static PyObject* PyBobIoVideoReader_Load(PyBobIoVideoReaderObject* self, PyObjec
     frames_read = self->v->load(skin, raise_on_error, &Check_Interrupt);
   }
   catch (std::exception& e) {
-    if (!PyErr_Occurred()) PyErr_Format(PyExc_RuntimeError, "caught std::exception while reading video from file `%s': %s", self->v->filename().c_str(), e.what());
+    if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, e.what());
     Py_DECREF(retval);
     return 0;
   }
@@ -429,7 +429,7 @@ static PyObject* PyBobIoVideoReader_GetIndex (PyBobIoVideoReaderObject* self, Py
     it.read(skin);
   }
   catch (std::exception& e) {
-    if (!PyErr_Occurred()) PyErr_Format(PyExc_RuntimeError, "caught std::exception while reading frame %" PY_FORMAT_SIZE_T "d from file `%s': %s", i, self->v->filename().c_str(), e.what());
+    if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, e.what());
     Py_DECREF(retval);
     return 0;
   }
@@ -499,7 +499,7 @@ static PyObject* PyBobIoVideoReader_GetSlice (PyBobIoVideoReaderObject* self, Py
       it += (st-1);
     }
     catch (std::exception& e) {
-      if (!PyErr_Occurred()) PyErr_Format(PyExc_RuntimeError, "caught std::exception while reading frame %" PY_FORMAT_SIZE_T "d from file `%s': %s", i, self->v->filename().c_str(), e.what());
+      if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, e.what());
       Py_DECREF(retval);
       Py_DECREF(item);
       return 0;
@@ -587,7 +587,7 @@ static PyObject* PyBobIoVideoReaderIterator_Next (PyBobIoVideoReaderIteratorObje
     self->iter->read(skin);
   }
   catch (std::exception& e) {
-    if (!PyErr_Occurred()) PyErr_Format(PyExc_RuntimeError, "caught std::exception while reading frame #%" PY_FORMAT_SIZE_T "d from file `%s': %s", self->iter->cur(), self->pyreader->v->filename().c_str(), e.what());
+    if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, e.what());
     Py_DECREF(retval);
     return 0;
   }
diff --git a/xbob/io/videowriter.cpp b/xbob/io/videowriter.cpp
index 5db88c9dcc4fe4e01edb3d350f6e0fec7bfb2b33..19b50a8f44310a3a5219c8ba24873473bdf1dc93 100644
--- a/xbob/io/videowriter.cpp
+++ b/xbob/io/videowriter.cpp
@@ -128,7 +128,7 @@ static int PyBobIoVideoWriter_Init(PyBobIoVideoWriterObject* self,
         framerate, bitrate, gop, codec, format, check);
   }
   catch (std::exception& e) {
-    PyErr_Format(PyExc_RuntimeError, "cannot open video file `%s' for writing: %s", filename, e.what());
+    PyErr_SetString(PyExc_RuntimeError, e.what());
     return -1;
   }
   catch (...) {
@@ -430,7 +430,7 @@ static PyObject* PyBobIoVideoWriter_Append(PyBobIoVideoWriterObject* self, PyObj
     }
   }
   catch (std::exception& e) {
-    if (!PyErr_Occurred()) PyErr_Format(PyExc_RuntimeError, "caught std::exception while writing frame #%" PY_FORMAT_SIZE_T "d to file `%s': %s", self->v->numberOfFrames(), self->v->filename().c_str(), e.what());
+    if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, e.what());
     Py_DECREF(frame);
     return 0;
   }