diff --git a/bob/learn/misc/gmm_stats.cpp b/bob/learn/misc/gmm_stats.cpp
index 6409945a2f07381feec951a74fc71210525b04e6..88e9419c80b32c047c0919b55f703de336ffba70 100644
--- a/bob/learn/misc/gmm_stats.cpp
+++ b/bob/learn/misc/gmm_stats.cpp
@@ -33,18 +33,32 @@ static auto GMMStats_doc = bob::extension::ClassDoc(
   .add_prototype("hdf5")
   .add_prototype("")
 
-  //.add_parameter("mean", "array_like<double, 1D>", "Mean of the Gaussian")
+  .add_parameter("n_gaussians", "int", "Number of gaussians")
+  .add_parameter("n_inputs", "int", "Dimension of the feature vector")
+  .add_parameter("other", ":py:class:`bob.learn.misc.GMMStats`", "A GMMStats object to be copied.")
+  .add_parameter("hdf5", ":py:class:`bob.io.base.HDF5File`", "An HDF5 file open for reading")
+
 );
 
 
 static int PyBobLearnMiscGMMStats_init_number(PyBobLearnMiscGMMStatsObject* self, PyObject* args, PyObject* kwargs) {
 
   char** kwlist = GMMStats_doc.kwlist(0);
-  size_t n_inputs=1;
-  size_t n_gaussians=1;
+  int n_inputs    = 1;
+  int n_gaussians = 1;
   //Parsing the input argments
-  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "II", kwlist, &n_gaussians, &n_inputs))
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii", kwlist, &n_gaussians, &n_inputs))
+    return -1;
+
+  if(n_gaussians < 0){
+    PyErr_Format(PyExc_TypeError, "gaussians argument must be greater than or equal to zero");
+    return -1;
+  }
+
+  if(n_inputs < 0){
+    PyErr_Format(PyExc_TypeError, "input argument must be greater than or equal to zero");
     return -1;
+   }
 
   self->cxx.reset(new bob::learn::misc::GMMStats(n_gaussians, n_inputs));
   return 0;
