<commit_before>#ifndef _PETSC_PYTHON_H
#define _PETSC_PYTHON_H

/* -------------------------------------------------------------------------- */

#include <petsc.h>

#if !defined(PETSC_USE_ERRORCHECKING)
#undef  SETERRQ
#define SETERRQ(n,s)                     return(n)
#undef  SETERRQ1
#define SETERRQ1(n,s,a1)                 return(n)
#undef  SETERRQ2
#define SETERRQ2(n,s,a1,a2)              return(n)
#undef  SETERRQ3
#define SETERRQ3(n,s,a1,a2,a3)           return(n)
#undef  SETERRQ4
#define SETERRQ4(n,s,a1,a2,a3,a4)        return(n)
#undef  SETERRQ5
#define SETERRQ5(n,s,a1,a2,a3,a4,a5)     return(n)
#undef  SETERRQ6
#define SETERRQ6(n,s,a1,a2,a3,a4,a5,a6)  return(n)
#undef  CHKERRQ
#define CHKERRQ(n)                       if(n)return(n)
#endif

#include <petsc4py/petsc4py.h>

#ifdef import_petsc
#define import_petsc4py() \
  (import_petsc(),(PyErr_Occurred()?-1:0))
#define PyPetscViewer_New  PyPetscViewer->Arg
#define PyPetscVec_New     PyPetscVec->Arg
#define PyPetscMat_New     PyPetscMat->Arg
#define PyPetscPC_New      PyPetscPC->Arg
#define PyPetscKSP_New     PyPetscKSP->Arg
#define PyPetscSNES_New    PyPetscSNES->Arg
#define PyPetscTS_New      PyPetscTS->Arg
#endif

#ifndef PETSC_ERR_PYTHON
#define PETSC_ERR_PYTHON (-1)
#endif

/* -------------------------------------------------------------------------- */

#if PY_VERSION_HEX < 0x02050000
#define PetscPyExceptionClassCheck(exc) PyClass_Check((exc))
#define PetscPyExceptionClassName(exc)  PyString_AsString(((PyClassObject*)(exc))->cl_name)
#else
#define PetscPyExceptionClassCheck(exc) PyExceptionClass_Check((exc))
#define PetscPyExceptionClassName(exc)  PyExceptionClass_Name((exc))
#endif

#if PY_VERSION_HEX < 0x02050000
#define PetscPyImportModule(modname) PyImport_ImportModule((char *)(modname));
#define PetscPyObjectGetAttrStr(ob,attr) PyObject_GetAttrString((ob),(char *)(attr))
#else
#define PetscPyImportModule(modname) PyImport_ImportModule((modname));
#define PetscPyObjectGetAttrStr(ob,attr) PyObject_GetAttrString((ob),(attr))
#endif

/* -------------------------------------------------------------------------- */

static const char * PetscPythonHandleError(void)
{
  static char ExcName[256];
  PyObject*   ExcType = PyErr_Occurred();
  PyOS_snprintf(ExcName, sizeof(ExcName), "%s", "<unknown>");
  if (ExcType){
    if (PetscPyExceptionClassCheck(ExcType)) {
      const char *name = PetscPyExceptionClassName(ExcType);
      if (name != NULL) {
	const char *dot = strrchr(name, '.');
	if (dot != NULL) name = dot+1;
	PyOS_snprintf(ExcName, sizeof(ExcName), "%s", name);
      }
    }
    {
      PyObject *exc,*val,*tb;
      PyErr_Fetch(&exc,&val,&tb);
      PyErr_NormalizeException(&exc, &val, &tb);
      PyErr_Display(exc ? exc : Py_None,
		    val ? val : Py_None,
		    tb  ? tb  : Py_None);
      PyErr_Restore(exc,val,tb);
    }
  }
  return ExcName;
}

/* -------------------------------------------------------------------------- */

#undef __FUNCT__
#define __FUNCT__ "Petsc4PyInitialize"
static PetscErrorCode Petsc4PyInitialize(void)
{
  static PetscTruth initialized = PETSC_FALSE;
  PetscErrorCode ierr;
  PetscFunctionBegin;
  if (initialized) PetscFunctionReturn(0);
  if (import_petsc4py() < 0) goto fail;
  initialized = PETSC_TRUE;
  PetscFunctionReturn(0);
 fail:
  PetscPythonHandleError();
  SETERRQ(PETSC_ERR_PYTHON,"could not import Python package 'petsc4py.PETSc'");
  PetscFunctionReturn(ierr);
}

/* -------------------------------------------------------------------------- */

