Beispiel #1
0
PyObject *
rpcErrorClass(void)
{
	PyObject	*klass,
			*dict,
			*func,
			*meth;
	PyMethodDef	*method;

	dict = PyDict_New();
	if (dict == NULL)
		return (NULL);
	klass = PyErr_NewException("xmlrpc.error", NULL, dict);
	if (klass == NULL)
		return (NULL);
	for (method = rpcErrorMethods; method->ml_name != NULL; method++) {
		func = PyCFunction_New(method, NULL);
		if (func == NULL)
			return (NULL);
		meth = PyMethod_New(func, NULL, klass);
		if (meth == NULL)
			return (NULL);
		if (PyDict_SetItemString(dict, method->ml_name, meth))
			return (NULL);
		Py_DECREF(meth);
		Py_DECREF(func);
	}
	return (klass);
}
Beispiel #2
0
PyObject *
PyECMethod_New_(PyObject *callable, PyObject *inst)
{
  if (! PyExtensionInstance_Check(inst))
    {
      PyErr_SetString(PyExc_TypeError, 
                      "Can't bind non-ExtensionClass instance.");
      return NULL;
    }

  if (PyMethod_Check(callable))
    {
      if (callable->ob_refcnt == 1)
        {
          Py_XDECREF(((PyMethodObject*)callable)->im_self);
          Py_INCREF(inst);
          ((PyMethodObject*)callable)->im_self = inst;
          Py_INCREF(callable);
          return callable;
        }
      else
        return callable->ob_type->tp_descr_get(
                   callable, inst, 
                   ((PyMethodObject*)callable)->im_class);
    }
  else
    return PyMethod_New(callable, inst, (PyObject*)(ECBaseType));
}
    // Stolen from Python's funcobject.c
    static PyObject *
    function_descr_get(PyObject *func, PyObject *obj, PyObject *type_)
    {
#if PY_VERSION_HEX >= 0x03000000
        // The implement is different in Python 3 because of the removal of unbound method
        if (obj == Py_None || obj == NULL) {
            Py_INCREF(func);
            return func;
        }
        return PyMethod_New(func, obj);
#else
        if (obj == Py_None)
            obj = NULL;
        return PyMethod_New(func, obj, type_);
#endif
    }
Beispiel #4
0
/* Bind a function to an object */
static PyObject *
func_descr_get(PyObject *func, PyObject *obj, PyObject *type)
{
    if (obj == Py_None)
        obj = NULL;
    return PyMethod_New(func, obj, type);
}
Beispiel #5
0
static int
add_method (PyObject * klass, PyObject * dict, PyMethodDef * method)
{
  PyObject *module = NULL;
  PyObject *func = NULL;
  PyObject *meth = NULL;

  module = PyString_FromString ("gst");
  if (module == NULL)
    goto exception;

  func = PyCFunction_NewEx (method, NULL, module);
  if (func == NULL)
    goto exception;
  Py_DECREF (module);

  meth = PyMethod_New (func, NULL, klass);
  if (meth == NULL)
    goto exception;
  Py_DECREF (func);

  if (PyDict_SetItemString (dict, method->ml_name, meth) < 0)
    goto exception;
  Py_DECREF (meth);

  return 0;

exception:
  Py_XDECREF (module);
  Py_XDECREF (func);
  Py_XDECREF (meth);

  return -1;
}
Beispiel #6
0
static PyObject *
new_instancemethod(PyObject* unused, PyObject* args)
{
	PyObject* func;
	PyObject* self;
	PyObject* classObj;

	if (!PyArg_ParseTuple(args, "OOO!:instancemethod",
			      &func,
			      &self,
			      &PyClass_Type, &classObj))
		return NULL;
	if (!PyCallable_Check(func)) {
		PyErr_SetString(PyExc_TypeError,
				"first argument must be callable");
		return NULL;
	}
	if (self == Py_None)
		self = NULL;
	else if (!PyInstance_Check(self)) {
		PyErr_SetString(PyExc_TypeError,
				"second argument must be instance or None");
		return NULL;
	}
	return PyMethod_New(func, self, classObj);
}
Beispiel #7
0
void init_scope(void) {
  PyMethodDef *def;

  PyObject *module=Py_InitModule("_scope", ModuleMethods);
  PyObject *moduleDict=PyModule_GetDict(module);
  PyObject *classDict=PyDict_New();
  PyObject *className = PyString_FromString("Scopeable");
  PyObject *scopeableClass = PyClass_New(NULL, classDict, className);
  PyDict_SetItemString(moduleDict, "Scopeable", scopeableClass);
  Py_DECREF(classDict);
  Py_DECREF(className);
  Py_DECREF(scopeableClass);

  for (def = ScopeableMethods; def->ml_name != NULL; def++) {
    PyObject *func=PyCFunction_New(def, NULL);
    PyObject *method= PyMethod_New(func, NULL, scopeableClass);
    PyDict_SetItemString(classDict, def->ml_name, method);
    /* 
     * this would normally happen in PyClass_New() if the classDict
     * were already populated; but I'm passing it an empty dict
     */
    if (!strncmp(def->ml_name, "__getattr__", strlen("__getattr__"))) {
      ((PyClassObject *)scopeableClass)->cl_getattr=method;
    }
    Py_DECREF(func);
    Py_DECREF(method);
  }
}
Beispiel #8
0
/*
 * This function returns a NEW reference, i.e. caller must decref it in the end.
 */
