diff --git a/Mesh/FieldPython.h b/Mesh/FieldPython.h
new file mode 100644
index 0000000000000000000000000000000000000000..f6ca53c1b47ed1fb3df6a0e7cd97ca37d17d6a80
--- /dev/null
+++ b/Mesh/FieldPython.h
@@ -0,0 +1,59 @@
+#ifndef _FIELD_PYTHON_H_
+#define _FIELD_PYTHON_H_
+
+#include "Field.h"
+#include "Python.h"
+class FieldPython : public Field
+{
+  PyObject *_callback;
+
+ public:
+  const char *getName()
+  {
+    return "Python";
+  }
+
+  std::string getDescription()
+  {
+    return "simple call to a python function";
+  }
+
+  FieldPython(PyObject *cb, PyObject *arg = NULL)
+  {
+    _callback = cb;
+    Py_INCREF(_callback);
+  }
+
+  ~FieldPython()
+  {
+    Py_DECREF(_callback);
+  }
+
+  double operator() (double x, double y, double z, GEntity *ge=0)
+  {
+    PyObject *pyge = SWIG_NewPointerObj((void*) ge, SWIGTYPE_p_GEntity, 0);
+    PyObject *args = Py_BuildValue("(dddO)",  x, y, z, pyge);
+    PyObject *result = PyEval_CallObject(_callback, args);
+    Py_DECREF(args);
+    if (result) {
+      double r = PyFloat_AsDouble(result);
+      if (PyErr_Occurred()) {
+        PyErr_Print();
+        PyErr_Clear();
+        Msg::Error("Result of python function of field %i cannot be interpreted as a float.", id);
+        r = MAX_LC;
+      }
+      Py_DECREF(result);
+      return r;
+    }
+    else {
+      if (PyErr_Occurred()) {
+        PyErr_Print();
+        PyErr_Clear();
+      }
+      Msg::Error("An error occurs while evaluating python function of field %i.", id);
+      return MAX_LC;
+    }
+  }
+};
+#endif
diff --git a/wrappers/gmshpy/gmshMesh.i b/wrappers/gmshpy/gmshMesh.i
index 0e3c66d39b624592bc7db6437d0cf62c1f465a8e..38836cae212845de6e35522d230b32a3a1f9c853 100644
--- a/wrappers/gmshpy/gmshMesh.i
+++ b/wrappers/gmshpy/gmshMesh.i
@@ -21,6 +21,7 @@
   #include "meshPartition.h"
 #endif
   #include "Field.h"
+  #include "FieldPython.h"
   #include "meshMetric.h"
 #if defined(HAVE_ANN)
   #include "CenterlineField.h"
@@ -58,6 +59,21 @@ namespace std {
 %include "meshPartition.h"
 #endif
 %include "Field.h"
+%extend FieldManager {
+  int addPythonField(PyObject *callback, int id = -1) {
+    if (id == -1) {
+      id = $self->newId();
+    }
+    if($self->find(id) != $self->end()) {
+      Msg::Error("Field id %i is already defined", id);
+      return -1;
+    }
+    Field *f = new FieldPython(callback);
+    f->id = id;
+    $self->operator[](id) = f;
+    return id;
+  }
+}
 %include "meshMetric.h"
 #if defined(HAVE_ANN)
 %include "CenterlineField.h"