diff --git a/src/PYTHON/python_impl.cpp b/src/PYTHON/python_impl.cpp index c492c6ab3..1b9eef9ea 100644 --- a/src/PYTHON/python_impl.cpp +++ b/src/PYTHON/python_impl.cpp @@ -1,519 +1,536 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ #include #include "python.h" #include "force.h" #include "input.h" #include "variable.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; enum{NONE,INT,DOUBLE,STRING,PTR}; #define VALUELENGTH 64 // also in variable.cpp // Wrap API changes between Python 2 and 3 using macros #if PY_MAJOR_VERSION == 2 #define PY_INT_FROM_LONG(X) PyInt_FromLong(X) #define PY_INT_AS_LONG(X) PyInt_AsLong(X) #define PY_STRING_FROM_STRING(X) PyString_FromString(X) #define PY_VOID_POINTER(X) PyCObject_FromVoidPtr((void *) X, NULL) #define PY_STRING_AS_STRING(X) PyString_AsString(X) #elif PY_MAJOR_VERSION == 3 #define PY_INT_FROM_LONG(X) PyLong_FromLong(X) #define PY_INT_AS_LONG(X) PyLong_AsLong(X) #define PY_STRING_FROM_STRING(X) PyUnicode_FromString(X) #define PY_VOID_POINTER(X) PyCapsule_New((void *) X, NULL, NULL) #define PY_STRING_AS_STRING(X) PyUnicode_AsUTF8(X) #endif /* ---------------------------------------------------------------------- */ PythonImpl::PythonImpl(LAMMPS *lmp) : Pointers(lmp) { // pfuncs stores interface info for each Python function nfunc = 0; pfuncs = NULL; // one-time initialization of Python interpreter // pymain stores pointer to main module external_interpreter = Py_IsInitialized(); Py_Initialize(); PyEval_InitThreads(); PyGILState_STATE gstate = PyGILState_Ensure(); PyObject *pModule = PyImport_AddModule("__main__"); if (!pModule) error->all(FLERR,"Could not initialize embedded Python"); pyMain = (void *) pModule; PyGILState_Release(gstate); } /* ---------------------------------------------------------------------- */ PythonImpl::~PythonImpl() { if(pyMain) { // clean up PyGILState_STATE gstate = PyGILState_Ensure(); for (int i = 0; i < nfunc; i++) { delete [] pfuncs[i].name; deallocate(i); PyObject *pFunc = (PyObject *) pfuncs[i].pFunc; Py_XDECREF(pFunc); } // shutdown Python interpreter if (!external_interpreter) { Py_Finalize(); } else { PyGILState_Release(gstate); } } memory->sfree(pfuncs); } /* ---------------------------------------------------------------------- */ void PythonImpl::command(int narg, char **arg) { if (narg < 2) error->all(FLERR,"Invalid python command"); // if invoke is only keyword, invoke the previously defined function if (narg == 2 && strcmp(arg[1],"invoke") == 0) { int ifunc = find(arg[0]); if (ifunc < 0) error->all(FLERR,"Python invoke of undefined function"); char *str = NULL; if (noutput) { str = input->variable->pythonstyle(pfuncs[ifunc].ovarname, pfuncs[ifunc].name); if (!str) error->all(FLERR,"Python variable does not match Python function"); } invoke_function(ifunc,str); return; } // if source is only keyword, execute the python code if (narg == 3 && strcmp(arg[1],"source") == 0) { + int err; - PyGILState_STATE gstate = PyGILState_Ensure(); - - // if argument string is file, open it - // otherwise process string as python code - - int err = 0; FILE *fp = fopen(arg[2],"r"); - if (fp == NULL) - err = PyRun_SimpleString(arg[2]); + err = execute_string(arg[2]); else - err = PyRun_SimpleFile(fp,arg[2]); + err = execute_file(arg[2]); - if (err) { - PyGILState_Release(gstate); - error->all(FLERR,"Could not process Python source command"); - } if (fp) fclose(fp); - PyGILState_Release(gstate); + if (err) error->all(FLERR,"Could not process Python source command"); + return; } // parse optional args, invoke is not allowed in this mode ninput = noutput = 0; istr = NULL; ostr = NULL; format = NULL; length_longstr = 0; char *pyfile = NULL; char *herestr = NULL; int existflag = 0; int iarg = 1; while (iarg < narg) { if (strcmp(arg[iarg],"input") == 0) { if (iarg+2 > narg) error->all(FLERR,"Invalid python command"); ninput = force->inumeric(FLERR,arg[iarg+1]); if (ninput < 0) error->all(FLERR,"Invalid python command"); iarg += 2; istr = new char*[ninput]; if (iarg+ninput > narg) error->all(FLERR,"Invalid python command"); for (int i = 0; i < ninput; i++) istr[i] = arg[iarg+i]; iarg += ninput; } else if (strcmp(arg[iarg],"return") == 0) { if (iarg+2 > narg) error->all(FLERR,"Invalid python command"); noutput = 1; ostr = arg[iarg+1]; iarg += 2; } else if (strcmp(arg[iarg],"format") == 0) { if (iarg+2 > narg) error->all(FLERR,"Invalid python command"); int n = strlen(arg[iarg+1]) + 1; format = new char[n]; strcpy(format,arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"length") == 0) { if (iarg+2 > narg) error->all(FLERR,"Invalid python command"); length_longstr = force->inumeric(FLERR,arg[iarg+1]); if (length_longstr <= 0) error->all(FLERR,"Invalid python command"); iarg += 2; } else if (strcmp(arg[iarg],"file") == 0) { if (iarg+2 > narg) error->all(FLERR,"Invalid python command"); delete[] pyfile; int n = strlen(arg[iarg+1]) + 1; pyfile = new char[n]; strcpy(pyfile,arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"here") == 0) { if (iarg+2 > narg) error->all(FLERR,"Invalid python command"); herestr = arg[iarg+1]; iarg += 2; } else if (strcmp(arg[iarg],"exists") == 0) { existflag = 1; iarg++; } else error->all(FLERR,"Invalid python command"); } if (pyfile && herestr) error->all(FLERR,"Invalid python command"); if (pyfile && existflag) error->all(FLERR,"Invalid python command"); if (herestr && existflag) error->all(FLERR,"Invalid python command"); // create or overwrite entry in pfuncs vector with name = arg[0] int ifunc = create_entry(arg[0]); PyGILState_STATE gstate = PyGILState_Ensure(); // send Python code to Python interpreter // file: read the file via PyRun_SimpleFile() // here: process the here string directly // exist: do nothing, assume code has already been run if (pyfile) { FILE *fp = fopen(pyfile,"r"); if (fp == NULL) { PyGILState_Release(gstate); error->all(FLERR,"Could not open Python file"); } int err = PyRun_SimpleFile(fp,pyfile); if (err) { PyGILState_Release(gstate); error->all(FLERR,"Could not process Python file"); } fclose(fp); } else if (herestr) { int err = PyRun_SimpleString(herestr); if (err) { PyGILState_Release(gstate); error->all(FLERR,"Could not process Python string"); } } // pFunc = function object for requested function PyObject *pModule = (PyObject *) pyMain; PyObject *pFunc = PyObject_GetAttrString(pModule,pfuncs[ifunc].name); if (!pFunc) { PyGILState_Release(gstate); error->all(FLERR,"Could not find Python function"); } if (!PyCallable_Check(pFunc)) { PyGILState_Release(gstate); error->all(FLERR,"Python function is not callable"); } pfuncs[ifunc].pFunc = (void *) pFunc; // clean-up input storage delete [] istr; delete [] format; delete [] pyfile; PyGILState_Release(gstate); } /* ------------------------------------------------------------------ */ void PythonImpl::invoke_function(int ifunc, char *result) { PyGILState_STATE gstate = PyGILState_Ensure(); PyObject *pValue; char *str; PyObject *pFunc = (PyObject *) pfuncs[ifunc].pFunc; // create Python tuple of input arguments int ninput = pfuncs[ifunc].ninput; PyObject *pArgs = PyTuple_New(ninput); if (!pArgs) { PyGILState_Release(gstate); error->all(FLERR,"Could not create Python function arguments"); } for (int i = 0; i < ninput; i++) { int itype = pfuncs[ifunc].itype[i]; if (itype == INT) { if (pfuncs[ifunc].ivarflag[i]) { str = input->variable->retrieve(pfuncs[ifunc].svalue[i]); if (!str) { PyGILState_Release(gstate); error->all(FLERR,"Could not evaluate Python function input variable"); } pValue = PY_INT_FROM_LONG(atoi(str)); } else { pValue = PY_INT_FROM_LONG(pfuncs[ifunc].ivalue[i]); } } else if (itype == DOUBLE) { if (pfuncs[ifunc].ivarflag[i]) { str = input->variable->retrieve(pfuncs[ifunc].svalue[i]); if (!str) { PyGILState_Release(gstate); error->all(FLERR,"Could not evaluate Python function input variable"); } pValue = PyFloat_FromDouble(atof(str)); } else { pValue = PyFloat_FromDouble(pfuncs[ifunc].dvalue[i]); } } else if (itype == STRING) { if (pfuncs[ifunc].ivarflag[i]) { str = input->variable->retrieve(pfuncs[ifunc].svalue[i]); if (!str) { PyGILState_Release(gstate); error->all(FLERR,"Could not evaluate Python function input variable"); } pValue = PY_STRING_FROM_STRING(str); } else { pValue = PY_STRING_FROM_STRING(pfuncs[ifunc].svalue[i]); } } else if (itype == PTR) { pValue = PY_VOID_POINTER(lmp); } PyTuple_SetItem(pArgs,i,pValue); } // call the Python function // error check with one() since only some procs may fail pValue = PyObject_CallObject(pFunc,pArgs); if (!pValue) { PyGILState_Release(gstate); error->one(FLERR,"Python function evaluation failed"); } Py_DECREF(pArgs); // function returned a value // assign it to result string stored by python-style variable // or if user specified a length, assign it to longstr if (pfuncs[ifunc].noutput) { int otype = pfuncs[ifunc].otype; if (otype == INT) { sprintf(result,"%ld",PY_INT_AS_LONG(pValue)); } else if (otype == DOUBLE) { sprintf(result,"%.15g",PyFloat_AsDouble(pValue)); } else if (otype == STRING) { char *pystr = PY_STRING_AS_STRING(pValue); if (pfuncs[ifunc].longstr) strncpy(pfuncs[ifunc].longstr,pystr,pfuncs[ifunc].length_longstr); else strncpy(result,pystr,VALUELENGTH-1); } Py_DECREF(pValue); } PyGILState_Release(gstate); } /* ------------------------------------------------------------------ */ int PythonImpl::find(char *name) { for (int i = 0; i < nfunc; i++) if (strcmp(name,pfuncs[i].name) == 0) return i; return -1; } /* ------------------------------------------------------------------ */ int PythonImpl::variable_match(char *name, char *varname, int numeric) { int ifunc = find(name); if (ifunc < 0) return -1; if (pfuncs[ifunc].noutput == 0) return -1; if (strcmp(pfuncs[ifunc].ovarname,varname) != 0) return -1; if (numeric && pfuncs[ifunc].otype == STRING) return -1; return ifunc; } /* ------------------------------------------------------------------ */ char *PythonImpl::long_string(int ifunc) { return pfuncs[ifunc].longstr; } /* ------------------------------------------------------------------ */ int PythonImpl::create_entry(char *name) { // ifunc = index to entry by name in pfuncs vector, can be old or new // free old vectors if overwriting old pfunc int ifunc = find(name); if (ifunc < 0) { ifunc = nfunc; nfunc++; pfuncs = (PyFunc *) memory->srealloc(pfuncs,nfunc*sizeof(struct PyFunc),"python:pfuncs"); int n = strlen(name) + 1; pfuncs[ifunc].name = new char[n]; strcpy(pfuncs[ifunc].name,name); } else deallocate(ifunc); pfuncs[ifunc].ninput = ninput; pfuncs[ifunc].noutput = noutput; if (!format && ninput+noutput) error->all(FLERR,"Invalid python command"); else if (format && strlen(format) != ninput+noutput) error->all(FLERR,"Invalid python command"); // process inputs as values or variables pfuncs[ifunc].itype = new int[ninput]; pfuncs[ifunc].ivarflag = new int[ninput]; pfuncs[ifunc].ivalue = new int[ninput]; pfuncs[ifunc].dvalue = new double[ninput]; pfuncs[ifunc].svalue = new char*[ninput]; for (int i = 0; i < ninput; i++) { pfuncs[ifunc].svalue[i] = NULL; char type = format[i]; if (type == 'i') { pfuncs[ifunc].itype[i] = INT; if (strstr(istr[i],"v_") == istr[i]) { pfuncs[ifunc].ivarflag[i] = 1; int n = strlen(&istr[i][2]) + 1; pfuncs[ifunc].svalue[i] = new char[n]; strcpy(pfuncs[ifunc].svalue[i],&istr[i][2]); } else { pfuncs[ifunc].ivarflag[i] = 0; pfuncs[ifunc].ivalue[i] = force->inumeric(FLERR,istr[i]); } } else if (type == 'f') { pfuncs[ifunc].itype[i] = DOUBLE; if (strstr(istr[i],"v_") == istr[i]) { pfuncs[ifunc].ivarflag[i] = 1; int n = strlen(&istr[i][2]) + 1; pfuncs[ifunc].svalue[i] = new char[n]; strcpy(pfuncs[ifunc].svalue[i],&istr[i][2]); } else { pfuncs[ifunc].ivarflag[i] = 0; pfuncs[ifunc].dvalue[i] = force->numeric(FLERR,istr[i]); } } else if (type == 's') { pfuncs[ifunc].itype[i] = STRING; if (strstr(istr[i],"v_") == istr[i]) { pfuncs[ifunc].ivarflag[i] = 1; int n = strlen(&istr[i][2]) + 1; pfuncs[ifunc].svalue[i] = new char[n]; strcpy(pfuncs[ifunc].svalue[i],&istr[i][2]); } else { pfuncs[ifunc].ivarflag[i] = 0; int n = strlen(istr[i]) + 1; pfuncs[ifunc].svalue[i] = new char[n]; strcpy(pfuncs[ifunc].svalue[i],istr[i]); } } else if (type == 'p') { pfuncs[ifunc].ivarflag[i] = 0; pfuncs[ifunc].itype[i] = PTR; if (strcmp(istr[i],"SELF") != 0) error->all(FLERR,"Invalid python command"); } else error->all(FLERR,"Invalid python command"); } // process output as value or variable pfuncs[ifunc].ovarname = NULL; pfuncs[ifunc].longstr = NULL; if (!noutput) return ifunc; char type = format[ninput]; if (type == 'i') pfuncs[ifunc].otype = INT; else if (type == 'f') pfuncs[ifunc].otype = DOUBLE; else if (type == 's') pfuncs[ifunc].otype = STRING; else error->all(FLERR,"Invalid python command"); if (length_longstr) { if (pfuncs[ifunc].otype != STRING) error->all(FLERR,"Python command length keyword " "cannot be used unless output is a string"); pfuncs[ifunc].length_longstr = length_longstr; pfuncs[ifunc].longstr = new char[length_longstr+1]; } if (strstr(ostr,"v_") != ostr) error->all(FLERR,"Invalid python command"); int n = strlen(&ostr[2]) + 1; pfuncs[ifunc].ovarname = new char[n]; strcpy(pfuncs[ifunc].ovarname,&ostr[2]); return ifunc; } +/* ---------------------------------------------------------------------- */ + +int PythonImpl::execute_string(char *cmd) +{ + PyGILState_STATE gstate = PyGILState_Ensure(); + int err = PyRun_SimpleString(cmd); + PyGILState_Release(gstate); + + return err; +} + +/* ---------------------------------------------------------------------- */ + +int PythonImpl::execute_file(char *fname) +{ + FILE *fp = fopen(fname,"r"); + if (fp == NULL) return -1; + + PyGILState_STATE gstate = PyGILState_Ensure(); + int err = PyRun_SimpleFile(fp,fname); + PyGILState_Release(gstate); + + if (fp) fclose(fp); + return err; +} + /* ------------------------------------------------------------------ */ void PythonImpl::deallocate(int i) { delete [] pfuncs[i].itype; delete [] pfuncs[i].ivarflag; delete [] pfuncs[i].ivalue; delete [] pfuncs[i].dvalue; for (int j = 0; j < pfuncs[i].ninput; j++) delete [] pfuncs[i].svalue[j]; delete [] pfuncs[i].svalue; delete [] pfuncs[i].ovarname; delete [] pfuncs[i].longstr; } diff --git a/src/PYTHON/python_impl.h b/src/PYTHON/python_impl.h index 07975b3fd..efe43edbd 100644 --- a/src/PYTHON/python_impl.h +++ b/src/PYTHON/python_impl.h @@ -1,130 +1,132 @@ /* -*- c++ -*- ---------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ #ifndef LMP_PYTHON_IMPL_H #define LMP_PYTHON_IMPL_H #include "pointers.h" namespace LAMMPS_NS { class PythonImpl : protected Pointers, public PythonInterface { public: bool external_interpreter; PythonImpl(class LAMMPS *); ~PythonImpl(); void command(int, char **); void invoke_function(int, char *); int find(char *); int variable_match(char *, char *, int); char *long_string(int); + int execute_string(char *); + int execute_file(char *); private: int ninput,noutput,length_longstr; char **istr; char *ostr,*format; void *pyMain; struct PyFunc { char *name; int ninput,noutput; int *itype,*ivarflag; int *ivalue; double *dvalue; char **svalue; int otype; char *ovarname; char *longstr; int length_longstr; void *pFunc; }; PyFunc *pfuncs; int nfunc; int create_entry(char *); void deallocate(int); }; } #endif /* ERROR/WARNING messages: E: Invalid python command Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. E: Python invoke of undefined function Cannot invoke a function that has not been previously defined. E: Python variable does not match Python function This matching is defined by the python-style variable and the python command. E: Cannot embed Python when also extending Python with LAMMPS When running LAMMPS via Python through the LAMMPS library interface you cannot also user the input script python command. E: Could not initialize embedded Python The main module in Python was not accessible. E: Could not open Python file The specified file of Python code cannot be opened. Check that the path and name are correct. E: Could not process Python file The Python code in the specified file was not run successfully by Python, probably due to errors in the Python code. E: Could not process Python string The Python code in the here string was not run successfully by Python, probably due to errors in the Python code. E: Could not find Python function The provided Python code was run successfully, but it not define a callable function with the required name. E: Python function is not callable The provided Python code was run successfully, but it not define a callable function with the required name. E: Could not create Python function arguments This is an internal Python error, possibly because the number of inputs to the function is too large. E: Could not evaluate Python function input variable Self-explanatory. E: Python function evaluation failed The Python function did not run successfully and/or did not return a value (if it is supposed to return a value). This is probably due to some error condition in the function. */ diff --git a/src/python.cpp b/src/python.cpp index fa1639b07..e32e2a161 100644 --- a/src/python.cpp +++ b/src/python.cpp @@ -1,99 +1,115 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ #include "python.h" #include "error.h" using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ Python::Python(LAMMPS *lmp) : Pointers(lmp) { // implementation of Python interface is only loaded on demand // and only if PYTHON package has been installed and compiled into binary impl = NULL; } /* ---------------------------------------------------------------------- */ Python::~Python() { delete impl; } /* ---------------------------------------------------------------------- */ PythonInterface::~PythonInterface() { } /* ---------------------------------------------------------------------- */ void Python::init() { #if LMP_PYTHON if (!impl) impl = new PythonImpl(lmp); #else error->all(FLERR,"Python support missing! Compile with PYTHON package installed!"); #endif } /* ---------------------------------------------------------------------- */ bool Python::is_enabled() const { #if LMP_PYTHON return true; #else return false; #endif } /* ---------------------------------------------------------------------- */ void Python::command(int narg, char **arg) { init(); impl->command(narg, arg); } /* ------------------------------------------------------------------ */ void Python::invoke_function(int ifunc, char *result) { init(); impl->invoke_function(ifunc, result); } /* ------------------------------------------------------------------ */ int Python::find(char *name) { init(); return impl->find(name); } /* ------------------------------------------------------------------ */ int Python::variable_match(char *name, char *varname, int numeric) { init(); return impl->variable_match(name, varname, numeric); } /* ------------------------------------------------------------------ */ char * Python::long_string(int ifunc) { init(); return impl->long_string(ifunc); } + +/* ------------------------------------------------------------------ */ + +int Python::execute_string(char *cmd) +{ + init(); + return impl->execute_string(cmd); +} + +/* ------------------------------------------------------------------ */ + +int Python::execute_file(char *fname) +{ + init(); + return impl->execute_file(fname); +} diff --git a/src/python.h b/src/python.h index 73f635460..190fd6ddb 100644 --- a/src/python.h +++ b/src/python.h @@ -1,123 +1,127 @@ /* -*- c++ -*- ---------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ #ifndef LMP_PYTHON_H #define LMP_PYTHON_H #include "pointers.h" namespace LAMMPS_NS { class PythonInterface { public: virtual ~PythonInterface(); virtual void command(int, char **) = 0; virtual void invoke_function(int, char *) = 0; virtual int find(char *) = 0; virtual int variable_match(char *, char *, int) = 0; virtual char * long_string(int ifunc) = 0; + virtual int execute_string(char *) = 0; + virtual int execute_file(char *) = 0; }; class Python : protected Pointers { public: Python(class LAMMPS *); ~Python(); void command(int, char **); void invoke_function(int, char *); int find(char *); int variable_match(char *, char *, int); char * long_string(int ifunc); + int execute_string(char *); + int execute_file(char *); bool is_enabled() const; void init(); private: PythonInterface * impl; }; } #endif #if LMP_PYTHON #include "python_impl.h" #endif /* ERROR/WARNING messages: E: Invalid python command Self-explanatory. Check the input script syntax and compare to the documentation for the command. You can use -echo screen as a command-line option when running LAMMPS to see the offending line. E: Python invoke of undefined function Cannot invoke a function that has not been previously defined. E: Python variable does not match Python function This matching is defined by the python-style variable and the python command. E: Cannot embed Python when also extending Python with LAMMPS When running LAMMPS via Python through the LAMMPS library interface you cannot also user the input script python command. E: Could not initialize embedded Python The main module in Python was not accessible. E: Could not open Python file The specified file of Python code cannot be opened. Check that the path and name are correct. E: Could not process Python file The Python code in the specified file was not run successfully by Python, probably due to errors in the Python code. E: Could not process Python string The Python code in the here string was not run successfully by Python, probably due to errors in the Python code. E: Could not find Python function The provided Python code was run successfully, but it not define a callable function with the required name. E: Python function is not callable The provided Python code was run successfully, but it not define a callable function with the required name. E: Could not create Python function arguments This is an internal Python error, possibly because the number of inputs to the function is too large. E: Could not evaluate Python function input variable Self-explanatory. E: Python function evaluation failed The Python function did not run successfully and/or did not return a value (if it is supposed to return a value). This is probably due to some error condition in the function. */