PyObject* JySync_Init_PyMethod_From_JyMethod(jobject src, PyTypeObject* nonNativeSubtype)
{
	env(NULL);
	return PyMethod_New(
		JyNI_PyObject_FromJythonPyObject((*env)->GetObjectField(env, src, pyMethod___func__Field)),
		JyNI_PyObject_FromJythonPyObject((*env)->GetObjectField(env, src, pyMethod___self__Field)),
		JyNI_PyObject_FromJythonPyObject((*env)->GetObjectField(env, src, pyMethod_im_classField)));
}
Beispiel #9
0
static PyObject *
lru_cache_descr_get(PyObject *self, PyObject *obj, PyObject *type)
{
    if (obj == Py_None || obj == NULL) {
        Py_INCREF(self);
        return self;
    }
    return PyMethod_New(self, obj);
}
Beispiel #10
0
/* Bind a function to an object */
static PyObject *
func_descr_get(PyObject *func, PyObject *obj, PyObject *type)
{
    if (obj == Py_None || obj == NULL) {
        Py_INCREF(func);
        return func;
    }
    return PyMethod_New(func, obj);
}
Beispiel #11
0
static PyObject *
instancemethod_descr_get(PyObject *descr, PyObject *obj, PyObject *type) {
    PyObject *func = PyInstanceMethod_GET_FUNCTION(descr);
    if (obj == NULL) {
        Py_INCREF(func);
        return func;
    }
    else
        return PyMethod_New(func, obj);
}
Beispiel #12
0
static PyObject *
method_descr_get(PyObject *meth, PyObject *obj, PyObject *cls)
{
    /* Don't rebind an already bound method of a class that's not a base
       class of cls. */
    if (PyMethod_GET_SELF(meth) != NULL) {
        /* Already bound */
        Py_INCREF(meth);
        return meth;
    }
    /* Bind it to obj */
    return PyMethod_New(PyMethod_GET_FUNCTION(meth), obj);
}
Beispiel #13
0
static PyObject *
cm_descr_get(PyObject *self, PyObject *obj, PyObject *type)
{
    classmethod *cm = (classmethod *)self;

    if (cm->cm_callable == NULL) {
        PyErr_SetString(PyExc_RuntimeError,
                        "uninitialized classmethod object");
        return NULL;
    }
    if (type == NULL)
        type = (PyObject *)(Py_TYPE(obj));
    return PyMethod_New(cm->cm_callable, type);
}
Beispiel #14
0
static PyObject * adamethod_descr_get
   (PyAdaMethodDescrObject *descr, PyObject *obj, PyObject *type)
{
  PyObject *res;

  if (obj == NULL) {
    Py_INCREF(descr);
    return (PyObject*) descr;
  }
  if (!PyObject_TypeCheck(obj, PyDescr_TYPE(descr))) {
    PyErr_Format(PyExc_TypeError,
                 "descriptor '%V' for '%s' objects "
                 "doesn't apply to '%s' object",
                 PyDescr_NAME(descr), "?",
                 PyDescr_TYPE(descr)->tp_name,
                 obj->ob_type->tp_name);
    return NULL;
  }
  return PyMethod_New (descr->cfunc, obj);
}
Beispiel #15
0
static PyObject *
method_new(PyTypeObject* type, PyObject* args, PyObject *kw)
{
    PyObject *func;
    PyObject *self;

    if (!_PyArg_NoKeywords("method", kw))
        return NULL;
    if (!PyArg_UnpackTuple(args, "method", 2, 2,
                          &func, &self))
        return NULL;
    if (!PyCallable_Check(func)) {
        PyErr_SetString(PyExc_TypeError,
                        "first argument must be callable");
        return NULL;
    }
    if (self == NULL || self == Py_None) {
        PyErr_SetString(PyExc_TypeError,
            "self must not be None");
        return NULL;
    }

    return PyMethod_New(func, self);
}
Beispiel #16
0
void initredirector()
{
    PyMethodDef *def;

    /* create a new module and class */
    PyObject *module = Py_InitModule("redirector", ModuleMethods);
    PyObject *moduleDict = PyModule_GetDict(module);
    PyObject *classDict = PyDict_New();
    PyObject *className = PyString_FromString("redirector");
    PyObject *fooClass = PyClass_New(NULL, classDict, className);
    PyDict_SetItemString(moduleDict, "redirector", fooClass);
    Py_DECREF(classDict);
    Py_DECREF(className);
    Py_DECREF(fooClass);

    /* add methods to class */
    for (def = redirectorMethods; def->ml_name != NULL; def++) {
        PyObject *func = PyCFunction_New(def, NULL);
        PyObject *method = PyMethod_New(func, NULL, fooClass);
        PyDict_SetItemString(classDict, def->ml_name, method);
        Py_DECREF(func);
        Py_DECREF(method);
    }
}
Beispiel #17
0
/* Implementation of classmethargdefault */

