Exemple #1
0
static void
mu_port_alloc_buffer (SCM port, size_t read_size, size_t write_size)
{
  scm_port *pt = SCM_PTAB_ENTRY (port);
  static char *s_mu_port_alloc_buffer = "mu_port_alloc_buffer";
  
  if (!read_size)
    read_size = DEFAULT_BUF_SIZE;
  if (!write_size)
    write_size = DEFAULT_BUF_SIZE;

  if (SCM_INPUT_PORT_P (port))
    {
      pt->read_buf = malloc (read_size);
      if (pt->read_buf == NULL)
	scm_memory_error (s_mu_port_alloc_buffer);
      pt->read_pos = pt->read_end = pt->read_buf;
      pt->read_buf_size = read_size;
    }
  else
    {
      pt->read_pos = pt->read_buf = pt->read_end = &pt->shortbuf;
      pt->read_buf_size = 1;
    }
  
  if (SCM_OUTPUT_PORT_P (port))
    {
      pt->write_buf = malloc (write_size);
      if (pt->write_buf == NULL)
	scm_memory_error (s_mu_port_alloc_buffer);
      pt->write_pos = pt->write_buf;
      pt->write_buf_size = write_size;
      pt->write_end = pt->write_buf + pt->write_buf_size;
    }
  else
    {
      pt->write_buf = pt->write_pos = &pt->shortbuf;
      pt->write_buf_size = 1;
    }
  
  SCM_SET_CELL_WORD_0 (port, SCM_CELL_WORD_0 (port) & ~SCM_BUF0);
}
Exemple #2
0
static int
pyscm_PySCM_print(pyscm_PySCMObject *self, FILE *fp, int flags)
{
  PyObject *pstr = pyscm_PySCM_str(self);
  if (NULL == pstr) {
    scm_memory_error("pyscm_PySCM_print");
  }
  int retval = PyObject_Print(pstr,fp,flags);
  Py_DECREF(pstr);
  return(retval);
}
Exemple #3
0
// Create a pyscm_PySCMObject instance, which wraps sobj and associates
// with it with template for data conversions when python accesses data
// and functions/methods associated with sobj.
PyObject *
wrap_scm(SCM sobj,SCM stemplate)
{
  if (pyguile_verbosity_test(PYGUILE_VERBOSE_PYSCM)) {
    scm_simple_format(scm_current_output_port(),scm_makfrom0str("# wrap_scm: was called to wrap ~S\n"),scm_list_1(sobj));
  }
  pyscm_PySCMObject *pwrapper = PyObject_New(pyscm_PySCMObject,&pyscm_PySCMType);
  if (NULL == pwrapper) {
    scm_memory_error("wrap_scm");  // NOT COVERED BY TESTS
  }
  //PyObject_Init(pwrapper,&pyscm_PySCMType);  // Is it needed or does PyObject_New() take care of it?
  //if (NULL == pwrapper) {
  //  scm_misc_error("wrap_scm","could not wrap object ~S with PySCM when using conversion template ~S",
  //		   scm_list_2(sobj,stemplate));
  //}
  else {
    SCM sconsed = scm_cons(sobj,stemplate);
    SCM shashkey = scm_long2num(++pyscm_registration_index);
    scm_hashv_create_handle_x(pyscm_registration_hash,shashkey,sconsed);
    pwrapper->ob_scm_index = pyscm_registration_index;
    return((PyObject *)pwrapper);
  }
}
Exemple #4
0
// python_apply implements the function call:
// (python-apply ("module.submodule" 'obj 'func)
//               (arg1 arg2 arg3)
//               (('keyword1 . val4) ('keyword2 . val5))
//               sargtemplate
//               skwtemplate)
// which is the basic way to invoke a Python function.
//
// sfunc specifies the function to be invoked.  The possibilities
// are:
//   String - denotes a top level function ("func" means __main__.func).
//   pysmob - assumed to be a callable object.
//   ("module.submodule" ...) - a List of strings/symbols/keywords
//     in which the first item must be a string denotes:
//     Module "module.submodule" (which should have already been imported
//       using python-import)
//     followed by name of object in that module, followed by attribute,...,
//     until the final callable attribute.
//   (pysmob ...) - a List starting with pysmob followed by
//     strings/symbols/keywords - processed similarly, except that the
//     pysmob stands for the module.
// sarg is a list of arguments (in Python it's *arg)
// skw is an alist (in Python it's **kw).
// sargtemplate - specifies how to convert sarg - optional argument.
// skwtemplate - specifies how to convert skw - optional argument.
// srestemplate - specifies how to convert the result back into
//     SCM - optional argument.
SCM
python_apply(SCM sfunc, SCM sarg, SCM skw,
	     SCM sargtemplate, SCM skwtemplate,	SCM srestemplate)
{
  PyObject *pfunc = NULL;
  PyObject *parg = NULL;
  PyObject *pkw = NULL;

  PyObject *pfuncobj = NULL;
  PyObject *pres = NULL;
  SCM sres = SCM_UNDEFINED;

  if (SCM_UNBNDP(sargtemplate)) { //(sargtemplate == SCM_UNDEFINED) // SCM_UNSPECIFIED
    sargtemplate = sargtemplate_default;
  }
  if (SCM_UNBNDP(skwtemplate)) {
    skwtemplate = skwtemplate_default;
  }
  if (SCM_UNBNDP(srestemplate)) {
    srestemplate = srestemplate_default;
  }

  // Retrieve the function object.

  pfunc = guile2python(sfunc,SCM_UNSPECIFIED);
  if (pyguile_verbosity_test(PYGUILE_VERBOSE_PYTHON_APPLY)) {
    char *preprfunc = PyString_AsString(PyObject_Repr(pfunc));
    scm_simple_format(scm_current_output_port(),scm_makfrom0str("# python_apply: decoded pfunc ~S\n"),scm_list_1(scm_makfrom0str(preprfunc)));
  }
  if (NULL == pfunc) {
    scm_misc_error("python-apply","conversion failure (~S)",
		   scm_list_1(SCM_CDR(sfunc)));
  }
  // If it is a string, prepend it with "__main__".
  if (PyString_CheckExact(pfunc)) {
    // Convert it into a List of two items, to unify
    // subsequent treatment.
    PyObject *plist = PyList_New(2);
    if (NULL == plist) {
      Py_DECREF(pfunc);  // NOT COVERED BY TESTS
      scm_memory_error("python-apply");  // NOT COVERED BY TESTS
    }
    if (-1 == PyList_SetItem(plist,0,PyString_FromString("__main__"))) {
      Py_DECREF(pfunc);  // NOT COVERED BY TESTS
      Py_DECREF(plist);  // NOT COVERED BY TESTS
      scm_misc_error("python-apply","PyList_SetItem 0 failure (~S)",  // NOT COVERED BY TESTS
		     scm_list_1(SCM_CAR(sfunc)));
    }
    if (-1 == PyList_SetItem(plist,1,pfunc)) {
      Py_DECREF(pfunc);  // NOT COVERED BY TESTS
      Py_DECREF(plist);  // NOT COVERED BY TESTS
      scm_misc_error("python-apply","PyList_SetItem 1 failure (~S)",  // NOT COVERED BY TESTS
		     scm_list_1(SCM_CAR(sfunc)));
    }
    pfunc = plist;  // plist stole previous pfunc's value's reference.
  }
  else if (IS_PYSMOBP(sfunc)) {
    // We check the SCM object because guile2python() destroys
    // the indication whether the SCM was originally a pysmob, when it
    // converts it into PyObject.
    PyObject *plist1 = PyList_New(1);
    if (NULL == plist1) {
      Py_DECREF(pfunc);  // NOT COVERED BY TESTS
      scm_memory_error("python-apply");  // NOT COVERED BY TESTS
    }
    if (-1 == PyList_SetItem(plist1,0,pfunc)) {
      Py_DECREF(pfunc);  // NOT COVERED BY TESTS
      Py_DECREF(plist1);  // NOT COVERED BY TESTS
      scm_misc_error("python-apply","PyList_SetItem 0 failure (~S)",  // NOT COVERED BY TESTS
		     scm_list_1(SCM_CAR(sfunc)));
    }
    pfunc = plist1;  // plist1 stole previous pfunc's value's reference.
    // Now pfunc is an 1-member list, and this member is
    // expected to be callable.
  }
  else if (!PyList_CheckExact(pfunc)) {
    // Now, the qualified function name must be a proper list.
    scm_wrong_type_arg("python-apply",SCM_ARG1,sfunc);
  }

  if (1 > PyList_Size(pfunc)) {
    // The list must consist of at least one callable module name/object.
    scm_misc_error("python-apply",
		   "first argument must contain at least one callable object (~S)",
		   scm_list_1(SCM_CAR(sfunc)));
  }

  if (PyString_CheckExact(PyList_GetItem(pfunc,0))) {
    // If it is a string, we assume it to be the name of a module
    // which has already been imported.
    // Due to the existence of dots, 
    // we don't allow it to be symbol or keyword.

    pfuncobj = PyImport_AddModule(PyString_AsString(PyList_GetItem(pfunc,0)));
    if (NULL == pfuncobj) {
      Py_DECREF(pfunc);
      scm_misc_error("python-apply",
		     "module ~S could not be accessed - probably not imported",
		     scm_list_1(SCM_CAR(sfunc)));
    }
    Py_INCREF(pfuncobj);
  }
  else {
    // We assume that it is a callable or object with attributes.
    pfuncobj = PyList_GetItem(pfunc,0);
    if (NULL == pfuncobj) {
      Py_DECREF(pfunc);
      scm_misc_error("python-apply",
		     "could not access object starting ~S",
		     scm_list_1(sfunc));
    }
    Py_INCREF(pfuncobj);
  }

  // Here we dereference attributes (if any).
  int listsize = PyList_Size(pfunc);
  int ind;

  for (ind = 1; ind < listsize; ++ind) {
    PyObject *pnextobj = PyObject_GetAttr(pfuncobj,PyList_GetItem(pfunc,ind));
    if (NULL == pnextobj) {
      PyObject *pexception = PyErr_Occurred();
      Py_DECREF(pfunc);
      Py_DECREF(pfuncobj);
      if (pexception) {
	PyErr_Clear();
	// An AttributeError exception is expected here.
	if (!PyErr_GivenExceptionMatches(pexception,PyExc_AttributeError)) {
	  PyObject *prepr = PyObject_Repr(pexception);
	  if (NULL == prepr) {
	    scm_misc_error("python-apply",
			   "python exception - could not be identified",
			   SCM_UNSPECIFIED);
	  }
	  else {
	    int strlength = PyString_Size(prepr);
	    char *pstr = PyString_AsString(prepr);
	    SCM srepr = scm_list_1(scm_mem2string(pstr,strlength));
	    Py_DECREF(prepr);
	    scm_misc_error("python-apply",
			   "Python exception (~A) while dereferencing object attribute",
			   srepr);
	  }
	}
	// else we got the expected AttributeError exception.
      }
      // else we got NULL==pnextobj without Python exception.
      scm_misc_error("python-apply",
		     "could not dereference ~Ath level attribute in ~S",
		     scm_list_2(scm_long2num(ind),sfunc));
    }
    Py_INCREF(pnextobj);
    Py_DECREF(pfuncobj);
    pfuncobj = pnextobj;
  }
  Py_DECREF(pfunc);  // We do not need it anymore.  pfuncobj points at
                     // the function actually to be invoked.
  if (!PyCallable_Check(pfuncobj)) {
    Py_DECREF(pfuncobj);
    scm_misc_error("python-apply","function denoted by ~S is not callable",scm_list_1(sfunc));
  }

  if (pyguile_verbosity_test(PYGUILE_VERBOSE_PYTHON_APPLY)) {
    char *preprfuncobj = PyString_AsString(PyObject_Repr(pfuncobj));
    scm_simple_format(scm_current_output_port(),
		      scm_makfrom0str("# python_apply: decoded function actually to be invoked: ~S\n"),
		      scm_list_1(scm_makfrom0str(preprfuncobj)));
  }

  // Retrieve positional arguments

  parg = g2p_apply(sarg,sargtemplate);
  if (NULL == parg) {
    Py_DECREF(pfuncobj);
    scm_misc_error("python-apply","positional arguments conversion failure (~S)",
		   scm_list_1(sarg));
  }
  // Validate that it is indeed a tuple.
  if (!PyTuple_CheckExact(parg)) {
    Py_DECREF(pfuncobj);
    Py_DECREF(parg);
    scm_wrong_type_arg("python-apply",SCM_ARG2,sarg);
  }
  if (pyguile_verbosity_test(PYGUILE_VERBOSE_PYTHON_APPLY)) {
    char *pposarg = PyString_AsString(PyObject_Repr(parg));
    scm_simple_format(scm_current_output_port(),scm_makfrom0str("# python_apply: decoded positional arguments ~S\n"),scm_list_1(scm_makfrom0str(pposarg)));
  }

  // Retrieve keyword arguments.

  pkw = guileassoc2pythondict(skw,skwtemplate);
  if (NULL == pkw) {
    // Seems that PyDict_CheckExact() does not handle NULL argument gracefully.
     Py_DECREF(pfuncobj);
     Py_DECREF(parg);
     scm_misc_error("python-apply","keyword arguments conversion failure (~S)",
		    scm_list_1(skw));
  }
  if (!PyDict_CheckExact(pkw)) {
     Py_DECREF(pfuncobj);
     Py_DECREF(parg);
     Py_DECREF(pkw);
     scm_misc_error("python-apply",
		    "keyword arguments (~S) not properly converted into Python Dict",
		    scm_list_1(skw));
  }
  if (pyguile_verbosity_test(PYGUILE_VERBOSE_PYTHON_APPLY)) {
    char *pkwarg = PyString_AsString(PyObject_Repr(pkw));
    scm_simple_format(scm_current_output_port(),scm_makfrom0str("# python_apply: decoded keyword arguments ~S\n"),scm_list_1(scm_makfrom0str(pkwarg)));
  }

  // Ready to invoke the function.

  pres = PyEval_CallObjectWithKeywords(pfuncobj,parg,pkw);
  PyObject *pexception = PyErr_Occurred();
  if (pexception) {
    PyObject *prepr = PyObject_Repr(pexception);
    Py_DECREF(pfuncobj);
    Py_DECREF(parg);
    Py_DECREF(pkw);
    Py_XDECREF(pres);
    PyErr_Clear();
    if (NULL == prepr) {
      scm_misc_error("python-apply",
		     "python exception - could not be identified",
		     SCM_UNSPECIFIED);
    }
    else {
      int strlength = PyString_Size(prepr);
      char *pstr = PyString_AsString(prepr);
      SCM srepr = scm_list_1(scm_mem2string(pstr,strlength));
      Py_DECREF(prepr);
      scm_misc_error("python-apply","Python exception: ~A",
		     srepr);
    }
  }
  if (NULL != pres) {
    sres = p2g_apply(pres,srestemplate);
    if (pyguile_verbosity_test(PYGUILE_VERBOSE_PYTHON_APPLY)) {
      char *presstr = PyString_AsString(PyObject_Repr(pres));
      scm_simple_format(scm_current_output_port(),scm_makfrom0str("# python_apply: decoded results:\n#     Python: ~S\n#     Scheme: ~S\n"),scm_list_2(scm_makfrom0str(presstr),sres));
    }
  }
  else {
    // else sres remains SCM_UNDEFINED.
    if (pyguile_verbosity_test(PYGUILE_VERBOSE_PYTHON_APPLY)) {
      scm_simple_format(scm_current_output_port(),scm_makfrom0str("# python_apply: Python code returned <NULL>\n"),SCM_EOL);
    }
  }
  return(sres);
}
Exemple #5
0
SCM
python_eval(SCM sobj,SCM smode)
{
  if (!SCM_STRINGP(sobj)) {
    scm_wrong_type_arg("python-eval",SCM_ARG1,sobj);
  }

  int start = (SCM_UNBNDP(smode)) || (SCM_EQ_P(SCM_BOOL_F,smode))
    ? Py_file_input
    : Py_eval_input;

  char *pstr = scm_to_locale_string(sobj);
  if (NULL == pstr) {
    scm_memory_error("python-eval");  // NOT COVERED BY TESTS
    //return(SCM_UNSPECIFIED);
  }

  PyObject *pmaindict =
    PyModule_GetDict(PyImport_AddModule("__main__"));
  if (NULL == pmaindict) {
    scm_misc_error("python-eval","could not get __main__ for (~S), mode ~A",  // NOT COVERED BY TESTS
		   scm_list_2(sobj,smode));
  }
  Py_INCREF(pmaindict);
  PyObject *pres = PyRun_String(pstr, start, pmaindict, pmaindict);
  Py_DECREF(pmaindict);
  free(pstr);

  PyObject *pexception = PyErr_Occurred();
  if (pexception) {
    PyObject *prepr = PyObject_Repr(pexception);
    Py_XDECREF(pres);
    PyErr_Clear();
    if (NULL == prepr) {
      scm_misc_error("python-eval",  // NOT COVERED BY TESTS
		     "python exception - could not be identified",
		     SCM_UNSPECIFIED);
    }
    else {
      int strlength = PyString_Size(prepr);
      char *pstr = PyString_AsString(prepr);
      SCM slist = scm_list_1(scm_mem2string(pstr,strlength));
      Py_DECREF(prepr);
      scm_misc_error("python-eval","Python exception: ~A",
		     slist);
    }
  }

  switch(start) {
  case Py_eval_input:
    {
      if (NULL != pres) {
	SCM sres = p2g_apply(pres,
			     SCM_EQ_P(SCM_BOOL_T,smode)
			          ? srestemplate_default : smode);
	Py_DECREF(pres);
	return(sres);
      }
      else {
	scm_misc_error("python-eval","could not return result of evaluation",
		       SCM_UNSPECIFIED);
	return(SCM_UNSPECIFIED);
      }
    }
  case Py_file_input:
  default:
    {
      Py_XDECREF(pres);
      return(SCM_UNSPECIFIED);
    }
  }
}