diff --git a/bob/learn/em/isv_trainer.cpp b/bob/learn/em/isv_trainer.cpp
index d557999ab54f353ca033b15cd70877715337ce7f..9fdc0052f849512f7fa215d9fa6c86182ffe21db 100644
--- a/bob/learn/em/isv_trainer.cpp
+++ b/bob/learn/em/isv_trainer.cpp
@@ -485,9 +485,9 @@ static auto m_step = bob::extension::FunctionDoc(
   "",
   true
 )
-.add_prototype("isv_base, stats")
+.add_prototype("isv_base, [stats]")
 .add_parameter("isv_base", ":py:class:`bob.learn.em.ISVBase`", "ISVBase Object")
-.add_parameter("stats", ":py:class:`bob.learn.em.GMMStats`", "Ignored");
+.add_parameter("stats", "object", "Ignored.");
 static PyObject* PyBobLearnEMISVTrainer_m_step(PyBobLearnEMISVTrainerObject* self, PyObject* args, PyObject* kwargs) {
   BOB_TRY
 
@@ -495,10 +495,10 @@ static PyObject* PyBobLearnEMISVTrainer_m_step(PyBobLearnEMISVTrainerObject* sel
   char** kwlist = m_step.kwlist(0);
 
   PyBobLearnEMISVBaseObject* isv_base = 0;
-  PyObject* stats = 0;
+  PyObject* stats;
 
-  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|O!", kwlist, &PyBobLearnEMISVBase_Type, &isv_base,
-                                                                 &PyList_Type, &stats)) return 0;
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|O", kwlist, &PyBobLearnEMISVBase_Type, &isv_base,
+                                                                 &stats)) return 0;
 
   self->cxx->mStep(*isv_base->cxx);
 
diff --git a/bob/learn/em/ivector_trainer.cpp b/bob/learn/em/ivector_trainer.cpp
index 61a427d7ae731e99f31fd9b561d9d43ee09baea8..9e630548508398b13759be0f5b214af80519468e 100644
--- a/bob/learn/em/ivector_trainer.cpp
+++ b/bob/learn/em/ivector_trainer.cpp
@@ -315,7 +315,7 @@ static auto initialize = bob::extension::FunctionDoc(
 )
 .add_prototype("ivector_machine, [stats], [rng]")
 .add_parameter("ivector_machine", ":py:class:`bob.learn.em.IVectorMachine`", "IVectorMachine Object")
-.add_parameter("stats", ":py:class:`bob.learn.em.GMMStats`", "Ignored")
+.add_parameter("stats", "object", "Ignored")
 .add_parameter("rng", ":py:class:`bob.core.random.mt19937`", "The Mersenne Twister mt19937 random generator used for the initialization of subspaces/arrays before the EM loop.");
 static PyObject* PyBobLearnEMIVectorTrainer_initialize(PyBobLearnEMIVectorTrainerObject* self, PyObject* args, PyObject* kwargs) {
   BOB_TRY
@@ -324,12 +324,13 @@ static PyObject* PyBobLearnEMIVectorTrainer_initialize(PyBobLearnEMIVectorTraine
   char** kwlist = initialize.kwlist(0);
 
   PyBobLearnEMIVectorMachineObject* ivector_machine = 0;
-  PyObject* stats = 0;
+  PyObject* stats;
   PyBoostMt19937Object* rng = 0;
 
-  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|O!O!", kwlist, &PyBobLearnEMIVectorMachine_Type, &ivector_machine,
-                                                                    &PyList_Type, &stats,
-                                                                    &PyBoostMt19937_Type, &rng)) return 0;
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|OO!", kwlist, &PyBobLearnEMIVectorMachine_Type, &ivector_machine,
+                                                                   &stats,
+                                                                   &PyBoostMt19937_Type, &rng)) return 0;
+
   if(rng){
     boost::shared_ptr<boost::mt19937> rng_cpy = (boost::shared_ptr<boost::mt19937>)new boost::mt19937(*rng->rng);
     self->cxx->setRng(rng_cpy);
@@ -383,9 +384,9 @@ static auto m_step = bob::extension::FunctionDoc(
   "",
   true
 )
-.add_prototype("ivector_machine, stats")
+.add_prototype("ivector_machine, [stats]")
 .add_parameter("ivector_machine", ":py:class:`bob.learn.em.ISVBase`", "IVectorMachine Object")
-.add_parameter("stats", ":py:class:`bob.learn.em.GMMStats`", "Ignored");
+.add_parameter("stats", "object", "Ignored");
 static PyObject* PyBobLearnEMIVectorTrainer_m_step(PyBobLearnEMIVectorTrainerObject* self, PyObject* args, PyObject* kwargs) {
   BOB_TRY
 
@@ -393,10 +394,10 @@ static PyObject* PyBobLearnEMIVectorTrainer_m_step(PyBobLearnEMIVectorTrainerObj
   char** kwlist = m_step.kwlist(0);
 
   PyBobLearnEMIVectorMachineObject* ivector_machine = 0;
-  PyObject* stats = 0;
+  PyObject* stats;
 
-  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|O!", kwlist, &PyBobLearnEMIVectorMachine_Type, &ivector_machine,
-                                                                 &PyList_Type, &stats)) return 0;
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|O", kwlist, &PyBobLearnEMIVectorMachine_Type, &ivector_machine,
+                                                                 &stats)) return 0;
 
   self->cxx->mStep(*ivector_machine->cxx);
 