static PyObject *__pyx_f_19classmethargdefault_7Swallow_spam(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_19classmethargdefault_7Swallow_spam = {"spam", (PyCFunction)__pyx_f_19classmethargdefault_7Swallow_spam, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_f_19classmethargdefault_7Swallow_spam(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
    PyObject *__pyx_v_w = 0;
    int __pyx_v_x;
    PyObject *__pyx_v_y = 0;
    PyObject *__pyx_v_z = 0;
    PyObject *__pyx_r;
    static char *__pyx_argnames[] = {"w","x","y","z",0};
    __pyx_v_x = __pyx_d1;
    __pyx_v_y = __pyx_d2;
    __pyx_v_z = __pyx_d3;
    if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "O|iOO", __pyx_argnames, &__pyx_v_w, &__pyx_v_x, &__pyx_v_y, &__pyx_v_z)) return 0;
    Py_INCREF(__pyx_v_w);
    Py_INCREF(__pyx_v_y);
    Py_INCREF(__pyx_v_z);

    __pyx_r = Py_None;
    Py_INCREF(Py_None);
    Py_DECREF(__pyx_v_w);
    Py_DECREF(__pyx_v_y);
    Py_DECREF(__pyx_v_z);
    return __pyx_r;
}

static struct PyMethodDef __pyx_methods[] = {
    {0, 0, 0, 0}
};

static void __pyx_init_filenames(void); /*proto*/