@@ -55,7 +69,7 @@ static int PyBobLearnMiscGMMStats_init_copy(PyBobLearnMiscGMMStatsObject* self,
 
   char** kwlist = GMMStats_doc.kwlist(1);
   PyBobLearnMiscGMMStatsObject* tt;
-  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&", kwlist, &PyBobLearnMiscGMMStats_Type, &tt)) return -1;
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!", kwlist, &PyBobLearnMiscGMMStats_Type, &tt)) return -1;
 
   self->cxx.reset(new bob::learn::misc::GMMStats(*tt->cxx));
   return 0;
@@ -67,7 +81,7 @@ static int PyBobLearnMiscGMMStats_init_hdf5(PyBobLearnMiscGMMStatsObject* self,
   char** kwlist = GMMStats_doc.kwlist(2);
 
   PyBobIoHDF5FileObject* config = 0;
-  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&", kwlist, &PyBobIoHDF5File_Converter, &config)) 
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&", kwlist, &PyBobIoHDF5File_Converter, &config))
     return -1;
 
   try {
@@ -99,7 +113,6 @@ static int PyBobLearnMiscGMMStats_init(PyBobLearnMiscGMMStatsObject* self, PyObj
       self->cxx.reset(new bob::learn::misc::GMMStats());
 
     case 1:{
-
       //Reading the input argument
       PyObject* arg = 0;
       if (PyTuple_Size(args))
@@ -115,7 +128,7 @@ static int PyBobLearnMiscGMMStats_init(PyBobLearnMiscGMMStatsObject* self, PyObj
        return PyBobLearnMiscGMMStats_init_copy(self, args, kwargs);
       /**If the constructor input is a HDF5**/
      else if (PyBobIoHDF5File_Check(arg))
-       return PyBobLearnMiscGMMStats_init_hdf5(self, args, kwargs);	
+       return PyBobLearnMiscGMMStats_init_hdf5(self, args, kwargs);
     }
     case 2:
       return PyBobLearnMiscGMMStats_init_number(self, args, kwargs);
@@ -166,8 +179,9 @@ int PyBobLearnMiscGMMStats_Check(PyObject* o) {
 /***** n *****/
 static auto n = bob::extension::VariableDoc(
   "n",
-  "array_like <double, 1D>",
-  "For each Gaussian, the accumulated sum of responsibilities, i.e. the sum of P(gaussian_i|x)"
+  "array_like <double, 1D> "
+  "For each Gaussian, the accumulated sum of responsibilities, i.e. the sum of P(gaussian_i|x)",
+  ""
 );
 PyObject* PyBobLearnMiscGMMStats_getN(PyBobLearnMiscGMMStatsObject* self, void*){
   BOB_TRY
@@ -193,8 +207,9 @@ int PyBobLearnMiscGMMStats_setN(PyBobLearnMiscGMMStatsObject* self, PyObject* va
 /***** sum_px *****/
 static auto sum_px = bob::extension::VariableDoc(
   "sum_px",
-  "array_like <double, 2D>",
-  "For each Gaussian, the accumulated sum of responsibility times the sample"
+  "array_like <double, 2D> "
+  "For each Gaussian, the accumulated sum of responsibility times the sample",
+  ""
 );
 PyObject* PyBobLearnMiscGMMStats_getSum_px(PyBobLearnMiscGMMStatsObject* self, void*){
   BOB_TRY
@@ -220,8 +235,9 @@ int PyBobLearnMiscGMMStats_setSum_px(PyBobLearnMiscGMMStatsObject* self, PyObjec
 /***** sum_pxx *****/
 static auto sum_pxx = bob::extension::VariableDoc(
   "sum_pxx",
-  "array_like <double, 2D>",
-  "For each Gaussian, the accumulated sum of responsibility times the sample squared"
+  "array_like <double, 2D> "
+  "For each Gaussian, the accumulated sum of responsibility times the sample squared",
+  ""
 );
 PyObject* PyBobLearnMiscGMMStats_getSum_pxx(PyBobLearnMiscGMMStatsObject* self, void*){
   BOB_TRY
@@ -247,8 +263,9 @@ int PyBobLearnMiscGMMStats_setSum_pxx(PyBobLearnMiscGMMStatsObject* self, PyObje
 /***** t *****/
 static auto t = bob::extension::VariableDoc(
   "t",
-  "size_t",
-  "The accumulated log likelihood of all samples"
+  "int "
+  "The accumulated log likelihood of all samples",
+  ""
 );
 PyObject* PyBobLearnMiscGMMStats_getT(PyBobLearnMiscGMMStatsObject* self, void*){
   BOB_TRY
@@ -277,8 +294,9 @@ int PyBobLearnMiscGMMStats_setT(PyBobLearnMiscGMMStatsObject* self, PyObject* va
 /***** log_likelihood *****/
 static auto log_likelihood = bob::extension::VariableDoc(
   "log_likelihood",
-  "double",
-  "The accumulated log likelihood of all samples"
+  "double "
+  "The accumulated log likelihood of all samples",
+  ""
 );
 PyObject* PyBobLearnMiscGMMStats_getLog_likelihood(PyBobLearnMiscGMMStatsObject* self, void*){
   BOB_TRY
@@ -387,7 +405,9 @@ static auto load = bob::extension::FunctionDoc(
   " Load the configuration of the GMMStats to a given HDF5 file",
   0,
   true
-);
+)
+.add_prototype("hdf5")
+.add_parameter("hdf5", ":py:class:`bob.io.base.HDF5File`", "An HDF5 file open for reading");
 static PyObject* PyBobLearnMiscGMMStats_Load(PyBobLearnMiscGMMStatsObject* self, PyObject* f) {
 
   if (!PyBobIoHDF5File_Check(f)) {
@@ -425,7 +445,7 @@ static auto is_similar_to = bob::extension::FunctionDoc(
   true
 )
 .add_prototype("other, [r_epsilon], [a_epsilon]","bool")
-.add_parameter("other", ":py:class:`bob.learn.misc.GMMStats`", "A gaussian to be compared.")
+.add_parameter("other", ":py:class:`bob.learn.misc.GMMStats`", "A GMMStats object to be compared.")
 .add_parameter("[r_epsilon]", "float", "Relative precision.")
 .add_parameter("[a_epsilon]", "float", "Absolute precision.")
 .add_return("bool","","");
@@ -454,21 +474,22 @@ static PyObject* PyBobLearnMiscGMMStats_IsSimilarTo(PyBobLearnMiscGMMStatsObject
 /*** resize ***/
 static auto resize = bob::extension::FunctionDoc(
   "resize",
-  "(size_t,size_t)"
-  " Allocates space for the statistics and resets to zero."
+  " Allocates space for the statistics and resets to zero.",
+  ""
 )
-.add_prototype("n_gaussians,n_inputs")
-.add_parameter("n_gaussians,n_inputs", "(size_t, size_t)", "Tuple with the new shape");
+.add_prototype("n_gaussians,n_inputs","")
+.add_parameter("n_gaussians", "int", "Number of gaussians")
+.add_parameter("n_inputs", "int", "Dimensionality of the feature vector");
 static PyObject* PyBobLearnMiscGMMStats_resize(PyBobLearnMiscGMMStatsObject* self, PyObject* args, PyObject* kwargs) {
   BOB_TRY
 
   /* Parses input arguments in a single shot */
   char** kwlist = resize.kwlist(0);
 
-  Py_ssize_t n_gaussians = 0;
-  Py_ssize_t n_inputs = 0;
+  int n_gaussians = 0;
+  int n_inputs = 0;
 
-  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "nn", kwlist, &n_gaussians, &n_inputs)) Py_RETURN_NONE;
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii", kwlist, &n_gaussians, &n_inputs)) Py_RETURN_NONE;
   self->cxx->resize(n_gaussians, n_inputs);
 
   BOB_CATCH_MEMBER("cannot perform the resize method", 0)
@@ -480,9 +501,10 @@ static PyObject* PyBobLearnMiscGMMStats_resize(PyBobLearnMiscGMMStatsObject* sel
 /*** init ***/
 static auto init = bob::extension::FunctionDoc(
   "init",
+  " Resets statistics to zero.",
   ""
-  " Resets statistics to zero."
-);
+)
+.add_prototype("","");
 static PyObject* PyBobLearnMiscGMMStats_init_method(PyBobLearnMiscGMMStatsObject* self) {
   BOB_TRY
 
@@ -505,7 +527,7 @@ static PyMethodDef PyBobLearnMiscGMMStats_methods[] = {
   {
     load.name(),
     (PyCFunction)PyBobLearnMiscGMMStats_Load,
-    METH_VARARGS|METH_KEYWORDS,
+    METH_O,
     load.doc()
   },
   {
@@ -523,7 +545,7 @@ static PyMethodDef PyBobLearnMiscGMMStats_methods[] = {
   {
     init.name(),
     (PyCFunction)PyBobLearnMiscGMMStats_init_method,
-    METH_VARARGS|METH_KEYWORDS,
+    METH_NOARGS,
     init.doc()
   },
 
@@ -554,54 +576,7 @@ static PyObject* PyBobLearnMiscGMMStats_inplaceadd(PyObject* self, PyObject* oth
   return self;
 }
 
-static PyNumberMethods PyBobLearnMiscGMMStats_operators[] = {{
-     0, // nb_add;
-     0, // nb_subtract;
-     0, // nb_multiply;
-     0, // nb_divide;
-     0, // nb_remainder;
-     0, // nb_divmod;
-     0, // nb_power;
-     0, // nb_negative;
-     0, // nb_positive;
-     0, // nb_absolute;
-     0, // nb_nonzero;       /* Used by PyObject_IsTrue */
-     0, // nb_invert;
-     0, // nb_lshift;
-     0, // nb_rshift;
-     0, // nb_and;
-     0, // nb_xor;
-     0, // nb_or;
-     0, // nb_coerce;       /* Used by the coerce() function */
-     0, // nb_int;
-     0, // nb_long;
-     0, // nb_float;
-     0, // nb_oct;
-     0, // nb_hex;
-
-     /* Added in release 2.0 */
-     PyBobLearnMiscGMMStats_inplaceadd, // nb_inplace_add;
-     0, // nb_inplace_subtract;
-     0, // nb_inplace_multiply;
-     0, // nb_inplace_divide;
-     0, // nb_inplace_remainder;
-     0, // nb_inplace_power;
-     0, // nb_inplace_lshift;
-     0, // nb_inplace_rshift;
-     0, // nb_inplace_and;
-     0, // nb_inplace_xor;
-     0, // nb_inplace_or;
-
-     /* Added in release 2.2 */
-     0, // nb_floor_divide;
-     0, // nb_true_divide;
-     0, // nb_inplace_floor_divide;
-     0, // nb_inplace_true_divide;
-
-     /* Added in release 2.5 */
-     0, // nb_index
-}};
-
+static PyNumberMethods PyBobLearnMiscGMMStats_operators = {0};
 
 /******************************************************************/
 /************ Module Section **************************************/
@@ -629,7 +604,10 @@ bool init_BobLearnMiscGMMStats(PyObject* module)
   PyBobLearnMiscGMMStats_Type.tp_methods = PyBobLearnMiscGMMStats_methods;
   PyBobLearnMiscGMMStats_Type.tp_getset = PyBobLearnMiscGMMStats_getseters;
   //PyBobLearnMiscGMMStats_Type.tp_call = reinterpret_cast<ternaryfunc>(PyBobLearnMiscGMMStats_loglikelihood);
-  PyBobLearnMiscGMMStats_Type.tp_as_number = PyBobLearnMiscGMMStats_operators;
+  PyBobLearnMiscGMMStats_Type.tp_as_number = &PyBobLearnMiscGMMStats_operators;
+
+  //set operators
+  PyBobLearnMiscGMMStats_operators.nb_inplace_add = PyBobLearnMiscGMMStats_inplaceadd;
 
   // check that everything is fine
   if (PyType_Ready(&PyBobLearnMiscGMMStats_Type) < 0) return false;