// Get the receiver QObject from the slot (if there is one) and its signature
// (if it wraps a Qt slot).  A Python exception will be raised if there was an
// error.
static QObject *get_receiver(qpycore_pyqtBoundSignal *bs, PyObject *slot_obj,
        QByteArray &name)
{
    PyObject *rx_self, *decorations;
    QByteArray rx_name;
    bool try_qt_slot;
    Chimera::Signature *signature = bs->unbound_signal->signature;

    decorations = 0;

    if (PyMethod_Check(slot_obj))
    {
        rx_self = PyMethod_GET_SELF(slot_obj);

        PyObject *f = PyMethod_GET_FUNCTION(slot_obj);
        Q_ASSERT(PyFunction_Check(f));

        PyObject *f_name_obj = ((PyFunctionObject *)f)->func_name;
        const char *f_name = sipString_AsASCIIString(&f_name_obj);
        Q_ASSERT(f_name);

        rx_name = f_name;
        Py_DECREF(f_name_obj);

        // See if this has been decorated.
        decorations = PyObject_GetAttr(f, qpycore_signature_attr_name);

        if (decorations)
        {
            try_qt_slot = true;

            // It's convenient to do this here as it's not going to disappear.
            Py_DECREF(decorations);
        }
        else
        {
            try_qt_slot = false;
        }

        Py_XINCREF(rx_self);
    }
    else if (PyCFunction_Check(slot_obj))
    {
        rx_self = PyCFunction_GET_SELF(slot_obj);
        rx_name = ((PyCFunctionObject *)slot_obj)->m_ml->ml_name;

        // We actually want the C++ name which may (in theory) be completely
        // different.  However this will cope with the exec_ case which is
        // probably good enough.
        if (rx_name.endsWith('_'))
            rx_name.chop(1);

        try_qt_slot = true;

        Py_XINCREF(rx_self);
    }
    else
    {
        static PyObject *partial = 0;

        // Get the functools.partial type object if we haven't already got it.
        if (!partial)
        {
            PyObject *functools = PyImport_ImportModule("functools");

            if (functools)
            {
                partial = PyObject_GetAttrString(functools, "partial");
                Py_DECREF(functools);
            }
        }

        // If we know about functools.partial then remove the outer partials to
        // get to the original function.
        if (partial && PyObject_IsInstance(slot_obj, partial))
        {
            PyObject *func = slot_obj;

            Py_INCREF(func);

            do
            {
                PyObject *subfunc = PyObject_GetAttrString(func, "func");

                Py_DECREF(func);

                // This should never happen.
                if (!subfunc)
                    return 0;

                func = subfunc;
            }
            while (PyObject_IsInstance(func, partial));

            if (PyMethod_Check(func))
                rx_self = PyMethod_GET_SELF(func);
            else if (PyCFunction_Check(func))
                rx_self = PyCFunction_GET_SELF(func);
            else
                rx_self = 0;

            Py_XINCREF(rx_self);
            Py_DECREF(func);

            try_qt_slot = false;
        }
        else
        {
            rx_self = 0;
        }
    }
 
    if (!rx_self)
        return 0;

    int iserr = 0;
    void *rx = sipForceConvertToType(rx_self, sipType_QObject, 0,
            SIP_NO_CONVERTORS, 0, &iserr);

    Py_DECREF(rx_self);

    PyErr_Clear();

    if (iserr)
        return 0;

    QObject *rx_qobj = reinterpret_cast<QObject *>(rx);

    // If there might be a Qt slot that can handle the arguments (or a subset
    // of them) then use it.  Otherwise we will fallback to using a proxy.
    if (try_qt_slot)
    {
        for (int ol = signature->parsed_arguments.count(); ol >= 0; --ol)
        {
            // If there are decorations then we compare the signal's signature
            // against them so that we distinguish between Python types that
            // are passed to Qt as PyQt_PyObject objects.  Qt will not make the
            // distinction.  If there are no decorations then let Qt determine
            // if a slot is available.
            if (decorations)
                name = slot_signature_from_decorations(signature, decorations,
                        ol);
            else
                name = slot_signature_from_metaobject(signature,
                        rx_qobj->metaObject(), rx_name, ol);

            if (!name.isEmpty())
            {
                // Prepend the magic slot marker.
                name.prepend('1');
                break;
            }
        }
    }

    return rx_qobj;
}
示例#2
0
static foreign_t python_function(term_t tobj) {
  PyObject *obj = term_to_python(tobj, true);
    foreign_t rc = PyFunction_Check(obj);

    return rc;
}
示例#3
0
文件: pyevent.c 项目: KaSt/nereamud
//
// no point in reinventing the wheel; start_event and start_update both
// need to be handled exactly the same, so here's a function to do just that
PyObject *PyEvent_start(PyObject *self, PyObject *args, void *func) {
  void (* start_func)(void *, int, void *, void *, void *, const char *) = func;
  PyObject *PyOwner = NULL;    // the python representation of our owner
  PyObject   *efunc = NULL;    // the event function
  PyObject   *edata = Py_None; // the event data
  char         *arg = NULL;    // the arg we will be supplying to the function
  double      delay = 0;       // how long the event delay is (in seconds)
  void       *owner = NULL;    // actual owner supplied to the event handler
  char    otype[20];           // is the owner a char, room, obj, or None?

  // try to parse all of our values
  if(!PyArg_ParseTuple(args, "OdO|Os", &PyOwner, &delay, &efunc, &edata, &arg)){
    //PyErr_Format(PyExc_TypeError, 
    //"Invalid arguments provided to event handler");
    return NULL;
  }

  // make sure our event is a function
  if(!PyFunction_Check(efunc)) {
    PyErr_Format(PyExc_TypeError,
		 "The event handler supplied must be a python function");
    return NULL;
  }

  // figure out what type of data our owner is
  if(PyOwner == Py_None) {
    owner = NULL;
    sprintf(otype, "none");
  }
  else if(PyChar_Check(PyOwner)) {
    owner = PyChar_AsChar(PyOwner);
    sprintf(otype, "char");
  }
  else if(PyRoom_Check(PyOwner)) {
    owner = PyRoom_AsRoom(PyOwner);
    sprintf(otype, "room");
  }
  else if(PyObj_Check(PyOwner)) {
    owner = PyObj_AsObj(PyOwner);
    sprintf(otype, "obj");
  }
  // invalid type
  else {
    PyErr_Format(PyExc_TypeError,
		 "An event owner must be a room, char, obj, or none");
    return NULL;
  }

  // make sure the owner exists
  if(PyOwner != Py_None && owner == NULL) {
    PyErr_Format(PyExc_StandardError, "Owner supplied does not exist in game");
    return NULL;
  }
  
  // now, queue up the action
  start_func(owner, (int)(delay SECONDS), PyEvent_on_complete, NULL, 
	     Py_BuildValue("sOO", otype, efunc, edata), arg);

  // everything seems ok. exit normally
  return Py_BuildValue("i", 1);
}
void PythonQtSignalTarget::call(void **arguments) const
{
  // Note: we check if the callable is a PyFunctionObject and has a fixed number of arguments
  // if that is the case, we only pass these arguments to python and skip the additional arguments from the signal
  
  int numPythonArgs = -1;
  if (PyFunction_Check(_callable)) {
    PyObject* o = _callable;
    PyFunctionObject* func = (PyFunctionObject*)o;
    PyCodeObject* code = (PyCodeObject*)func->func_code;
    if (!(code->co_flags & 0x04)) {
      numPythonArgs = code->co_argcount;
    } else {
      // variable numbers of arguments allowed
    }
  } else if (PyMethod_Check(_callable)) {
    PyObject* o = _callable;
    PyMethodObject* method = (PyMethodObject*)o;
    if (PyFunction_Check(method->im_func)) {
      PyFunctionObject* func = (PyFunctionObject*)method->im_func;
      PyCodeObject* code = (PyCodeObject*)func->func_code;
      if (!(code->co_flags & 0x04)) {
        numPythonArgs = code->co_argcount - 1; // we subtract one because the first is "self"
      } else {
        // variable numbers of arguments allowed
      }
    }
  }

  const PythonQtMethodInfo* m = methodInfo();
  // parameterCount includes return value:
  int count = m->parameterCount();
  if (numPythonArgs!=-1) {
    if (count>numPythonArgs+1) {
      // take less arguments
      count = numPythonArgs+1;
    }
  }

  PyObject* pargs = NULL;
  if (count>1) {
    pargs = PyTuple_New(count-1);
  }
  bool err = false;
  // transform Qt values to Python
  const QList<PythonQtMethodInfo::ParameterInfo>& params = m->parameters();
  for (int i = 1; i < count; i++) {
    const PythonQtMethodInfo::ParameterInfo& param = params.at(i);
    PyObject* arg = PythonQtConv::ConvertQtValueToPython(param, arguments[i]);
    if (arg) {
      // steals reference, no unref
      PyTuple_SetItem(pargs, i-1,arg);
    } else {
      err = true;
      break;
    }
  }

  if (!err) {
    PyErr_Clear();
    PyObject* result = PyObject_CallObject(_callable, pargs);
    if (result) {
      // ok
      Py_DECREF(result);
    } else {
      PythonQt::self()->handleError();
    }
  }
  if (pargs) {
    // free the arguments again
    Py_DECREF(pargs);
  }
}
示例#5
0
static gboolean
gplp_func_desc_load (GOPluginService *service,
		     char const *name,
		     GnmFuncDescriptor *res)
{
	ServiceLoaderDataFunctionGroup *loader_data;
	PyObject *fn_info_obj;

	g_return_val_if_fail (IS_GNM_PLUGIN_SERVICE_FUNCTION_GROUP (service), FALSE);
	g_return_val_if_fail (name != NULL, FALSE);

	loader_data = g_object_get_data (G_OBJECT (service), "loader_data");
	SWITCH_TO_PLUGIN (go_plugin_service_get_plugin (service));
	fn_info_obj = PyDict_GetItemString (loader_data->python_fn_info_dict,
					    (gchar *) name);
	if (fn_info_obj == NULL) {
		gnm_python_clear_error_if_needed (SERVICE_GET_LOADER (service)->py_object);
		return FALSE;
	}

	if (PyTuple_Check (fn_info_obj)) {
		PyObject *python_args, *python_arg_names;
		PyObject *python_fn;

		if (PyTuple_Size (fn_info_obj) == 3 &&
		    (python_args = PyTuple_GetItem (fn_info_obj, 0)) != NULL &&
			PyString_Check (python_args) &&
		    (python_arg_names = PyTuple_GetItem (fn_info_obj, 1)) != NULL &&
		    PyString_Check (python_arg_names) &&
		    (python_fn = PyTuple_GetItem (fn_info_obj, 2)) != NULL &&
		    PyFunction_Check (python_fn)) {
			res->arg_spec	= PyString_AsString (python_args);
#if 0
			res->arg_names  = PyString_AsString (python_arg_names);
#endif
			res->help	= python_function_get_gnumeric_help (
				loader_data->python_fn_info_dict, python_fn, name);
			res->fn_args	= &call_python_function_args;
			res->fn_nodes	= NULL;
			res->linker	= NULL;
			res->unlinker	= NULL;
			res->impl_status = GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC;
			res->test_status = GNM_FUNC_TEST_STATUS_UNKNOWN;
			return TRUE;
		}

		gnm_python_clear_error_if_needed (SERVICE_GET_LOADER (service)->py_object);
		return FALSE;
	}

	if (PyFunction_Check (fn_info_obj)) {
		res->arg_spec	= "";
		res->help	= python_function_get_gnumeric_help (
			loader_data->python_fn_info_dict, fn_info_obj, name);
		res->fn_args	= NULL;
		res->fn_nodes	= &call_python_function_nodes;
		res->linker	= NULL;
		res->unlinker	= NULL;
		res->impl_status = GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC;
		res->test_status = GNM_FUNC_TEST_STATUS_UNKNOWN;
		return TRUE;
	}

	gnm_python_clear_error_if_needed (SERVICE_GET_LOADER (service)->py_object);
	return FALSE;
}
// Get the receiver QObject from the slot (if there is one) and its signature
// (if it wraps a Qt slot).  A Python exception will be raised if there was an
// error.
static QObject *get_receiver(Chimera::Signature *overload, PyObject *slot_obj,
        QByteArray &name)
{
    PyObject *rx_self, *decorations;
    QByteArray rx_name;
    bool try_qt_slot;

    decorations = 0;

    if (PyMethod_Check(slot_obj))
    {
        rx_self = PyMethod_GET_SELF(slot_obj);

        PyObject *f = PyMethod_GET_FUNCTION(slot_obj);
        Q_ASSERT(PyFunction_Check(f));

        PyObject *f_name_obj = ((PyFunctionObject *)f)->func_name;
        const char *f_name = sipString_AsASCIIString(&f_name_obj);
        Q_ASSERT(f_name);

        rx_name = f_name;
        Py_DECREF(f_name_obj);

        // See if this has been decorated.
        decorations = PyObject_GetAttr(f, qpycore_signature_attr_name);

        if (decorations)
        {
            try_qt_slot = true;

            // It's convenient to do this here as it's not going to disappear.
            Py_DECREF(decorations);
        }
        else
        {
            try_qt_slot = false;
        }
    }
    else if (PyCFunction_Check(slot_obj))
    {
        rx_self = PyCFunction_GET_SELF(slot_obj);
        rx_name = ((PyCFunctionObject *)slot_obj)->m_ml->ml_name;

        // We actually want the C++ name which may (in theory) be completely
        // different.  However this will cope with the exec_ case which is
        // probably good enough.
        if (rx_name.endsWith('_'))
            rx_name.chop(1);

        try_qt_slot = true;
    }
    else
    {
        rx_self = 0;
    }
 
    if (!rx_self)
        return 0;

    int iserr = 0;
    void *rx = sipForceConvertToType(rx_self, sipType_QObject, 0,
            SIP_NO_CONVERTORS, 0, &iserr);

    PyErr_Clear();

    if (iserr)
        return 0;

    QObject *rx_qobj = reinterpret_cast<QObject *>(rx);

    // If there might be a Qt slot that can handle the arguments (or a subset
    // of them) then use it.  Otherwise we will fallback to using a proxy.
    if (try_qt_slot)
    {
        for (int ol = overload->parsed_arguments.count(); ol >= 0; --ol)
        {
            // If there are decorations then we compare the signal's signature
            // against them so that we distinguish between Python types that
            // are passed to Qt as PyQt_PyObject objects.  Qt will not make the
            // distinction.  If there are no decorations then let Qt determine
            // if a slot is available.
            if (decorations)
                name = slot_signature_from_decorations(overload, decorations,
                        ol);
            else
                name = slot_signature_from_metaobject(overload,
                        rx_qobj->metaObject(), rx_name, ol);

            if (!name.isEmpty())
            {
                // Prepend the magic slot marker.
                name.prepend('1');
                break;
            }
        }
    }

    return rx_qobj;
}
示例#7
0
static char const *GET_CALLABLE_DESC( PyObject *object )
{
    if ( Nuitka_Function_Check( object ) || Nuitka_Generator_Check( object ) || PyMethod_Check( object ) || PyFunction_Check( object ) || PyCFunction_Check( object ) )
    {
        return "()";
    }
#if PYTHON_VERSION < 300
    else if ( PyClass_Check( object ) )
    {
        return " constructor";
    }
    else if ( PyInstance_Check( object ))
    {
        return " instance";
    }
#endif
    else
    {
        return " object";
    }
}