PyMODINIT_FUNC initclassmethargdefault(void); /*proto*/
PyMODINIT_FUNC initclassmethargdefault(void) {
    PyObject *__pyx_1 = 0;
    PyObject *__pyx_2 = 0;
    PyObject *__pyx_3 = 0;
    PyObject *__pyx_4 = 0;
    PyObject *__pyx_5 = 0;
    __pyx_init_filenames();
    __pyx_m = Py_InitModule4("classmethargdefault", __pyx_methods, 0, 0, PYTHON_API_VERSION);
    if (!__pyx_m) {
        __pyx_filename = __pyx_f[0];
        __pyx_lineno = 1;
        goto __pyx_L1;
    };
    Py_INCREF(__pyx_m);
    __pyx_b = PyImport_AddModule("__builtin__");
    if (!__pyx_b) {
        __pyx_filename = __pyx_f[0];
        __pyx_lineno = 1;
        goto __pyx_L1;
    };
    if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {
        __pyx_filename = __pyx_f[0];
        __pyx_lineno = 1;
        goto __pyx_L1;
    };
    if (__Pyx_InitStrings(__pyx_string_tab) < 0) {
        __pyx_filename = __pyx_f[0];
        __pyx_lineno = 1;
        goto __pyx_L1;
    };
    __pyx_1 = PyDict_New();
    if (!__pyx_1) {
        __pyx_filename = __pyx_f[0];
        __pyx_lineno = 1;
        goto __pyx_L1;
    }
    __pyx_2 = PyTuple_New(0);
    if (!__pyx_2) {
        __pyx_filename = __pyx_f[0];
        __pyx_lineno = 1;
        goto __pyx_L1;
    }
    __pyx_3 = __Pyx_CreateClass(__pyx_2, __pyx_1, __pyx_n_Swallow, "classmethargdefault");
    if (!__pyx_3) {
        __pyx_filename = __pyx_f[0];
        __pyx_lineno = 1;
        goto __pyx_L1;
    }
    Py_DECREF(__pyx_2);
    __pyx_2 = 0;
    __pyx_d1 = 42;
    Py_INCREF(__pyx_n_grail);
    __pyx_d2 = __pyx_n_grail;
    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_swallow);
    if (!__pyx_2) {
        __pyx_filename = __pyx_f[0];
        __pyx_lineno = 3;
        goto __pyx_L1;
    }
    __pyx_d3 = __pyx_2;
    __pyx_2 = 0;
    __pyx_4 = PyCFunction_NewEx(&__pyx_mdef_19classmethargdefault_7Swallow_spam, 0, __pyx_n_classmethargdefault);
    if (!__pyx_4) {
        __pyx_filename = __pyx_f[0];
        __pyx_lineno = 3;
        goto __pyx_L1;
    }
    __pyx_5 = PyMethod_New(__pyx_4, 0, __pyx_3);
    if (!__pyx_5) {
        __pyx_filename = __pyx_f[0];
        __pyx_lineno = 3;
        goto __pyx_L1;
    }
    Py_DECREF(__pyx_4);
    __pyx_4 = 0;
    if (PyObject_SetAttr(__pyx_3, __pyx_n_spam, __pyx_5) < 0) {
        __pyx_filename = __pyx_f[0];
        __pyx_lineno = 3;
        goto __pyx_L1;
    }
    Py_DECREF(__pyx_5);
    __pyx_5 = 0;
    if (PyObject_SetAttr(__pyx_m, __pyx_n_Swallow, __pyx_3) < 0) {
        __pyx_filename = __pyx_f[0];
        __pyx_lineno = 1;
        goto __pyx_L1;
    }
    Py_DECREF(__pyx_3);
    __pyx_3 = 0;
    Py_DECREF(__pyx_1);
    __pyx_1 = 0;
    return;