#define PETSC_PYTHON_CALL_HEAD(PySelf, PyMethod)			\
do {									\
  PyObject   *_self = PySelf;						\
  const char *_meth = PyMethod;						\
  PyObject   *_call = NULL;						\
  PyObject   *_args = NULL;						\
  PyObject   *_retv = NULL;						\
  if (!Py_IsInitialized()) {						\
    SETERRQ(PETSC_ERR_LIB,"Python is not initialized");			\
    PetscFunctionReturn(PETSC_ERR_PYTHON);				\
  }									\
  do {									\
    if (_self != NULL && _self != Py_None) {				\
      _call = PetscPyObjectGetAttrStr(_self, _meth);			\
      if      (_call == NULL)    { PyErr_Clear(); }			\
      else if (_call == Py_None) { Py_DecRef(_call); _call = NULL; }	\
    }									\
  } while(0)								\
/**/

#define PETSC_PYTHON_CALL_JUMP(LABEL)					\
  do { if (_call == NULL) goto LABEL; } while(0)			\
/**/
 
#define PETSC_PYTHON_CALL_BODY(Py_BV_ARGS)				\
  if (_call != NULL) {							\
    do {								\
      _args = Py_BuildValue Py_BV_ARGS;					\
      if (_args != NULL) {						\
	if (_args == Py_None)						\
	  _retv = PyObject_CallObject(_call, NULL);			\
	else if (PyTuple_CheckExact(_args))				\
	  _retv = PyObject_CallObject(_call, _args);			\
	else								\
	  _retv = PyObject_CallFunctionObjArgs(_call, _args, NULL);	\
	Py_DecRef(_args); _args = NULL;					\
      }									\
      Py_DecRef(_call); _call = NULL;					\
    } while(0)								\
/**/

#define PETSC_PYTHON_CALL_TAIL()					\
    if (_retv == NULL) {						\
      const char *_exc = PetscPythonHandleError();			\
      SETERRQ2(PETSC_ERR_PYTHON,"calling Python, "			\
	       "method %s(), exception '%s'", _meth, _exc);		\<commit_msg>Custom equivalent to Py_BuildValue for Python 2.4 and below<commit_after>#ifndef _PETSC_PYTHON_H
#define _PETSC_PYTHON_H

/* -------------------------------------------------------------------------- */

#include <petsc.h>

#if !defined(PETSC_USE_ERRORCHECKING)
#undef  SETERRQ
#define SETERRQ(n,s)                     return(n)
#undef  SETERRQ1
#define SETERRQ1(n,s,a1)                 return(n)
#undef  SETERRQ2
#define SETERRQ2(n,s,a1,a2)              return(n)
#undef  SETERRQ3
#define SETERRQ3(n,s,a1,a2,a3)           return(n)
#undef  SETERRQ4
#define SETERRQ4(n,s,a1,a2,a3,a4)        return(n)
#undef  SETERRQ5
#define SETERRQ5(n,s,a1,a2,a3,a4,a5)     return(n)
#undef  SETERRQ6
#define SETERRQ6(n,s,a1,a2,a3,a4,a5,a6)  return(n)
#undef  CHKERRQ
#define CHKERRQ(n)                       if(n)return(n)
#endif

#include <petsc4py/petsc4py.h>

#ifdef import_petsc
#define import_petsc4py() \
  (import_petsc(),(PyErr_Occurred()?-1:0))
#define PyPetscViewer_New  PyPetscViewer->Arg
#define PyPetscVec_New     PyPetscVec->Arg
#define PyPetscMat_New     PyPetscMat->Arg
#define PyPetscPC_New      PyPetscPC->Arg
#define PyPetscKSP_New     PyPetscKSP->Arg
#define PyPetscSNES_New    PyPetscSNES->Arg
#define PyPetscTS_New      PyPetscTS->Arg
#endif

#ifndef PETSC_ERR_PYTHON
#define PETSC_ERR_PYTHON (-1)
#endif

/* -------------------------------------------------------------------------- */

#if PY_VERSION_HEX < 0x02050000
#define PetscPyExceptionClassCheck(exc) PyClass_Check((exc))
#define PetscPyExceptionClassName(exc)  PyString_AsString(((PyClassObject*)(exc))->cl_name)
#else
#define PetscPyExceptionClassCheck(exc) PyExceptionClass_Check((exc))
#define PetscPyExceptionClassName(exc)  PyExceptionClass_Name((exc))
#endif

#if PY_VERSION_HEX < 0x02050000
#define PetscPyImportModule(modname) PyImport_ImportModule((char *)(modname));
#define PetscPyObjectGetAttrStr(ob,attr) PyObject_GetAttrString((ob),(char *)(attr))
#else
#define PetscPyImportModule(modname) PyImport_ImportModule((modname));
#define PetscPyObjectGetAttrStr(ob,attr) PyObject_GetAttrString((ob),(attr))
#endif

#if PY_VERSION_HEX < 0x02050000
static PyObject* PetscPythonBuildValue(const char *format, ...)
{
  va_list va;
  PyObject* retval;
  va_start(va, format);
  retval = Py_VaBuildValue((char *)format, va);
  va_end(va);
  return retval;
}
#else
#define PetscPythonBuildValue Py_BuildValue
#endif

/* -------------------------------------------------------------------------- */

static const char * PetscPythonHandleError(void)
{
  static char ExcName[256];
  PyObject*   ExcType = PyErr_Occurred();
  PyOS_snprintf(ExcName, sizeof(ExcName), "%s", "<unknown>");
  if (ExcType){
    if (PetscPyExceptionClassCheck(ExcType)) {
      const char *name = PetscPyExceptionClassName(ExcType);
      if (name != NULL) {
	const char *dot = strrchr(name, '.');
	if (dot != NULL) name = dot+1;
	PyOS_snprintf(ExcName, sizeof(ExcName), "%s", name);
      }
    }
    {
      PyObject *exc,*val,*tb;
      PyErr_Fetch(&exc,&val,&tb);
      PyErr_NormalizeException(&exc, &val, &tb);
      PyErr_Display(exc ? exc : Py_None,
		    val ? val : Py_None,
		    tb  ? tb  : Py_None);
      PyErr_Restore(exc,val,tb);
    }
  }
  return ExcName;
}

/* -------------------------------------------------------------------------- */

#undef __FUNCT__
#define __FUNCT__ "Petsc4PyInitialize"
static PetscErrorCode Petsc4PyInitialize(void)
{
  static PetscTruth initialized = PETSC_FALSE;
  PetscErrorCode ierr;
  PetscFunctionBegin;
  if (initialized) PetscFunctionReturn(0);
  if (import_petsc4py() < 0) goto fail;
  initialized = PETSC_TRUE;
  PetscFunctionReturn(0);
 fail:
  PetscPythonHandleError();
  SETERRQ(PETSC_ERR_PYTHON,"could not import Python package 'petsc4py.PETSc'");
  PetscFunctionReturn(ierr);
}

/* -------------------------------------------------------------------------- */

#define PETSC_PYTHON_CALL_HEAD(PySelf, PyMethod)			\
do {									\
  PyObject   *_self = PySelf;						\
  const char *_meth = PyMethod;						\
  PyObject   *_call = NULL;						\
  PyObject   *_args = NULL;						\
  PyObject   *_retv = NULL;						\
  if (!Py_IsInitialized()) {						\
    SETERRQ(PETSC_ERR_LIB,"Python is not initialized");			\
    PetscFunctionReturn(PETSC_ERR_PYTHON);				\
  }									\
  do {									\
    if (_self != NULL && _self != Py_None) {				\
      _call = PetscPyObjectGetAttrStr(_self, _meth);			\
      if      (_call == NULL)    { PyErr_Clear(); }			\
      else if (_call == Py_None) { Py_DecRef(_call); _call = NULL; }	\
    }									\
  } while(0)								\
/**/

#define PETSC_PYTHON_CALL_JUMP(LABEL)					\
  do { if (_call == NULL) goto LABEL; } while(0)			\
/**/
 
#define PETSC_PYTHON_CALL_BODY(Py_BV_ARGS)				\
  if (_call != NULL) {							\
    do {								\
      _args = PetscPythonBuildValue Py_BV_ARGS;				\
      if (_args != NULL) {						\
	if (_args == Py_None)						\
	  _retv = PyObject_CallObject(_call, NULL);			\
	else if (PyTuple_CheckExact(_args))				\
	  _retv = PyObject_CallObject(_call, _args);			\
	else								\
	  _retv = PyObject_CallFunctionObjArgs(_call, _args, NULL);	\
	Py_DecRef(_args); _args = NULL;					\
      }									\
      Py_DecRef(_call); _call = NULL;					\
    } while(0)								\
/**/

#define PETSC_PYTHON_CALL_TAIL()					\
    if (_retv == NULL) {						\
      const char *_exc = PetscPythonHandleError();			\
      SETERRQ2(PETSC_ERR_PYTHON,"calling Python, "			\
	       "method %s(), exception '%s'", _meth, _exc);		\
{'fraction_non_alphanumeric': 0.1928450066075137, 'fraction_numerical': 0.014630923164055126, 'mean_word_length': 2.5316666666666667, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4203739', 'n_tokens_mistral': 4245, 'n_tokens_neox': 3908, 'n_words': 676}