diff --git a/bob/learn/em/kmeans_trainer.cpp b/bob/learn/em/kmeans_trainer.cpp
index 2fe2c3c2e5202d62f603f0103b73bacb8cb7f826..90ebb5c26558f87258be6f3190d11b9d4d6378b3 100644
--- a/bob/learn/em/kmeans_trainer.cpp
+++ b/bob/learn/em/kmeans_trainer.cpp
@@ -417,9 +417,9 @@ static auto m_step = bob::extension::FunctionDoc(
   0,
   true
 )
-.add_prototype("kmeans_machine,data")
+.add_prototype("kmeans_machine, [data]")
 .add_parameter("kmeans_machine", ":py:class:`bob.learn.em.KMeansMachine`", "KMeansMachine Object")
-.add_parameter("data", "array_like <float, 2D>", "Ignored.");
+.add_parameter("data", "object", "Ignored.");
 static PyObject* PyBobLearnEMKMeansTrainer_m_step(PyBobLearnEMKMeansTrainerObject* self, PyObject* args, PyObject* kwargs) {
   BOB_TRY
 
@@ -427,12 +427,9 @@ static PyObject* PyBobLearnEMKMeansTrainer_m_step(PyBobLearnEMKMeansTrainerObjec
   char** kwlist = m_step.kwlist(0);
 
   PyBobLearnEMKMeansMachineObject* kmeans_machine;
-  PyBlitzArrayObject* data = 0;
-  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O&", kwlist, &PyBobLearnEMKMeansMachine_Type, &kmeans_machine,
-                                                                 &PyBlitzArray_Converter, &data)) return 0;
-  if(data!=NULL)
-    auto data_ = make_safe(data);
-
+  PyObject* data = 0;
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|O", kwlist, &PyBobLearnEMKMeansMachine_Type, &kmeans_machine,
+                                                                 &data)) return 0;
   self->cxx->mStep(*kmeans_machine->cxx);
 
   BOB_CATCH_MEMBER("cannot perform the m_step method", 0)
diff --git a/bob/learn/em/map_gmm_trainer.cpp b/bob/learn/em/map_gmm_trainer.cpp
index eae15d4f232c55c3f8d3c573550ba0b1d4e940c3..1eb3a1881ddedf8babc1c2d658583914f76bd25e 100644
--- a/bob/learn/em/map_gmm_trainer.cpp
+++ b/bob/learn/em/map_gmm_trainer.cpp
@@ -306,9 +306,9 @@ static auto initialize = bob::extension::FunctionDoc(
   "",
   true
 )
-.add_prototype("gmm_machine,data")
+.add_prototype("gmm_machine, [data]")
 .add_parameter("gmm_machine", ":py:class:`bob.learn.em.GMMMachine`", "GMMMachine Object")
-.add_parameter("data", "array_like <float, 2D>", "Ignored.");
+.add_parameter("data", "object", "Ignored.");
 static PyObject* PyBobLearnEMMAPGMMTrainer_initialize(PyBobLearnEMMAPGMMTrainerObject* self, PyObject* args, PyObject* kwargs) {
   BOB_TRY
 
@@ -316,12 +316,11 @@ static PyObject* PyBobLearnEMMAPGMMTrainer_initialize(PyBobLearnEMMAPGMMTrainerO
   char** kwlist = initialize.kwlist(0);
 
   PyBobLearnEMGMMMachineObject* gmm_machine = 0;
-  PyBlitzArrayObject* data                  = 0;
+  PyObject* data;
+
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|O", kwlist, &PyBobLearnEMGMMMachine_Type, &gmm_machine,
+                                                                 &data)) return 0;
 
-  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|O&", kwlist, &PyBobLearnEMGMMMachine_Type, &gmm_machine,
-                                                                  &PyBlitzArray_Converter, &data)) return 0;
-  if(data != NULL)
-    auto data_ = make_safe(data);
   self->cxx->initialize(*gmm_machine->cxx);
 
   BOB_CATCH_MEMBER("cannot perform the initialize method", 0)
@@ -390,9 +389,9 @@ static auto m_step = bob::extension::FunctionDoc(
   "",
   true
 )