__pyx_L1:
    ;
    Py_XDECREF(__pyx_1);
    Py_XDECREF(__pyx_2);
    Py_XDECREF(__pyx_3);
    Py_XDECREF(__pyx_4);
    Py_XDECREF(__pyx_5);
    __Pyx_AddTraceback("classmethargdefault");
}
static PyObject* copyrec(PyObject* o)
{
  PyTypeObject* t;
  PyObject* n;
  PyObject* key;
  KeyObject* fkey;

  if (o == Py_None || o->ob_type == &PyInt_Type || o->ob_type == &PyString_Type)
    {
      Py_INCREF(o);
      return o;
    }
  if (ss_next_in_block < 0)
    {
      struct key_block* b = (struct key_block*) malloc(sizeof(struct key_block));
      if (!b) { PyErr_NoMemory(); goto fail1; }
      b->next = ss_block;
      ss_block = b;
      ss_next_in_block = KEYS_BY_BLOCK - 1;
    }
  fkey = ss_block->keys + ss_next_in_block;
  fkey->ob_refcnt = 1;
  fkey->ob_type = &keytype;
  fkey->o = o;
  key = (PyObject*) fkey;
  n = PyDict_GetItem(ss_memo, key);
  if (n)
    {
      Py_INCREF(n);
      return n;
    }
  ss_next_in_block--;
  Py_INCREF(o);    /* reference stored in 'fkey->o' */
  t = o->ob_type;
  if (t == &PyTuple_Type)
    {
      int i, count = PyTuple_GET_SIZE(o);
      n = PyTuple_New(count);
      if (!n || PyDict_SetItem(ss_memo, key, n)) goto fail;
      for (i=0; i<count; i++)
        PyTuple_SET_ITEM(n, i, copyrec(PyTuple_GET_ITEM(o, i)));
      return n;
    }
  if (t == &PyList_Type)
    {
      int i, count = PyList_GET_SIZE(o);
      n = PyList_New(count);
      if (!n || PyDict_SetItem(ss_memo, key, n)) goto fail;
      for (i=0; i<count; i++)
        PyList_SET_ITEM(n, i, copyrec(PyList_GET_ITEM(o, i)));
      return n;
    }
  if (t == &PyDict_Type)
    {
      int i = 0;
      PyObject* dictkey;
      PyObject* dictvalue;
      n = PyDict_New();
      if (!n || PyDict_SetItem(ss_memo, key, n)) goto fail;
      while (PyDict_Next(o, &i, &dictkey, &dictvalue))
        if (PyDict_SetItem(n, copyrec(dictkey), copyrec(dictvalue)))
          goto fail;
      return n;
    }
  if (t == &PyInstance_Type)
    {
      int i = 0;
      PyObject* dictkey;
      PyObject* dictvalue;
      PyObject* dsrc;
      PyObject* ddest;
      PyObject* inst_build = PyObject_GetAttr(o, str_inst_build);
      if (inst_build == NULL)
        {
          PyErr_Clear();
          goto unmodified;
        }
      n = PyObject_CallObject(inst_build, NULL);
      if (!n || PyDict_SetItem(ss_memo, key, n)) goto fail;
      dsrc  = ((PyInstanceObject*) o)->in_dict;
      ddest = ((PyInstanceObject*) n)->in_dict;
      while (PyDict_Next(dsrc, &i, &dictkey, &dictvalue))
        if (PyDict_SetItem(ddest, copyrec(dictkey), copyrec(dictvalue)))
          goto fail;
      return n;
    }
  if (t == &PyFunction_Type)
    {
      int i, count;
      PyObject* tsrc = PyFunction_GET_DEFAULTS(o);
      PyObject* tdest;
      if (!tsrc) goto unmodified;
      count = PyTuple_GET_SIZE(tsrc);
      if (count == 0) goto unmodified;
      n = PyFunction_New(PyFunction_GET_CODE(o), PyFunction_GET_GLOBALS(o));
      if (!n || PyDict_SetItem(ss_memo, key, n)) goto fail;
      tdest = PyTuple_New(count);
      if (!tdest) goto fail;
      for (i=0; i<count; i++)
        PyTuple_SET_ITEM(tdest, i, copyrec(PyTuple_GET_ITEM(tsrc, i)));
      i = PyFunction_SetDefaults(n, tdest);
      Py_DECREF(tdest);
      if (i) goto fail;
      return n;
    }
  if (t == &PyMethod_Type)
    {
      PyObject* x;
      n = PyMethod_New(PyMethod_GET_FUNCTION(o),
                       PyMethod_GET_SELF(o),
                       PyMethod_GET_CLASS(o));
      if (!n || PyDict_SetItem(ss_memo, key, n)) goto fail;
      x = copyrec(PyMethod_GET_FUNCTION(n));
      Py_DECREF(PyMethod_GET_FUNCTION(n));
      PyMethod_GET_FUNCTION(n) = x;
      x = copyrec(PyMethod_GET_SELF(n));
      Py_DECREF(PyMethod_GET_SELF(n));
      PyMethod_GET_SELF(n) = x;
      return n;
    }
  if (t == GeneratorType)
    {
      n = genbuild(o);
      if (!n || PyDict_SetItem(ss_memo, key, n)) goto fail;
      if (gencopy(n, o)) goto fail;
      return n;
    }
  if (t == &PySeqIter_Type)
    {
      n = seqiterbuild(o);
      if (!n || PyDict_SetItem(ss_memo, key, n)) goto fail;
      if (seqitercopy(n, o)) goto fail;
      return n;
    }
  ss_next_in_block++;
  return o;     /* reference no longer stored in 'fkey->o' */

 unmodified:
  PyDict_SetItem(ss_memo, key, o);
  Py_INCREF(o);
  return o;

 fail1:
  n = NULL;
 fail:
  Py_INCREF(o);
  Py_XDECREF(n);
  return o;
}
Beispiel #19
0
static int
PyExtensionClass_Export_(PyObject *dict, char *name, PyTypeObject *typ)
{
  long ecflags = 0;
  PyMethodDef *pure_methods = NULL, *mdef = NULL;
  PyObject *m;

  if (typ->tp_flags == 0) 
    { 
      /* Old-style EC */

      if (typ->tp_traverse) 
        { 
          /* ExtensionClasses stick there methods in the tp_traverse slot */
          mdef = (PyMethodDef *)typ->tp_traverse;

          if (typ->tp_basicsize <= sizeof(_emptyobject))
            /* Pure mixin. We want rebindable methods */
            pure_methods = mdef;
          else
            typ->tp_methods = mdef;

          typ->tp_traverse = NULL; 

          /* Look for __init__ method  */
          for (; mdef->ml_name; mdef++)
            {
              if (strcmp(mdef->ml_name, "__init__") == 0)
                {
                  /* we have an old-style __init__, install a special slot */
                  typ->tp_init = ec_init;
                  break;
                }
            }
        } 

      if (typ->tp_clear)
        {
          /* ExtensionClasses stick there flags in the tp_clear slot */
          ecflags = (long)(typ->tp_clear);

          /* Some old-style flags were set */

          if ((ecflags & EXTENSIONCLASS_BINDABLE_FLAG)
              && typ->tp_descr_get == NULL)
            /* We have __of__-style binding */
            typ->tp_descr_get = of_get; 
        }
      typ->tp_clear = NULL; 
      typ->tp_flags = Py_TPFLAGS_DEFAULT 
                    | Py_TPFLAGS_BASETYPE;

      if (typ->tp_dealloc != NULL)
          typ->tp_new = ec_new_for_custom_dealloc;
    }

  typ->ob_type = ECExtensionClassType; 

  if (ecflags & EXTENSIONCLASS_NOINSTDICT_FLAG)
    typ->tp_base = &NoInstanceDictionaryBaseType;
  else
    typ->tp_base = &BaseType;
  typ->tp_basicsize += typ->tp_base->tp_basicsize;

  if (typ->tp_new == NULL)
    typ->tp_new = PyType_GenericNew; 

  if (PyType_Ready(typ) < 0) 
    return -1; 

  if (pure_methods)
    {
      /* We had pure methods. We want to be able to rebind these, so
         we'll make them ordinary method wrappers around method descrs
      */
      for (; pure_methods->ml_name; pure_methods++)
        {
          m = PyDescr_NewMethod(ECBaseType, pure_methods);
          if (! m)
            return -1;
          m = PyMethod_New((PyObject *)m, NULL, (PyObject *)ECBaseType);
          if (! m)
            return -1;
          if (PyDict_SetItemString(typ->tp_dict, pure_methods->ml_name, m) 
              < 0)
            return -1;
        }      
#ifdef Py_TPFLAGS_HAVE_VERSION_TAG
      PyType_Modified(typ);
#endif
    }
  else if (mdef && mdef->ml_name)
    {
      /* Blast, we have to stick __init__ in the dict ourselves
         because PyType_Ready probably stuck a wrapper for ec_init in
         instead.
      */
      m = PyDescr_NewMethod(typ, mdef);
      if (! m)
        return -1;
      if (PyDict_SetItemString(typ->tp_dict, mdef->ml_name, m) < 0)
        return -1;
#ifdef Py_TPFLAGS_HAVE_VERSION_TAG
      PyType_Modified(typ);
#endif
    }

  if (PyMapping_SetItemString(dict, name, (PyObject*)typ) < 0)  
    return -1; 

  return 0;
}
Beispiel #20
0
/*
 * Invoke a single slot (Qt or Python) and return the result.
 */
