Esempio n. 1
0
/*
 * Get possible out argument from kwds, and returns the number of outputs
 * contained within it: if a tuple, the number of elements in it, 1 otherwise.
 * The out argument itself is returned in out_kwd_obj, and the outputs
 * in the out_obj array (all as borrowed references).
 *
 * Returns -1 if kwds is not a dict, 0 if no outputs found.
 */
static int
get_out_objects(PyObject *kwds, PyObject **out_kwd_obj, PyObject ***out_objs)
{
    if (kwds == NULL) {
        return 0;
    }
    if (!PyDict_CheckExact(kwds)) {
        PyErr_SetString(PyExc_TypeError,
                        "Internal Numpy error: call to PyUFunc_WithOverride "
                        "with non-dict kwds");
        return -1;
    }
    /* borrowed reference */
    *out_kwd_obj = PyDict_GetItemString(kwds, "out");
    if (*out_kwd_obj == NULL) {
        return 0;
    }
    if (PyTuple_CheckExact(*out_kwd_obj)) {
        *out_objs = PySequence_Fast_ITEMS(*out_kwd_obj);
        return PySequence_Fast_GET_SIZE(*out_kwd_obj);
    }
    else {
        *out_objs = out_kwd_obj;
        return 1;
    }
}
Esempio n. 2
0
static int
BaseRowProxy_init(BaseRowProxy *self, PyObject *args, PyObject *kwds)
{
    PyObject *parent, *row, *processors, *keymap;

    if (!PyArg_UnpackTuple(args, "BaseRowProxy", 4, 4,
                           &parent, &row, &processors, &keymap))
        return -1;

    Py_INCREF(parent);
    self->parent = parent;

    if (!PySequence_Check(row)) {
        PyErr_SetString(PyExc_TypeError, "row must be a sequence");
        return -1;
    }
    Py_INCREF(row);
    self->row = row;

    if (!PyList_CheckExact(processors)) {
        PyErr_SetString(PyExc_TypeError, "processors must be a list");
        return -1;
    }
    Py_INCREF(processors);
    self->processors = processors;

    if (!PyDict_CheckExact(keymap)) {
        PyErr_SetString(PyExc_TypeError, "keymap must be a dict");
        return -1;
    }
    Py_INCREF(keymap);
    self->keymap = keymap;

    return 0;
}
Esempio n. 3
0
static Nuitka_DictEntryHandle GET_STRING_DICT_ENTRY( PyDictObject *dict, Nuitka_StringObject *key )
{
    assert( PyDict_CheckExact( dict ) );
    assert( Nuitka_String_Check( key ) );

    Py_hash_t hash = key->_base._base.hash;

    // Only improvement would be to identify how to ensure that the hash is computed
    // already. Calling hash early on could do that potentially.
    if ( hash == -1 )
    {
        hash = PyUnicode_Type.tp_hash( (PyObject *)key );
        key->_base._base.hash = hash;
    }

    PyObject **value_addr;

    PyDictKeyEntry *entry = dict->ma_keys->dk_lookup( dict, (PyObject *)key, hash, &value_addr );

    // The "entry" cannot be NULL, it can only be empty for a string dict lookup, but at
    // least assert it.
    assert( entry != NULL );

    return value_addr;
}
Esempio n. 4
0
static PyDictEntry *GET_STRING_DICT_ENTRY( PyDictObject *dict, Nuitka_StringObject *key )
{
    assert( PyDict_CheckExact( dict ) );
    assert( Nuitka_String_Check( key ) );

#if PYTHON_VERSION < 300
    Py_hash_t hash = key->ob_shash;
#else
    Py_hash_t hash = key->hash;
#endif

    // Only improvement would be to identify how to ensure that the hash is
    // computed already. Calling hash early on could do that potentially.
    if ( hash == -1 )
    {
#if PYTHON_VERSION < 300
        hash = PyString_Type.tp_hash( (PyObject *)key );
        key->ob_shash = hash;
#else
        hash = PyUnicode_Type.tp_hash( (PyObject *)key );
        key->hash = hash;
#endif
    }

    PyDictEntry *entry = dict->ma_lookup( dict, (PyObject *)key, hash );

    // The "entry" cannot be NULL, it can only be empty for a string dict
    // lookup, but at least assert it.
    assert( entry != NULL );

    return entry;
}
Esempio n. 5
0
static void py_variable_to_json_internal( PyObject *obj,
                                          json_writer_t *writer )
{
  if ( PyString_CheckExact( obj ) ) {
    json_writer_write_str( writer, PyString_AS_STRING( obj ) );
  }
  else if ( PyInt_CheckExact( obj ) ) {
    json_writer_write_integer( writer, PyInt_AS_LONG( obj ) );
  }
  else if ( PyFloat_CheckExact( obj ) ) {
    json_writer_write_number( writer, PyFloat_AS_DOUBLE( obj ) );
  }
  else if ( PyBool_Check( obj ) ) {
    json_writer_write_boolean( writer, ( obj == Py_True ) );
  }
  else if ( PyUnicode_CheckExact( obj ) ) {
    /* Create a new string object that is UTF-8 encoded. */
    Py_UNICODE *unicode = PyUnicode_AS_UNICODE( obj );
    Py_ssize_t size = PyUnicode_GET_SIZE( obj );
    PyObject *str_obj = PyUnicode_EncodeUTF8( unicode, size, NULL );
    py_variable_to_json_internal( str_obj, writer );
    PyObject_Free( str_obj );
  }
  else if ( PyDict_CheckExact( obj ) ) {
    py_dict_to_json( obj, writer );
  }
  else if ( PyList_CheckExact( obj ) ) {
    py_list_to_json( obj, writer );
  }
  else if ( PyTuple_CheckExact( obj ) ) {
    py_tuple_to_json( obj, writer ); 
  }
}
Esempio n. 6
0
Box* setInit(Box* _self, Box* container, BoxedDict* kwargs) {
    RELEASE_ASSERT(PySet_Check(_self), "");

    if (PySet_Check(_self) && !_PyArg_NoKeywords("set()", kwargs)) {
        throwCAPIException();
    }

    if (!container)
        return incref(None);

    BoxedSet* self = static_cast<BoxedSet*>(_self);

    setClearInternal(self);

    if (PyAnySet_Check(container)) {
        for (auto&& elt : ((BoxedSet*)container)->s) {
            self->s.insert(incref(elt));
        }
    } else if (PyDict_CheckExact(container)) {
        for (auto&& elt : ((BoxedDict*)container)->d) {
            self->s.insert(incref(elt.first));
        }

    } else {
        for (auto elt : container->pyElements()) {
            _setAddStolen(self, elt);
        }
    }

    return incref(None);
}
Esempio n. 7
0
// Convert a Python object to a QVariantHash and return true if there was no
// error.
bool Chimera::to_QVariantHash(PyObject *py, QVariantHash &cpp) const
{
    Q_ASSERT(PyDict_CheckExact(py));

    PyObject *key_obj, *val_obj;
    SIP_SSIZE_T i;

    i = 0;
    while (PyDict_Next(py, &i, &key_obj, &val_obj))
    {
        int key_state, val_state, iserr = 0;

        QString *key = reinterpret_cast<QString *>(sipForceConvertToType(
                key_obj, sipType_QString, NULL, SIP_NOT_NONE, &key_state,
                &iserr));

        QVariant *val = reinterpret_cast<QVariant *>(sipForceConvertToType(
                val_obj, sipType_QVariant, NULL, SIP_NOT_NONE, &val_state,
                &iserr));

        if (iserr)
            return false;

        cpp.insert(*key, *val);

        sipReleaseType(key, sipType_QString, key_state);
        sipReleaseType(val, sipType_QVariant, val_state);
    }

    return true;
}
Esempio n. 8
0
/* Move the unreachable objects from young to unreachable.  After this,
 * all objects in young have gc_refs = GC_REACHABLE, and all objects in
 * unreachable have gc_refs = GC_TENTATIVELY_UNREACHABLE.  All tracked
 * gc objects not in young or unreachable still have gc_refs = GC_REACHABLE.
 * All objects in young after this are directly or indirectly reachable
 * from outside the original young; and all objects in unreachable are
 * not.
 */