-.add_prototype("gmm_machine,data")
+.add_prototype("gmm_machine, [data]")
 .add_parameter("gmm_machine", ":py:class:`bob.learn.em.GMMMachine`", "GMMMachine Object")
-.add_parameter("data", "array_like <float, 2D>", "Ignored.");
+.add_parameter("data", "object", "Ignored.");
 static PyObject* PyBobLearnEMMAPGMMTrainer_m_step(PyBobLearnEMMAPGMMTrainerObject* self, PyObject* args, PyObject* kwargs) {
   BOB_TRY
 
@@ -400,12 +399,10 @@ static PyObject* PyBobLearnEMMAPGMMTrainer_m_step(PyBobLearnEMMAPGMMTrainerObjec
   char** kwlist = m_step.kwlist(0);
 
   PyBobLearnEMGMMMachineObject* gmm_machine;
-  PyBlitzArrayObject* data                  = 0;
+  PyObject* data;
 
-  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|O&", kwlist, &PyBobLearnEMGMMMachine_Type, &gmm_machine,
-                                                                  &PyBlitzArray_Converter, &data)) return 0;
-  if(data != NULL)
-    auto data_ = make_safe(data);
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|O", kwlist, &PyBobLearnEMGMMMachine_Type, &gmm_machine,
+                                                                 &data)) return 0;
 
   self->cxx->mStep(*gmm_machine->cxx);
 
diff --git a/bob/learn/em/ml_gmm_trainer.cpp b/bob/learn/em/ml_gmm_trainer.cpp
index 2b30ec980fa97b6e1b69c1f19078df93ea2417f5..515e9e903b55c003512fbb7459dc1ecacd7df266 100644
--- a/bob/learn/em/ml_gmm_trainer.cpp
+++ b/bob/learn/em/ml_gmm_trainer.cpp
@@ -192,20 +192,19 @@ static auto initialize = bob::extension::FunctionDoc(
   "",
   true
 )
-.add_prototype("gmm_machine,data")
+.add_prototype("gmm_machine, [data]")
 .add_parameter("gmm_machine", ":py:class:`bob.learn.em.GMMMachine`", "GMMMachine Object")
-.add_parameter("data", "array_like <float, 2D>", "Ignored.");
+.add_parameter("data", "object", "Ignored.");
 static PyObject* PyBobLearnEMMLGMMTrainer_initialize(PyBobLearnEMMLGMMTrainerObject* self, PyObject* args, PyObject* kwargs) {
   BOB_TRY
 
   /* Parses input arguments in a single shot */
   char** kwlist = initialize.kwlist(0);
   PyBobLearnEMGMMMachineObject* gmm_machine = 0;
-  PyBlitzArrayObject* data                  = 0;
+  PyObject* data;
 
-  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|O&", kwlist, &PyBobLearnEMGMMMachine_Type, &gmm_machine,
-                                                                  &PyBlitzArray_Converter, &data)) return 0;
-  auto data_ = make_safe(data);
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|O", kwlist, &PyBobLearnEMGMMMachine_Type, &gmm_machine,
+                                                                  &data)) return 0;
 
   self->cxx->initialize(*gmm_machine->cxx);
   BOB_CATCH_MEMBER("cannot perform the initialize method", 0)
@@ -275,9 +274,9 @@ static auto m_step = bob::extension::FunctionDoc(
 
   true
 )
-.add_prototype("gmm_machine,data")
+.add_prototype("gmm_machine, [data]")
 .add_parameter("gmm_machine", ":py:class:`bob.learn.em.GMMMachine`", "GMMMachine Object")
-.add_parameter("data", "array_like <float, 2D>", "Ignored.");
+.add_parameter("data", "object", "Ignored.");
 static PyObject* PyBobLearnEMMLGMMTrainer_m_step(PyBobLearnEMMLGMMTrainerObject* self, PyObject* args, PyObject* kwargs) {
   BOB_TRY
 
@@ -285,12 +284,10 @@ static PyObject* PyBobLearnEMMLGMMTrainer_m_step(PyBobLearnEMMLGMMTrainerObject*
   char** kwlist = m_step.kwlist(0);
 
   PyBobLearnEMGMMMachineObject* gmm_machine = 0;
-  PyBlitzArrayObject* data                  = 0;
+  PyObject* data;
 
-  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|O&", kwlist, &PyBobLearnEMGMMMachine_Type, &gmm_machine,
-                                                                  &PyBlitzArray_Converter, &data)) return 0;
-  if(data != NULL)
-    auto data_ = make_safe(data);
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|O", kwlist, &PyBobLearnEMGMMMachine_Type, &gmm_machine,
+                                                                 &data)) return 0;
 
   self->cxx->mStep(*gmm_machine->cxx);