PyObject *sip_api_invoke_slot(const sipSlot *slot, PyObject *sigargs)
{
    PyObject *sa, *oxtype, *oxvalue, *oxtb, *sfunc, *sref;

    /* Keep some compilers quiet. */
    oxtype = oxvalue = oxtb = NULL;

    /* Fan out Qt signals.  (Only PyQt3 will do this.) */
    if (slot->name != NULL && slot->name[0] != '\0')
    {
        assert(sipQtSupport->qt_emit_signal);

        if (sipQtSupport->qt_emit_signal(slot->pyobj, slot->name, sigargs) < 0)
            return NULL;

        Py_INCREF(Py_None);
        return Py_None;
    }

    /* Get the object to call, resolving any weak references. */
    if (slot->weakSlot == Py_True)
    {
        /*
         * The slot is guaranteed to be Ok because it has an extra reference or
         * is None.
         */
        sref = slot->pyobj;
        Py_INCREF(sref);
    }
    else if (slot -> weakSlot == NULL)
        sref = NULL;
    else if ((sref = PyWeakref_GetObject(slot -> weakSlot)) == NULL)
        return NULL;
    else
        Py_INCREF(sref);

    if (sref == Py_None)
    {
        /*
         * If the real object has gone then we pretend everything is Ok.  This
         * mimics the Qt behaviour of not caring if a receiving object has been
         * deleted.
         */
        Py_DECREF(sref);

        Py_INCREF(Py_None);
        return Py_None;
    }

    if (slot -> pyobj == NULL)
    {
        PyObject *self = (sref != NULL ? sref : slot->meth.mself);

        /*
         * If the receiver wraps a C++ object then ignore the call if it no
         * longer exists.
         */
        if (PyObject_TypeCheck(self, (PyTypeObject *)&sipSimpleWrapper_Type) &&
            sip_api_get_address((sipSimpleWrapper *)self) == NULL)
        {
            Py_XDECREF(sref);

            Py_INCREF(Py_None);
            return Py_None;
        }

#if PY_MAJOR_VERSION >= 3
        sfunc = PyMethod_New(slot->meth.mfunc, self);
#else
        sfunc = PyMethod_New(slot->meth.mfunc, self, slot->meth.mclass);
#endif

        if (sfunc == NULL)
        {
            Py_XDECREF(sref);
            return NULL;
        }
    }
    else if (slot -> name != NULL)
    {
        char *mname = slot -> name + 1;
        PyObject *self = (sref != NULL ? sref : slot->pyobj);

        if ((sfunc = PyObject_GetAttrString(self, mname)) == NULL || !PyCFunction_Check(sfunc))
        {
            /*
             * Note that in earlier versions of SIP this error would be
             * detected when the slot was connected.
             */
            PyErr_Format(PyExc_NameError,"Invalid slot %s",mname);

            Py_XDECREF(sfunc);
            Py_XDECREF(sref);
            return NULL;
        }
    }
    else
    {
        sfunc = slot->pyobj;
        Py_INCREF(sfunc);
    }

    /*
     * We make repeated attempts to call a slot.  If we work out that it failed
     * because of an immediate type error we try again with one less argument.
     * We keep going until we run out of arguments to drop.  This emulates the
     * Qt ability of the slot to accept fewer arguments than a signal provides.
     */
    sa = sigargs;
    Py_INCREF(sa);

    for (;;)
    {
        PyObject *nsa, *xtype, *xvalue, *xtb, *resobj;

        if ((resobj = PyEval_CallObject(sfunc, sa)) != NULL)
        {
            Py_DECREF(sfunc);
            Py_XDECREF(sref);

            /* Remove any previous exception. */

            if (sa != sigargs)
            {
                Py_XDECREF(oxtype);
                Py_XDECREF(oxvalue);
                Py_XDECREF(oxtb);
                PyErr_Clear();
            }

            Py_DECREF(sa);

            return resobj;
        }

        /* Get the exception. */
        PyErr_Fetch(&xtype,&xvalue,&xtb);

        /*
         * See if it is unacceptable.  An acceptable failure is a type error
         * with no traceback - so long as we can still reduce the number of
         * arguments and try again.
         */
        if (!PyErr_GivenExceptionMatches(xtype,PyExc_TypeError) ||
            xtb != NULL ||
            PyTuple_GET_SIZE(sa) == 0)
        {
            /*
             * If there is a traceback then we must have called the slot and
             * the exception was later on - so report the exception as is.
             */
            if (xtb != NULL)
            {
                if (sa != sigargs)
                {
                    Py_XDECREF(oxtype);
                    Py_XDECREF(oxvalue);
                    Py_XDECREF(oxtb);
                }

                PyErr_Restore(xtype,xvalue,xtb);
            }
            else if (sa == sigargs)
                PyErr_Restore(xtype,xvalue,xtb);
            else
            {
                /*
                 * Discard the latest exception and restore the original one.
                 */
                Py_XDECREF(xtype);
                Py_XDECREF(xvalue);
                Py_XDECREF(xtb);

                PyErr_Restore(oxtype,oxvalue,oxtb);
            }

            break;
        }

        /* If this is the first attempt, save the exception. */
        if (sa == sigargs)
        {
            oxtype = xtype;
            oxvalue = xvalue;
            oxtb = xtb;
        }
        else
        {
            Py_XDECREF(xtype);
            Py_XDECREF(xvalue);
            Py_XDECREF(xtb);
        }

        /* Create the new argument tuple. */
        if ((nsa = PyTuple_GetSlice(sa,0,PyTuple_GET_SIZE(sa) - 1)) == NULL)
        {
            /* Tidy up. */
            Py_XDECREF(oxtype);
            Py_XDECREF(oxvalue);
            Py_XDECREF(oxtb);

            break;
        }

        Py_DECREF(sa);
        sa = nsa;
    }

    Py_DECREF(sfunc);
    Py_XDECREF(sref);

    Py_DECREF(sa);

    return NULL;
}
Beispiel #21
0
// get attribute 'name' for object.
// uses obj->attr list of tuples for storage.
// returns new reference.
PyObject* pyjobject_getattr(PyJObject *obj,
                            char *name)
{
    PyObject *ret, *pyname, *methods, *members;
    ret = pyname = methods = members = NULL;

    if (!name) {
        Py_RETURN_NONE;
    }
    pyname  = PyString_FromString(name);
    methods = PyString_FromString("__methods__");
    members = PyString_FromString("__members__");

    if (PyObject_RichCompareBool(pyname, methods, Py_EQ)) {
        Py_DECREF(pyname);
        Py_DECREF(methods);
        Py_DECREF(members);

        Py_INCREF(obj->methods);
        return obj->methods;
    }
    Py_DECREF(methods);

    if (PyObject_RichCompareBool(pyname, members, Py_EQ)) {
        Py_DECREF(pyname);
        Py_DECREF(members);

        Py_INCREF(obj->fields);
        return obj->fields;
    }
    Py_DECREF(members);

    if (!PyList_Check(obj->attr)) {
        Py_DECREF(pyname);
        PyErr_Format(PyExc_RuntimeError, "Invalid attr list.");
        return NULL;
    }

    // util function fetches from attr list for us.
    ret = tuplelist_getitem(obj->attr, pyname);      /* new reference */
    Py_DECREF(pyname);

    // method optimizations
    if (pyjmethod_check(ret) || PyJmultiMethod_Check(ret)) {
        /*
         * TODO Should not bind non-static methods to pyjclass objects, but not
         * sure yet how to handle multimethods and static methods.
         */
#if PY_MAJOR_VERSION >= 3
        PyObject* wrapper = PyMethod_New(ret, (PyObject*) obj);
#else
        PyObject* wrapper = PyMethod_New(ret, (PyObject*) obj,
                                         (PyObject*) Py_TYPE(obj));
#endif
        Py_DECREF(ret);
        ret = wrapper;
    }

    if (PyErr_Occurred() || ret == Py_None) {
        if (ret == Py_None) {
            Py_DECREF(Py_None);
        }
        PyErr_Format(PyExc_AttributeError, "attr not found: %s", name);
        return NULL;
    }

    if (pyjfield_check(ret)) {
        PyObject *t = pyjfield_get((PyJFieldObject *) ret);
        Py_DECREF(ret);
        return t;
    }

    return ret;
}