static void
move_unreachable(PyGC_Head *young, PyGC_Head *unreachable)
{
    PyGC_Head *gc = young->gc.gc_next;

    /* Invariants:  all objects "to the left" of us in young have gc_refs
     * = GC_REACHABLE, and are indeed reachable (directly or indirectly)
     * from outside the young list as it was at entry.  All other objects
     * from the original young "to the left" of us are in unreachable now,
     * and have gc_refs = GC_TENTATIVELY_UNREACHABLE.  All objects to the
     * left of us in 'young' now have been scanned, and no objects here
     * or to the right have been scanned yet.
     */

    while (gc != young) {
        PyGC_Head *next;

        if (gc->gc.gc_refs) {
            /* gc is definitely reachable from outside the
             * original 'young'.  Mark it as such, and traverse
             * its pointers to find any other objects that may
             * be directly reachable from it.  Note that the
             * call to tp_traverse may append objects to young,
             * so we have to wait until it returns to determine
             * the next object to visit.
             */
            PyObject *op = FROM_GC(gc);
            traverseproc traverse = Py_TYPE(op)->tp_traverse;
            assert(gc->gc.gc_refs > 0);
            gc->gc.gc_refs = GC_REACHABLE;
            (void) traverse(op,
                            (visitproc)visit_reachable,
                            (void *)young);
            next = gc->gc.gc_next;
            if (PyTuple_CheckExact(op)) {
                _PyTuple_MaybeUntrack(op);
            }
            else if (PyDict_CheckExact(op)) {
                _PyDict_MaybeUntrack(op);
            }
        }
        else {
            /* This *may* be unreachable.  To make progress,
             * assume it is.  gc isn't directly reachable from
             * any object we've already traversed, but may be
             * reachable from an object we haven't gotten to yet.
             * visit_reachable will eventually move gc back into
             * young if that's so, and we'll see it again.
             */
            next = gc->gc.gc_next;
            gc_list_move(gc, unreachable);
            gc->gc.gc_refs = GC_TENTATIVELY_UNREACHABLE;
        }
        gc = next;
    }
}
Esempio n. 9
0
static int cdefer_Deferred__verify_callback_entry(const char *callback_name,
                                                  PyObject *callback_entry) {
    PyObject *callback;
    PyObject *args;
    PyObject *kw;

    if (!PyTuple_Check(callback_entry)) {
        PyErr_Format(PyExc_TypeError, "%s entries must be tuples", callback_name);
        return -1;
    }
    if (3 != PyTuple_GET_SIZE(callback_entry)) {
        PyErr_Format(PyExc_TypeError, "%s entries must contain exactly (callback, args, kw)",
                     callback_name);
        return -1;
    }

    callback = PyTuple_GET_ITEM(callback_entry, 0);
    if ((Py_None != callback) && !PyCallable_Check(callback)) {
        PyErr_Format(PyExc_TypeError, "%s entry callback must be callable",
                     callback_name);
        return -1;
    }

    args = PyTuple_GET_ITEM(callback_entry, 1);
    if (Py_None != args) {
        if (Py_None == callback) {
            PyErr_Format(PyExc_TypeError, "%s entry got a None callback with non-None args",
                         callback_name);
            return -1;
        }
        if (!PyTuple_Check(args)) {
            PyErr_Format(PyExc_TypeError, "%s entry args must be tuples or None",
                         callback_name);
            return -1;
        }
    }

    kw = PyTuple_GET_ITEM(callback_entry, 2);
    if (Py_None != kw) {
        if (Py_None == callback) {
            PyErr_Format(PyExc_TypeError, "%s entry got a None callback with non-None kws",
                         callback_name);
            return -1;
        }
        if (!PyDict_CheckExact(kw)) {
            PyErr_Format(PyExc_TypeError, "%s entry kws must be dicts or None",
                         callback_name);
            return -1;
        }
    }

    return 0;
}
Esempio n. 10
0
PyObject *
PyTuple_DeepCopy(register PyObject *a)
{
	PyTupleObject *np;
	PyObject **src, **dest;
	register Py_ssize_t i;
	Py_ssize_t len = Py_SIZE(a);
	np = (PyTupleObject *)PyTuple_New(len);
	if (np == NULL)
		return NULL;
	src = ((PyTupleObject *) a)->ob_item;
	dest = np->ob_item;
	for (i = 0; i < len; i++) {
		register PyObject *v = src[i];
		Py_INCREF(v);
		if (PyTuple_CheckExact(v)) {
			PyObject *w = PyTuple_DeepCopy(v);
			Py_DECREF(v);
			if (!w)	{
				Py_DECREF(np);
				return NULL;
			}
			v = w;
		}
		else if (PyList_CheckExact(v)) {
			PyObject *w = PyList_DeepCopy(v);
			Py_DECREF(v);
			if (!w)	{
				Py_DECREF(np);
				return NULL;
			}
			v = w;
		}
		else if (PyDict_CheckExact(v)) {
			PyObject *w = PyDict_DeepCopy(v);
			Py_DECREF(v);
			if (!w)	{
				Py_DECREF(np);
				return NULL;
			}
			v = w;
		}
		dest[i] = v;
	}
	return (PyObject *)np;
}
Esempio n. 11
0
// TODO: Have mapping.hpp
NUITKA_MAY_BE_UNUSED static void DICT_SYNC_FROM_VARIABLE( PyObject *dict, PyObject *key, PyObject *value )
{
    if ( value )
    {
        assert( PyDict_CheckExact( dict ) );
        UPDATE_STRING_DICT0( (PyDictObject *)dict, (Nuitka_StringObject *)key, value );
    }
    else
    {
        int res = PyDict_DelItem( dict, key );

        if ( res != 0 )
        {
            CLEAR_ERROR_OCCURRED();
        }
    }
}
Esempio n. 12
0
static PyObject *
partial_setstate(partialobject *pto, PyObject *state)
{
    PyObject *fn, *fnargs, *kw, *dict;

    if (!PyTuple_Check(state) ||
        !PyArg_ParseTuple(state, "OOOO", &fn, &fnargs, &kw, &dict) ||
        !PyCallable_Check(fn) ||
        !PyTuple_Check(fnargs) ||
        (kw != Py_None && !PyDict_Check(kw)))
    {
        PyErr_SetString(PyExc_TypeError, "invalid partial state");
        return NULL;
    }

    if(!PyTuple_CheckExact(fnargs))
        fnargs = PySequence_Tuple(fnargs);
    else
        Py_INCREF(fnargs);
    if (fnargs == NULL)
        return NULL;

    if (kw == Py_None)
        kw = PyDict_New();
    else if(!PyDict_CheckExact(kw))
        kw = PyDict_Copy(kw);
    else
        Py_INCREF(kw);
    if (kw == NULL) {
        Py_DECREF(fnargs);
        return NULL;
    }

    if (dict == Py_None)
        dict = NULL;
    else
        Py_INCREF(dict);

    Py_INCREF(fn);
    pto->use_fastcall = _PyObject_HasFastCall(fn);
    Py_SETREF(pto->fn, fn);
    Py_SETREF(pto->args, fnargs);
    Py_SETREF(pto->kw, kw);
    Py_XSETREF(pto->dict, dict);
    Py_RETURN_NONE;
}
Esempio n. 13
0
static void _setDifferenceUpdate(BoxedSet* self, BoxedTuple* args) {
    for (auto container : args->pyElements()) {
        AUTO_DECREF(container);
        if (PyAnySet_Check(container)) {
            for (auto&& elt : ((BoxedSet*)container)->s) {
                _setRemove(self, elt);
            }
        } else if (PyDict_CheckExact(container)) {
            for (auto&& elt : ((BoxedDict*)container)->d) {
                _setRemove(self, elt.first);
            }
        } else {
            for (auto elt : container->pyElements()) {
                AUTO_DECREF(elt);
                _setRemove(self, elt);
            }
        }
    }
}
Esempio n. 14
0
json_t *py_variable_to_json( apr_pool_t *mp, PyObject *obj )
{
  json_writer_t *writer;
  json_t *json = NULL;
  apr_pool_t *tmp_mp;

  if ( PyDict_CheckExact( obj ) || PyList_CheckExact( obj ) ||
       PyTuple_CheckExact( obj ) ) {
    apr_pool_create( &tmp_mp, NULL );
    writer = json_writer_create( tmp_mp, mp );
    py_variable_to_json_internal( obj, writer );
    json = writer->json;
    apr_pool_destroy( tmp_mp );
  }
  else {
    fprintf( stderr, "Must be an object, list or tuple.\n" );
  }

  return json;

}
Esempio n. 15
0
static int
BaseRowProxy_setkeymap(BaseRowProxy *self, PyObject *value, void *closure)
{
    if (value == NULL) {
        PyErr_SetString(PyExc_TypeError,
                        "Cannot delete the 'keymap' attribute");
        return -1;
    }

    if (!PyDict_CheckExact(value)) {
        PyErr_SetString(PyExc_TypeError,
                        "The 'keymap' attribute value must be a dict");
        return -1;
    }

    Py_XDECREF(self->keymap);
    Py_INCREF(value);
    self->keymap = value;

    return 0;
}
Esempio n. 16
0
static PyObject*
convert_nested(PyObject *ob, convert_func convert_string)
{
    /* dict. */
    if (PyDict_CheckExact(ob)) {
        return convert_dict(ob, convert_string);
    }

    /* sequence. */
    if (PyTuple_CheckExact(ob) || PyList_CheckExact(ob)) {
        return convert_seq(ob, convert_string);
    }

    /* numbers. */
    if (PyInt_CheckExact(ob) || PyLong_CheckExact(ob) || PyFloat_CheckExact(ob)) {
        Py_INCREF(ob);
        return ob;
    }

    /* bool. */
    if (PyBool_Check(ob)) {
        Py_INCREF(ob);
        return ob;
    }

    /* none. */
    if (ob == Py_None) {
        Py_INCREF(ob);
        return ob;
    }

    if (PyString_CheckExact(ob) || PyUnicode_CheckExact(ob)) {
        return convert_string(ob);
    }

    return PyErr_Format(
        PyExc_TypeError,
        "Got wrong type: %s",
        ob->ob_type->tp_name);
}
Esempio n. 17
0
static PyObject* new_check(PyObject* args)
{
    // We don't support a normal constructor, so only allow this for unpickling.  There should be a single arg that was
    // returned by Row_reduce.  Make sure the sizes match.  The desc and map should have one entry per column, which
    // should equal the number of remaining items.

    if (PyTuple_GET_SIZE(args) < 3)
        return 0;

    PyObject* desc = PyTuple_GET_ITEM(args, 0);
    PyObject* map  = PyTuple_GET_ITEM(args, 1);

    if (!PyTuple_CheckExact(desc) || !PyDict_CheckExact(map))
        return 0;

    Py_ssize_t cols = PyTuple_GET_SIZE(desc);

    if (PyDict_Size(map) != cols || PyTuple_GET_SIZE(args) - 2 != cols)
        return 0;

    PyObject** apValues = (PyObject**)pyodbc_malloc(sizeof(PyObject*) * cols);
    if (!apValues)
        return 0;

    for (int i = 0; i < cols; i++)
    {
        apValues[i] = PyTuple_GET_ITEM(args, i+2);
        Py_INCREF(apValues[i]);
    }

    // Row_Internal will incref desc and map.

    PyObject* self = (PyObject*)Row_InternalNew(desc, map, cols, apValues);
    if (!self)
        pyodbc_free(apValues);

    return self;
}
Esempio n. 18
0
// Creates a set of type 'cls' from 'container' (NULL to get an empty set).
// Works for frozenset and normal set types.
BoxedSet* makeNewSet(BoxedClass* cls, Box* container) {
    assert(isSubclass(cls, frozenset_cls) || isSubclass(cls, set_cls));

    BoxedSet* rtn = new (cls) BoxedSet();
    if (container) {
        AUTO_DECREF(rtn);
        if (PyAnySet_Check(container)) {
            for (auto&& elt : ((BoxedSet*)container)->s) {
                rtn->s.insert(incref(elt));
            }
        } else if (PyDict_CheckExact(container)) {
            for (auto&& elt : ((BoxedDict*)container)->d) {
                rtn->s.insert(incref(elt.first));
            }
        } else {
            for (auto elt : container->pyElements()) {
                _setAddStolen(rtn, elt);
            }
        }
        return incref(rtn);
    }
    return rtn;
}
Esempio n. 19
0
NUITKA_MAY_BE_UNUSED static PyObject *DICT_GET_ITEM( PyObject *dict, PyObject *key )
{
    CHECK_OBJECT( dict );
    assert( PyDict_CheckExact( dict ) );

    CHECK_OBJECT( key );

    PyObject *result = PyDict_GetItem( dict, key );

    if ( result == NULL )
    {
        if (unlikely( PyErr_Occurred() ))
        {
            return NULL;
        }

        /* Wrap all kinds of tuples, because normalization will later unwrap
         * it, but then that changes the key for the KeyError, which is not
         * welcome. The check is inexact, as the unwrapping one is too.
         */
        if ( PyTuple_Check( key ) )
        {
            PyObject *tuple = PyTuple_Pack( 1, key );
            PyErr_SetObject( PyExc_KeyError, tuple );
            Py_DECREF( tuple );
        }
        else
        {
            PyErr_SetObject( PyExc_KeyError, key );
        }
        return NULL;
    }
    else
    {
        return INCREASE_REFCOUNT( result );
    }
}
Esempio n. 20
0
static PyObject * ntracenative_frameSetLocals(PyObject *self, PyObject *args)
{
    PyObject *frameobj = NULL,*dict = NULL;
    PyFrameObject *frame;

    (void) self;

    
//printf("before parse\n");
    if (!PyArg_ParseTuple( args, "OO", &frameobj, &dict))
    {
	return NULL;
    }	

//printf("before framecheck frameobj=%p dict=%p\n", frameobj, dict);

    if ( frameobj == NULL || !PyFrame_Check(frameobj) ) // check if frame tame
    {
	return NULL;
    }

//printf("before dictcheck dict=%p\n", dict);
                             
    if ( !PyDict_Check(dict) )
    {
	return NULL;
    }	

//printf("allchecks ok\n");

    frame = (PyFrameObject *) frameobj;
    if (PyDict_CheckExact(frame->f_locals))    
    {
	PyObject *oldLocals;


//printf("set f_locals\n");

	PyDict_Merge(dict, frame->f_locals, 1); // 1 - add reference to keys and values
    	Py_INCREF(dict);


	oldLocals = frame->f_locals;

    	frame->f_locals = dict;

	if (oldLocals != NULL)
		Py_DECREF( oldLocals );
    }


#if 0
    if (PyDict_CheckExact(frame->f_globals))    
    {
	PyObject *oldLocals;

	PyDict_Merge(dict, frame->f_globals, 1); // 1 - add reference to keys and values
    	Py_INCREF(dict);


	oldLocals = frame->f_globals;

    	frame->f_globals = dict;

	if (oldLocals != NULL)
		Py_DECREF( oldLocals );
    }
#endif

    return Py_BuildValue("i", 0);
} 
Esempio n. 21
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);
}