Пример #1
0
static rlm_rcode_t do_python(rlm_python_t *inst, REQUEST *request, PyObject *pFunc, char const *funcname, bool worker)
{
	vp_cursor_t	cursor;
	VALUE_PAIR      *vp;
	PyObject	*pRet = NULL;
	PyObject	*pArgs = NULL;
	int		tuplelen;
	int		ret;

	PyGILState_STATE gstate;
	PyThreadState	*prev_thread_state = NULL;	/* -Wuninitialized */
	memset(&gstate, 0, sizeof(gstate));		/* -Wuninitialized */

	/* Return with "OK, continue" if the function is not defined. */
	if (!pFunc)
		return RLM_MODULE_NOOP;

#ifdef HAVE_PTHREAD_H
	gstate = PyGILState_Ensure();
	if (worker) {
		PyThreadState *my_thread_state;
		my_thread_state = fr_thread_local_init(local_thread_state, do_python_cleanup);
		if (!my_thread_state) {
			my_thread_state = PyThreadState_New(inst->main_thread_state->interp);
			if (!my_thread_state) {
				REDEBUG("Failed initialising local PyThreadState on first run");
				PyGILState_Release(gstate);
				return RLM_MODULE_FAIL;
			}

			ret = fr_thread_local_set(local_thread_state, my_thread_state);
			if (ret != 0) {
				REDEBUG("Failed storing PyThreadState in TLS: %s", fr_syserror(ret));
				PyThreadState_Clear(my_thread_state);
				PyThreadState_Delete(my_thread_state);
				PyGILState_Release(gstate);
				return RLM_MODULE_FAIL;
			}
		}
		prev_thread_state = PyThreadState_Swap(my_thread_state);	/* Swap in our local thread state */
	}
#endif

	/* Default return value is "OK, continue" */
	ret = RLM_MODULE_OK;

	/*
	 *	We will pass a tuple containing (name, value) tuples
	 *	We can safely use the Python function to build up a
	 *	tuple, since the tuple is not used elsewhere.
	 *
	 *	Determine the size of our tuple by walking through the packet.
	 *	If request is NULL, pass None.
	 */
	tuplelen = 0;
	if (request != NULL) {
		for (vp = paircursor(&cursor, &request->packet->vps);
		     vp;
		     vp = pairnext(&cursor)) {
			tuplelen++;
		}
	}

	if (tuplelen == 0) {
		Py_INCREF(Py_None);
		pArgs = Py_None;
	} else {
		int i = 0;
		if ((pArgs = PyTuple_New(tuplelen)) == NULL) {
			ret = RLM_MODULE_FAIL;
			goto finish;
		}

		for (vp = paircursor(&cursor, &request->packet->vps);
		     vp;
		     vp = pairnext(&cursor), i++) {
			PyObject *pPair;

			/* The inside tuple has two only: */
			if ((pPair = PyTuple_New(2)) == NULL) {
				ret = RLM_MODULE_FAIL;
				goto finish;
			}

			if (mod_populate_vptuple(pPair, vp) == 0) {
				/* Put the tuple inside the container */
				PyTuple_SET_ITEM(pArgs, i, pPair);
			} else {
				Py_INCREF(Py_None);
				PyTuple_SET_ITEM(pArgs, i, Py_None);
				Py_DECREF(pPair);
			}
		}
	}

	/* Call Python function. */
	pRet = PyObject_CallFunctionObjArgs(pFunc, pArgs, NULL);

	if (!pRet) {
		ret = RLM_MODULE_FAIL;
		goto finish;
	}

	if (!request)
		goto finish;

	/*
	 *	The function returns either:
	 *  1. (returnvalue, replyTuple, configTuple), where
	 *   - returnvalue is one of the constants RLM_*
	 *   - replyTuple and configTuple are tuples of string
	 *      tuples of size 2
	 *
	 *  2. the function return value alone
	 *
	 *  3. None - default return value is set
	 *
	 * xxx This code is messy!
	 */
	if (PyTuple_CheckExact(pRet)) {
		PyObject *pTupleInt;

		if (PyTuple_GET_SIZE(pRet) != 3) {
			ERROR("rlm_python:%s: tuple must be (return, replyTuple, configTuple)", funcname);
			ret = RLM_MODULE_FAIL;
			goto finish;
		}

		pTupleInt = PyTuple_GET_ITEM(pRet, 0);
		if (!PyInt_CheckExact(pTupleInt)) {
			ERROR("rlm_python:%s: first tuple element not an integer", funcname);
			ret = RLM_MODULE_FAIL;
			goto finish;
		}
		/* Now have the return value */
		ret = PyInt_AsLong(pTupleInt);
		/* Reply item tuple */
		mod_vptuple(request->reply, &request->reply->vps,
			    PyTuple_GET_ITEM(pRet, 1), funcname);
		/* Config item tuple */
		mod_vptuple(request, &request->config_items,
			    PyTuple_GET_ITEM(pRet, 2), funcname);

	} else if (PyInt_CheckExact(pRet)) {
		/* Just an integer */
		ret = PyInt_AsLong(pRet);

	} else if (pRet == Py_None) {
		/* returned 'None', return value defaults to "OK, continue." */
		ret = RLM_MODULE_OK;
	} else {
		/* Not tuple or None */
		ERROR("rlm_python:%s: function did not return a tuple or None", funcname);
		ret = RLM_MODULE_FAIL;
		goto finish;
	}

finish:
	if (pArgs) {
		Py_DECREF(pArgs);
	}
	if (pRet) {
		Py_DECREF(pRet);
	}

#ifdef HAVE_PTHREAD_H
	if (worker) {
		PyThreadState_Swap(prev_thread_state);
	}
	PyGILState_Release(gstate);
#endif

	return ret;
}
Пример #2
0
/**
 * _py_args_combine_and_check_length:
 * @cache: PyGICallableCache
 * @py_args: the tuple of positional arguments.
 * @py_kwargs: the dict of keyword arguments to be merged with py_args.
 *
 * Returns: New value reference to the combined py_args and py_kwargs.
 */
static PyObject *
_py_args_combine_and_check_length (PyGICallableCache *cache,
                                   PyObject    *py_args,
                                   PyObject    *py_kwargs)
{
    PyObject *combined_py_args = NULL;
    Py_ssize_t n_py_args, n_py_kwargs, i;
    guint n_expected_args = cache->n_py_args;
    GSList *l;

    n_py_args = PyTuple_GET_SIZE (py_args);
    if (py_kwargs == NULL)
        n_py_kwargs = 0;
    else
        n_py_kwargs = PyDict_Size (py_kwargs);

    /* Fast path, we already have the exact number of args and not kwargs. */
    if (n_py_kwargs == 0 && n_py_args == n_expected_args && cache->user_data_varargs_index < 0) {
        Py_INCREF (py_args);
        return py_args;
    }

    if (cache->user_data_varargs_index < 0 && n_expected_args < n_py_args) {
        char *full_name = pygi_callable_cache_get_full_name (cache);
        PyErr_Format (PyExc_TypeError,
                      "%.200s() takes exactly %d %sargument%s (%zd given)",
                      full_name,
                      n_expected_args,
                      n_py_kwargs > 0 ? "non-keyword " : "",
                      n_expected_args == 1 ? "" : "s",
                      n_py_args);
        g_free (full_name);
        return NULL;
    }

    if (cache->user_data_varargs_index >= 0 && n_py_kwargs > 0 && n_expected_args < n_py_args) {
        char *full_name = pygi_callable_cache_get_full_name (cache);
        PyErr_Format (PyExc_TypeError,
                      "%.200s() cannot use variable user data arguments with keyword arguments",
                      full_name);
        g_free (full_name);
        return NULL;
    }

    if (n_py_kwargs > 0 && !_check_for_unexpected_kwargs (cache,
                                                          cache->arg_name_hash,
                                                          py_kwargs)) {
        return NULL;
    }

    /* will hold arguments from both py_args and py_kwargs
     * when they are combined into a single tuple */
    combined_py_args = PyTuple_New (n_expected_args);

    for (i = 0, l = cache->arg_name_list; i < n_expected_args && l; i++, l = l->next) {
        PyObject *py_arg_item = NULL;
        PyObject *kw_arg_item = NULL;
        const gchar *arg_name = l->data;
        int arg_cache_index = -1;
        gboolean is_varargs_user_data = FALSE;

        if (arg_name != NULL)
            arg_cache_index = GPOINTER_TO_INT (g_hash_table_lookup (cache->arg_name_hash, arg_name));

        is_varargs_user_data = cache->user_data_varargs_index >= 0 &&
                                arg_cache_index == cache->user_data_varargs_index;

        if (n_py_kwargs > 0 && arg_name != NULL) {
            /* NULL means this argument has no keyword name */
            /* ex. the first argument to a method or constructor */
            kw_arg_item = PyDict_GetItemString (py_kwargs, arg_name);
        }

        /* use a bounded retrieval of the original input */
        if (i < n_py_args)
            py_arg_item = PyTuple_GET_ITEM (py_args, i);

        if (kw_arg_item == NULL && py_arg_item != NULL) {
            if (is_varargs_user_data) {
                /* For tail end user_data varargs, pull a slice off and we are done. */
                PyObject *user_data = PyTuple_GetSlice (py_args, i, PY_SSIZE_T_MAX);
                PyTuple_SET_ITEM (combined_py_args, i, user_data);
                return combined_py_args;
            } else {
                Py_INCREF (py_arg_item);
                PyTuple_SET_ITEM (combined_py_args, i, py_arg_item);
            }
        } else if (kw_arg_item != NULL && py_arg_item == NULL) {
            if (is_varargs_user_data) {
                /* Special case where user_data is passed as a keyword argument (user_data=foo)
                 * Wrap the value in a tuple to represent variable args for marshaling later on.
                 */
                PyObject *user_data = Py_BuildValue("(O)", kw_arg_item, NULL);
                PyTuple_SET_ITEM (combined_py_args, i, user_data);
            } else {
                Py_INCREF (kw_arg_item);
                PyTuple_SET_ITEM (combined_py_args, i, kw_arg_item);
            }

        } else if (kw_arg_item == NULL && py_arg_item == NULL) {
            if (is_varargs_user_data) {
                /* For varargs user_data, pass an empty tuple when nothing is given. */
                PyTuple_SET_ITEM (combined_py_args, i, PyTuple_New (0));
            } else if (arg_cache_index >= 0 && _pygi_callable_cache_get_arg (cache, arg_cache_index)->has_default) {
                /* If the argument supports a default, use a place holder in the
                 * argument tuple, this will be checked later during marshaling.
                 */
                Py_INCREF (_PyGIDefaultArgPlaceholder);
                PyTuple_SET_ITEM (combined_py_args, i, _PyGIDefaultArgPlaceholder);
            } else {
                char *full_name = pygi_callable_cache_get_full_name (cache);
                PyErr_Format (PyExc_TypeError,
                              "%.200s() takes exactly %d %sargument%s (%zd given)",
                              full_name,
                              n_expected_args,
                              n_py_kwargs > 0 ? "non-keyword " : "",
                              n_expected_args == 1 ? "" : "s",
                              n_py_args);
                g_free (full_name);

                Py_DECREF (combined_py_args);
                return NULL;
            }
        } else if (kw_arg_item != NULL && py_arg_item != NULL) {
            char *full_name = pygi_callable_cache_get_full_name (cache);
            PyErr_Format (PyExc_TypeError,
                          "%.200s() got multiple values for keyword argument '%.200s'",
                          full_name,
                          arg_name);

            Py_DECREF (combined_py_args);
            g_free (full_name);
            return NULL;
        }
    }

    return combined_py_args;
}
Пример #3
0
PyCodeObject *
PyCode_New(int argcount, int nlocals, int stacksize, int flags,
	   PyObject *code, PyObject *consts, PyObject *names,
	   PyObject *varnames, PyObject *freevars, PyObject *cellvars,
	   PyObject *filename, PyObject *name, int firstlineno,
	   PyObject *lnotab) 
{
	PyCodeObject *co;
	int i;
	/* Check argument types */
	if (argcount < 0 || nlocals < 0 ||
	    code == NULL ||
	    consts == NULL || !PyTuple_Check(consts) ||
	    names == NULL || !PyTuple_Check(names) ||
	    varnames == NULL || !PyTuple_Check(varnames) ||
	    freevars == NULL || !PyTuple_Check(freevars) ||
	    cellvars == NULL || !PyTuple_Check(cellvars) ||
	    name == NULL || !PyString_Check(name) ||
	    filename == NULL || !PyString_Check(filename) ||
	    lnotab == NULL || !PyString_Check(lnotab) ||
	    !PyObject_CheckReadBuffer(code)) {
		PyErr_BadInternalCall();
		return NULL;
	}
	intern_strings(names);
	intern_strings(varnames);
	intern_strings(freevars);
	intern_strings(cellvars);
	/* Intern selected string constants */
	for (i = PyTuple_Size(consts); --i >= 0; ) {
		PyObject *v = PyTuple_GetItem(consts, i);
		if (!PyString_Check(v))
			continue;
		if (!all_name_chars((unsigned char *)PyString_AS_STRING(v)))
			continue;
		PyString_InternInPlace(&PyTuple_GET_ITEM(consts, i));
	}
	co = PyObject_NEW(PyCodeObject, &PyCode_Type);
	if (co != NULL) {
		co->co_argcount = argcount;
		co->co_nlocals = nlocals;
		co->co_stacksize = stacksize;
		co->co_flags = flags;
		co->co_code = optimize_code(code, consts);
		Py_INCREF(consts);
		co->co_consts = consts;
		Py_INCREF(names);
		co->co_names = names;
		Py_INCREF(varnames);
		co->co_varnames = varnames;
		Py_INCREF(freevars);
		co->co_freevars = freevars;
		Py_INCREF(cellvars);
		co->co_cellvars = cellvars;
		Py_INCREF(filename);
		co->co_filename = filename;
		Py_INCREF(name);
		co->co_name = name;
		co->co_firstlineno = firstlineno;
		Py_INCREF(lnotab);
		co->co_lnotab = lnotab;
		if (PyTuple_GET_SIZE(freevars) == 0 &&
		    PyTuple_GET_SIZE(cellvars) == 0)
		    co->co_flags |= CO_NOFREE;
	}
	return co;
}
Пример #4
0
static PyObj
array_sql_get_element(PyObj self, PyObj indexes_ob)
{
	PyObj tup, element_type, rob = NULL;
	PyPgTypeInfo atypinfo, typinfo;
	ArrayType *at;
	int i, nindexes, indexes[MAXDIM] = {0,};

	/*
	 * Convert the dimensions keyword into a tuple and extract the values
	 * into the dims[] array.
	 */

	tup = Py_Call((PyObj) &PyTuple_Type, indexes_ob);
	if (tup == NULL)
		return(NULL);

	at = DatumGetArrayTypeP(PyPgObject_GetDatum(self));
	Assert(at != NULL);

	nindexes = (int) PyTuple_GET_SIZE(tup);
	if (nindexes != ARR_NDIM(at))
	{
		Py_DECREF(tup);
		Py_INCREF(Py_None);
		return(Py_None);
	}

	for (i = 0; i < nindexes; ++i)
	{
		indexes[i] = (int) PyNumber_AsSsize_t(PyTuple_GET_ITEM(tup, i),
											NULL);
		if (PyErr_Occurred())
		{
			Py_DECREF(tup);
			return(NULL);
		}
	}

	Py_DECREF(tup);

	atypinfo = PyPgTypeInfo(Py_TYPE(self));
	element_type = PyPgType_GetElementType(Py_TYPE(self));
	typinfo = PyPgTypeInfo(element_type);

	/*
	 * Single dimenion array? Get an element.
	 */
	PG_TRY();
	{
		Datum rd;
		bool isnull = false;

		rd = array_ref(at, nindexes, indexes, atypinfo->typlen,
			typinfo->typlen, typinfo->typbyval, typinfo->typalign, &isnull);

		if (isnull)
		{
			rob = Py_None;
			Py_INCREF(rob);
		}
		else
		{
			/*
			 * It points into the array structure, so there's no need to free.
			 */
			rob = PyPgObject_New(element_type, rd);
		}
	}
	PG_CATCH();
	{
		PyErr_SetPgError(false);
	}
	PG_END_TRY();

	return(rob);
}
Пример #5
0
/*
 * Array.get_element(indexes) - Get an element from the array.
 *
 * This uses Python sequence semantics(zero-based indexes, IndexError's).
 */
static PyObj
array_get_element(PyObj self, PyObj indexes_ob)
{
	PyObj tup, element_type, rob = NULL;
	PyPgTypeInfo atypinfo, typinfo;
	ArrayType *at;
	int i, nindexes, indexes[MAXDIM] = {0,};

	/*
	 * Convert the indexes_ob into a tuple and extract the values
	 * into the indexes[] array. Do any necessary checks along the way.
	 */
	tup = Py_Call((PyObj) &PyTuple_Type, indexes_ob);
	if (tup == NULL)
		return(NULL);

	nindexes = (int) PyTuple_GET_SIZE(tup);

	if (!(nindexes > 0))
	{
		Py_DECREF(tup);
		PyErr_SetString(PyExc_ValueError, "empty index tuple");
		return(NULL);
	}

	at = DatumGetArrayTypeP(PyPgObject_GetDatum(self));
	Assert(at != NULL);

	if (nindexes != ARR_NDIM(at))
	{
		Py_DECREF(tup);
		if (ARR_NDIM(at) == 0)
			PyErr_SetString(PyExc_IndexError, "no elements in array");
		else
			PyErr_Format(PyExc_ValueError, "element access requires exactly %d indexes, given %d",
				ARR_NDIM(at), nindexes);
		return(NULL);
	}

	for (i = 0; i < nindexes; ++i)
	{
		int index;
		index = (int) PyNumber_AsSsize_t(PyTuple_GET_ITEM(tup, i),
											NULL);
		if (PyErr_Occurred())
		{
			Py_DECREF(tup);
			return(NULL);
		}

		/*
		 * Adjust for backwards based access. (feature of get_element)
		 */
		if (index < 0)
			indexes[i] = index + ARR_DIMS(at)[i];
		else
			indexes[i] = index;

		if (indexes[i] >= ARR_DIMS(at)[i] || indexes[i] < 0)
		{
			PyErr_Format(PyExc_IndexError, "index %d out of range %d for axis %d",
				index, ARR_DIMS(at)[0], i);
			Py_DECREF(tup);
			return(NULL);
		}

		/*
		 * Adjust by the lowerbounds..
		 */
		indexes[i] = indexes[i] + ARR_LBOUND(at)[i];
	}

	Py_DECREF(tup);

	atypinfo = PyPgTypeInfo(Py_TYPE(self));
	element_type = PyPgType_GetElementType(Py_TYPE(self));
	typinfo = PyPgTypeInfo(element_type);

	PG_TRY();
	{
		Datum rd;
		bool isnull = false;

		rd = array_ref(at, nindexes, indexes, atypinfo->typlen,
			typinfo->typlen, typinfo->typbyval, typinfo->typalign, &isnull);

		if (isnull)
		{
			rob = Py_None;
			Py_INCREF(rob);
		}
		else
		{
			/*
			 * It points into the array structure, so there's no need to free.
			 */
			rob = PyPgObject_New(element_type, rd);
		}
	}
	PG_CATCH();
	{
		PyErr_SetPgError(false);
	}
	PG_END_TRY();

	return(rob);
}
Пример #6
0
static int
find_named_args(DispatcherObject *self, PyObject **pargs, PyObject **pkws)
{
    PyObject *oldargs = *pargs, *newargs;
    PyObject *kws = *pkws;
    Py_ssize_t pos_args = PyTuple_GET_SIZE(oldargs);
    Py_ssize_t named_args, total_args, i;
    Py_ssize_t func_args = PyTuple_GET_SIZE(self->argnames);
    Py_ssize_t defaults = PyTuple_GET_SIZE(self->defargs);
    /* Last parameter with a default value */
    Py_ssize_t last_def = (self->has_stararg)
                          ? func_args - 2
                          : func_args - 1;
    /* First parameter with a default value */
    Py_ssize_t first_def = last_def - defaults + 1;
    /* Minimum number of required arguments */
    Py_ssize_t minargs = first_def;

    if (kws != NULL)
        named_args = PyDict_Size(kws);
    else
        named_args = 0;
    total_args = pos_args + named_args;
    if (!self->has_stararg && total_args > func_args) {
        PyErr_Format(PyExc_TypeError,
                     "too many arguments: expected %d, got %d",
                     (int) func_args, (int) total_args);
        return -1;
    }
    else if (total_args < minargs) {
        if (minargs == func_args)
            PyErr_Format(PyExc_TypeError,
                         "not enough arguments: expected %d, got %d",
                         (int) minargs, (int) total_args);
        else
            PyErr_Format(PyExc_TypeError,
                         "not enough arguments: expected at least %d, got %d",
                         (int) minargs, (int) total_args);
        return -1;
    }
    newargs = PyTuple_New(func_args);
    if (!newargs)
        return -1;
    /* First pack the stararg */
    if (self->has_stararg) {
        Py_ssize_t stararg_size = Py_MAX(0, pos_args - func_args + 1);
        PyObject *stararg = PyTuple_New(stararg_size);
        if (!stararg) {
            Py_DECREF(newargs);
            return -1;
        }
        for (i = 0; i < stararg_size; i++) {
            PyObject *value = PyTuple_GET_ITEM(oldargs, func_args - 1 + i);
            Py_INCREF(value);
            PyTuple_SET_ITEM(stararg, i, value);
        }
        /* Put it in last position */
        PyTuple_SET_ITEM(newargs, func_args - 1, stararg);

    }
    for (i = 0; i < pos_args; i++) {
        PyObject *value = PyTuple_GET_ITEM(oldargs, i);
        if (self->has_stararg && i >= func_args - 1) {
            /* Skip stararg */
            break;
        }
        Py_INCREF(value);
        PyTuple_SET_ITEM(newargs, i, value);
    }

    /* Iterate over missing positional arguments, try to find them in
       named arguments or default values. */
    for (i = pos_args; i < func_args; i++) {
        PyObject *name = PyTuple_GET_ITEM(self->argnames, i);
        if (self->has_stararg && i >= func_args - 1) {
            /* Skip stararg */
            break;
        }
        if (kws != NULL) {
            /* Named argument? */
            PyObject *value = PyDict_GetItem(kws, name);
            if (value != NULL) {
                Py_INCREF(value);
                PyTuple_SET_ITEM(newargs, i, value);
                named_args--;
                continue;
            }
        }
        if (i >= first_def && i <= last_def) {
            /* Argument has a default value? */
            PyObject *value = PyTuple_GET_ITEM(self->defargs, i - first_def);
            Py_INCREF(value);
            PyTuple_SET_ITEM(newargs, i, value);
            continue;
        }
        else if (i < func_args - 1 || !self->has_stararg) {
            PyErr_Format(PyExc_TypeError,
                         "missing argument '%s'",
                         PyString_AsString(name));
            Py_DECREF(newargs);
            return -1;
        }
    }
    if (named_args) {
        PyErr_Format(PyExc_TypeError,
                     "some keyword arguments unexpected");
        Py_DECREF(newargs);
        return -1;
    }
    *pargs = newargs;
    *pkws = NULL;
    return 0;
}
Пример #7
0
static PyObject*
decode_struct(DecodeBuffer* input, PyObject* output, PyObject* klass, PyObject* spec_seq, long string_limit, long container_limit) {
    int spec_seq_len = PyTuple_Size(spec_seq);
    bool immutable = output == Py_None;
    PyObject* kwargs = NULL;
    if (spec_seq_len == -1) {
        return NULL;
    }

    if (immutable) {
        kwargs = PyDict_New();
        if (!kwargs) {
            PyErr_SetString(PyExc_TypeError, "failed to prepare kwargument storage");
            return NULL;
        }
    }

    while (true) {
        TType type;
        int16_t tag;
        PyObject* item_spec;
        PyObject* fieldval = NULL;
        StructItemSpec parsedspec;

        type = readByte(input);
        if (type == -1) {
            goto error;
        }
        if (type == T_STOP) {
            break;
        }
        tag = readI16(input);
        if (INT_CONV_ERROR_OCCURRED(tag)) {
            goto error;
        }
        if (tag >= 0 && tag < spec_seq_len) {
            item_spec = PyTuple_GET_ITEM(spec_seq, tag);
        } else {
            item_spec = Py_None;
        }

        if (item_spec == Py_None) {
            if (!skip(input, type)) {
                goto error;
            } else {
                continue;
            }
        }

        if (!parse_struct_item_spec(&parsedspec, item_spec)) {
            goto error;
        }
        if (parsedspec.type != type) {
            if (!skip(input, type)) {
                PyErr_Format(PyExc_TypeError, "struct field had wrong type: expected %d but got %d", parsedspec.type, type);
                goto error;
            } else {
                continue;
            }
        }

        fieldval = decode_val(input, parsedspec.type, parsedspec.typeargs, string_limit, container_limit);
        if (fieldval == NULL) {
            goto error;
        }

        if ((immutable && PyDict_SetItem(kwargs, parsedspec.attrname, fieldval) == -1)
                || (!immutable && PyObject_SetAttr(output, parsedspec.attrname, fieldval) == -1)) {
            Py_DECREF(fieldval);
            goto error;
        }
        Py_DECREF(fieldval);
    }
    if (immutable) {
        PyObject* args = PyTuple_New(0);
        PyObject* ret = NULL;
        if (!args) {
            PyErr_SetString(PyExc_TypeError, "failed to prepare argument storage");
            goto error;
        }
        ret = PyObject_Call(klass, args, kwargs);
        Py_DECREF(kwargs);
        Py_DECREF(args);
        return ret;
    }
    Py_INCREF(output);
    return output;

error:
    Py_XDECREF(kwargs);
    return NULL;
}
Пример #8
0
PyCodeObject *
PyCode_New(int argcount, int kwonlyargcount,
           int nlocals, int stacksize, int flags,
           PyObject *code, PyObject *consts, PyObject *names,
           PyObject *varnames, PyObject *freevars, PyObject *cellvars,
           PyObject *filename, PyObject *name, int firstlineno,
           PyObject *lnotab)
{
    PyCodeObject *co;
    Py_ssize_t *cell2arg = NULL;
    Py_ssize_t i, n_cellvars, n_varnames, total_args;

    /* Check argument types */
    if (argcount < 0 || kwonlyargcount < 0 || nlocals < 0 ||
        code == NULL || !PyBytes_Check(code) ||
        consts == NULL || !PyTuple_Check(consts) ||
        names == NULL || !PyTuple_Check(names) ||
        varnames == NULL || !PyTuple_Check(varnames) ||
        freevars == NULL || !PyTuple_Check(freevars) ||
        cellvars == NULL || !PyTuple_Check(cellvars) ||
        name == NULL || !PyUnicode_Check(name) ||
        filename == NULL || !PyUnicode_Check(filename) ||
        lnotab == NULL || !PyBytes_Check(lnotab)) {
        PyErr_BadInternalCall();
        return NULL;
    }

    /* Ensure that the filename is a ready Unicode string */
    if (PyUnicode_READY(filename) < 0)
        return NULL;

    intern_strings(names);
    intern_strings(varnames);
    intern_strings(freevars);
    intern_strings(cellvars);
    intern_string_constants(consts);

    /* Check for any inner or outer closure references */
    n_cellvars = PyTuple_GET_SIZE(cellvars);
    if (!n_cellvars && !PyTuple_GET_SIZE(freevars)) {
        flags |= CO_NOFREE;
    } else {
        flags &= ~CO_NOFREE;
    }

    n_varnames = PyTuple_GET_SIZE(varnames);
    if (argcount <= n_varnames && kwonlyargcount <= n_varnames) {
        /* Never overflows. */
        total_args = (Py_ssize_t)argcount + (Py_ssize_t)kwonlyargcount +
                ((flags & CO_VARARGS) != 0) + ((flags & CO_VARKEYWORDS) != 0);
    }
    else {
        total_args = n_varnames + 1;
    }
    if (total_args > n_varnames) {
        PyErr_SetString(PyExc_ValueError, "code: varnames is too small");
        return NULL;
    }

    /* Create mapping between cells and arguments if needed. */
    if (n_cellvars) {
        bool used_cell2arg = false;
        cell2arg = PyMem_NEW(Py_ssize_t, n_cellvars);
        if (cell2arg == NULL) {
            PyErr_NoMemory();
            return NULL;
        }
        /* Find cells which are also arguments. */
        for (i = 0; i < n_cellvars; i++) {
            Py_ssize_t j;
            PyObject *cell = PyTuple_GET_ITEM(cellvars, i);
            cell2arg[i] = CO_CELL_NOT_AN_ARG;
            for (j = 0; j < total_args; j++) {
                PyObject *arg = PyTuple_GET_ITEM(varnames, j);
                int cmp = PyUnicode_Compare(cell, arg);
                if (cmp == -1 && PyErr_Occurred()) {
                    PyMem_FREE(cell2arg);
                    return NULL;
                }
                if (cmp == 0) {
                    cell2arg[i] = j;
                    used_cell2arg = true;
                    break;
                }
            }
        }
        if (!used_cell2arg) {
            PyMem_FREE(cell2arg);
            cell2arg = NULL;
        }
    }
    co = PyObject_NEW(PyCodeObject, &PyCode_Type);
    if (co == NULL) {
        if (cell2arg)
            PyMem_FREE(cell2arg);
        return NULL;
    }
    co->co_argcount = argcount;
    co->co_kwonlyargcount = kwonlyargcount;
    co->co_nlocals = nlocals;
    co->co_stacksize = stacksize;
    co->co_flags = flags;
    Py_INCREF(code);
    co->co_code = code;
    Py_INCREF(consts);
    co->co_consts = consts;
    Py_INCREF(names);
    co->co_names = names;
    Py_INCREF(varnames);
    co->co_varnames = varnames;
    Py_INCREF(freevars);
    co->co_freevars = freevars;
    Py_INCREF(cellvars);
    co->co_cellvars = cellvars;
    co->co_cell2arg = cell2arg;
    Py_INCREF(filename);
    co->co_filename = filename;
    Py_INCREF(name);
    co->co_name = name;
    co->co_firstlineno = firstlineno;
    Py_INCREF(lnotab);
    co->co_lnotab = lnotab;
    co->co_zombieframe = NULL;
    co->co_weakreflist = NULL;
    co->co_extra = NULL;
    return co;
}
Пример #9
0
static PyObject *
GMPy_MPZ_unpack(PyObject *self, PyObject *args)
{
    mp_bitcnt_t nbits, total_bits, guard_bit, extra_bits, temp_bits;
    Py_ssize_t index = 0, lst_count, i, lst_ptr = 0;
    PyObject *result;
    mpz_t temp;
    mp_limb_t extra = 0;
    MPZ_Object *item, *tempx = NULL;
    CTXT_Object *context = NULL;

    if (PyTuple_GET_SIZE(args) != 2) {
        TYPE_ERROR("unpack() requires 'int','int' arguments");
        return NULL;
    }

    nbits = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1));
    if (nbits == (mp_bitcnt_t)(-1) && PyErr_Occurred()) {
        return NULL;
    }

    if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), context))) {
        TYPE_ERROR("unpack() requires 'int','int' arguments");
        return NULL;
    }

    if (mpz_sgn(tempx->z) < 0) {
        VALUE_ERROR("unpack() requires x >= 0");
        return NULL;
    }

    if (mpz_sgn(tempx->z) == 0) {
        total_bits = 0;
    }
    else {
        total_bits = mpz_sizeinbase(tempx->z, 2);
    }

    lst_count = total_bits / nbits;
    if ((total_bits % nbits) || !lst_count) {
        lst_count += 1;
    }

    if (!(result = PyList_New(lst_count))) {
        Py_DECREF((PyObject*)tempx);
        return NULL;
    }

    if (mpz_sgn(tempx->z) == 0) {
        if (!(item = GMPy_MPZ_New(context))) {
            Py_DECREF((PyObject*)tempx);
            Py_DECREF(result);
            return NULL;
        }
        mpz_set_ui(item->z, 0);
        PyList_SET_ITEM(result, 0, (PyObject*)item);
        Py_DECREF((PyObject*)tempx);
        return result;
    }

    mpz_init(temp);
    guard_bit = nbits + (2 * mp_bits_per_limb);
    extra_bits = 0;
    index = 0;

    while (lst_ptr < lst_count) {
        i = 0;
        temp_bits = 0;
        mpz_set_ui(temp, 0);
        mpz_setbit(temp, guard_bit);
        while (temp_bits + extra_bits < nbits) {
            temp->_mp_d[i++] = mpz_getlimbn(tempx->z, index++);
            temp_bits += mp_bits_per_limb;
        }
        mpz_clrbit(temp, guard_bit);
        mpz_mul_2exp(temp, temp, extra_bits);
        if (mpz_sgn(temp) == 0 && extra != 0) {
            mpz_set_ui(temp, 1);
            temp->_mp_d[0] = extra;
        }
        else {
           mpn_add_1(temp->_mp_d, temp->_mp_d, mpz_size(temp), extra);
        }
        temp_bits += extra_bits;

        while ((lst_ptr < lst_count) && (temp_bits >= nbits)) {
            if(!(item = GMPy_MPZ_New(context))) {
                mpz_clear(temp);
                Py_DECREF((PyObject*)tempx);
                Py_DECREF(result);
                return NULL;
            }
            mpz_tdiv_r_2exp(item->z, temp, nbits);
            PyList_SET_ITEM(result, lst_ptr++, (PyObject*)item);
            mpz_tdiv_q_2exp(temp, temp, nbits);
            temp_bits -= nbits;
        }
        extra = mpz_getlimbn(temp, 0);
        extra_bits = temp_bits;
    }
    Py_DECREF((PyObject*)tempx);
    mpz_clear(temp);
    return result;
}
Пример #10
0
/* This function is called by the tp_dealloc handler to clear weak references.
 *
 * This iterates through the weak references for 'object' and calls callbacks
 * for those references which have one.  It returns when all callbacks have
 * been attempted.
 */
void
PyObject_ClearWeakRefs(PyObject *object)
{
    PyWeakReference **list;

    if (object == NULL
        || !PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))
        || object->ob_refcnt != 0) {
        PyErr_BadInternalCall();
        return;
    }
    list = GET_WEAKREFS_LISTPTR(object);
    /* Remove the callback-less basic and proxy references */
    if (*list != NULL && (*list)->wr_callback == NULL) {
        clear_weakref(*list);
        if (*list != NULL && (*list)->wr_callback == NULL)
            clear_weakref(*list);
    }
    if (*list != NULL) {
        PyWeakReference *current = *list;
        Py_ssize_t count = _PyWeakref_GetWeakrefCount(current);
        int restore_error = PyErr_Occurred() ? 1 : 0;
        PyObject *err_type, *err_value, *err_tb;

        if (restore_error)
            PyErr_Fetch(&err_type, &err_value, &err_tb);
        if (count == 1) {
            PyObject *callback = current->wr_callback;

            current->wr_callback = NULL;
            clear_weakref(current);
            if (callback != NULL) {
                if (((PyObject *)current)->ob_refcnt > 0)
                    handle_callback(current, callback);
                Py_DECREF(callback);
            }
        }
        else {
            PyObject *tuple;
            Py_ssize_t i = 0;

            tuple = PyTuple_New(count * 2);
            if (tuple == NULL) {
                if (restore_error)
                    PyErr_Fetch(&err_type, &err_value, &err_tb);
                return;
            }

            for (i = 0; i < count; ++i) {
                PyWeakReference *next = current->wr_next;

                if (((PyObject *)current)->ob_refcnt > 0)
                {
                    Py_INCREF(current);
                    PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current);
                    PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback);
                }
                else {
                    Py_DECREF(current->wr_callback);
                }
                current->wr_callback = NULL;
                clear_weakref(current);
                current = next;
            }
            for (i = 0; i < count; ++i) {
                PyObject *callback = PyTuple_GET_ITEM(tuple, i * 2 + 1);

                /* The tuple may have slots left to NULL */
                if (callback != NULL) {
                    PyObject *item = PyTuple_GET_ITEM(tuple, i * 2);
                    handle_callback((PyWeakReference *)item, callback);
                }
            }
            Py_DECREF(tuple);
        }
        if (restore_error)
            PyErr_Restore(err_type, err_value, err_tb);
    }
}
Пример #11
0
PyObject*
_PyCode_ConstantKey(PyObject *op)
{
    PyObject *key;

    /* Py_None and Py_Ellipsis are singletons. */
    if (op == Py_None || op == Py_Ellipsis
       || PyLong_CheckExact(op)
       || PyUnicode_CheckExact(op)
          /* code_richcompare() uses _PyCode_ConstantKey() internally */
       || PyCode_Check(op))
    {
        /* Objects of these types are always different from object of other
         * type and from tuples. */
        Py_INCREF(op);
        key = op;
    }
    else if (PyBool_Check(op) || PyBytes_CheckExact(op)) {
        /* Make booleans different from integers 0 and 1.
         * Avoid BytesWarning from comparing bytes with strings. */
        key = PyTuple_Pack(2, Py_TYPE(op), op);
    }
    else if (PyFloat_CheckExact(op)) {
        double d = PyFloat_AS_DOUBLE(op);
        /* all we need is to make the tuple different in either the 0.0
         * or -0.0 case from all others, just to avoid the "coercion".
         */
        if (d == 0.0 && copysign(1.0, d) < 0.0)
            key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None);
        else
            key = PyTuple_Pack(2, Py_TYPE(op), op);
    }
    else if (PyComplex_CheckExact(op)) {
        Py_complex z;
        int real_negzero, imag_negzero;
        /* For the complex case we must make complex(x, 0.)
           different from complex(x, -0.) and complex(0., y)
           different from complex(-0., y), for any x and y.
           All four complex zeros must be distinguished.*/
        z = PyComplex_AsCComplex(op);
        real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0;
        imag_negzero = z.imag == 0.0 && copysign(1.0, z.imag) < 0.0;
        /* use True, False and None singleton as tags for the real and imag
         * sign, to make tuples different */
        if (real_negzero && imag_negzero) {
            key = PyTuple_Pack(3, Py_TYPE(op), op, Py_True);
        }
        else if (imag_negzero) {
            key = PyTuple_Pack(3, Py_TYPE(op), op, Py_False);
        }
        else if (real_negzero) {
            key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None);
        }
        else {
            key = PyTuple_Pack(2, Py_TYPE(op), op);
        }
    }
    else if (PyTuple_CheckExact(op)) {
        Py_ssize_t i, len;
        PyObject *tuple;

        len = PyTuple_GET_SIZE(op);
        tuple = PyTuple_New(len);
        if (tuple == NULL)
            return NULL;

        for (i=0; i < len; i++) {
            PyObject *item, *item_key;

            item = PyTuple_GET_ITEM(op, i);
            item_key = _PyCode_ConstantKey(item);
            if (item_key == NULL) {
                Py_DECREF(tuple);
                return NULL;
            }

            PyTuple_SET_ITEM(tuple, i, item_key);
        }

        key = PyTuple_Pack(2, tuple, op);
        Py_DECREF(tuple);
    }
    else if (PyFrozenSet_CheckExact(op)) {
        Py_ssize_t pos = 0;
        PyObject *item;
        Py_hash_t hash;
        Py_ssize_t i, len;
        PyObject *tuple, *set;

        len = PySet_GET_SIZE(op);
        tuple = PyTuple_New(len);
        if (tuple == NULL)
            return NULL;

        i = 0;
        while (_PySet_NextEntry(op, &pos, &item, &hash)) {
            PyObject *item_key;

            item_key = _PyCode_ConstantKey(item);
            if (item_key == NULL) {
                Py_DECREF(tuple);
                return NULL;
            }

            assert(i < len);
            PyTuple_SET_ITEM(tuple, i, item_key);
            i++;
        }
        set = PyFrozenSet_New(tuple);
        Py_DECREF(tuple);
        if (set == NULL)
            return NULL;

        key = PyTuple_Pack(2, set, op);
        Py_DECREF(set);
        return key;
    }
    else {
        /* for other types, use the object identifier as a unique identifier
         * to ensure that they are seen as unequal. */
        PyObject *obj_id = PyLong_FromVoidPtr(op);
        if (obj_id == NULL)
            return NULL;

        key = PyTuple_Pack(2, obj_id, op);
        Py_DECREF(obj_id);
    }
    return key;
}
Пример #12
0
static PyObject *next(PyObject *self)
{
	ligolw_RowDumper *rowdumper = (ligolw_RowDumper *) self;
	const Py_ssize_t n = PyTuple_GET_SIZE(rowdumper->attributes);
	PyObject *tokens;
	PyObject *row;
	PyObject *result;
	Py_ssize_t i;

	/*
	 * retrieve the next row object
	 */

	if(!PyIter_Check(rowdumper->iter)) {
		PyErr_SetObject(PyExc_TypeError, rowdumper->iter);
		return NULL;
	}
	row = PyIter_Next(rowdumper->iter);
	if(!row) {
		if(!PyErr_Occurred()) {
			Py_DECREF(rowdumper->iter);
			rowdumper->iter = Py_None;
			Py_INCREF(rowdumper->iter);
			PyErr_SetNone(PyExc_StopIteration);
		}
		return NULL;
	}

	/*
	 * wipe out the tuple of tokens from the previous row, and start a
	 * new tuple
	 */

	Py_DECREF(rowdumper->tokens);
	rowdumper->tokens = Py_None;
	Py_INCREF(rowdumper->tokens);

	tokens = PyTuple_New(n);
	if(!tokens) {
		Py_DECREF(row);
		return NULL;
	}

	/*
	 * retrieve attributes from the row object one-by-one, convert to
	 * strings, and insert into new token tuple
	 */

	for(i = 0; i < n; i++) {
		PyObject *val = PyObject_GetAttr(row, PyTuple_GET_ITEM(rowdumper->attributes, i));
		PyObject *token;

		if(!val) {
			Py_DECREF(tokens);
			Py_DECREF(row);
			return NULL;
		}

		if(val == Py_None)
			token = PyUnicode_FromUnicode(NULL, 0); /* u"" */
		else
			token = PyObject_CallFunctionObjArgs(PyTuple_GET_ITEM(rowdumper->formats, i), val, NULL);
		Py_DECREF(val);

		if(!token) {
			Py_DECREF(tokens);
			Py_DECREF(row);
			return NULL;
		}

		PyTuple_SET_ITEM(tokens, i, token);
	}
	Py_DECREF(row);

	/*
	 * that worked, so expose the new token tuple
	 */

	Py_DECREF(rowdumper->tokens);
	rowdumper->tokens = tokens;

	/*
	 * return tokens concatenated into a single string using the
	 * delimiter
	 */

	result = PyUnicode_Join(rowdumper->delimiter, rowdumper->tokens);

	rowdumper->rows_converted += result != NULL;

	return result;
}
Пример #13
0
static nxweb_result python_on_request(nxweb_http_server_connection* conn, nxweb_http_request* req, nxweb_http_response* resp) {
  nxb_buffer* nxb=req->nxb;
  nxweb_handler* handler=conn->handler;
  const char* request_uri=req->uri;
  char* query_string=strchr(request_uri, '?');
  int ulen=query_string? (query_string-request_uri) : strlen(request_uri);
  if (query_string) query_string++;
  int pfxlen=req->path_info? (req->path_info - req->uri) : 0;
  int plen=ulen-pfxlen;
  const char* path_info=request_uri+pfxlen;
  if (handler->uri && *handler->uri) {
    pfxlen=strlen(handler->uri);
    ulen=pfxlen+plen;
    char* u=nxb_alloc_obj(nxb, ulen+1);
    memcpy(u, handler->uri, pfxlen);
    memcpy(u+pfxlen, path_info, plen);
    u[ulen]='\0';
    request_uri=u;
    path_info=request_uri+pfxlen;
  }
  const char* host_port=req->host? strchr(req->host, ':') : 0;

  int content_fd=0;

  if (req->content_length) {
    nxd_fwbuffer* fwb=nxweb_get_request_data(req, PYTHON_HANDLER_KEY).ptr;

    if (fwb) {
      if (fwb->error || fwb->size > fwb->max_size) {
        nxweb_send_http_error(resp, 413, "Request Entity Too Large"); // most likely cause
        return NXWEB_ERROR;
      }
      else if (req->content_received!=fwb->size) {
        nxweb_log_error("content_received does not match upload stored size for %s", req->uri);
        nxweb_send_http_error(resp, 500, "Internal Server Error");
        return NXWEB_ERROR;
      }
      else {
        content_fd=fwb->fd;
        if (lseek(content_fd, 0, SEEK_SET)==-1) {
          nxweb_log_error("can't lseek() temp upload file for %s", req->uri);
          nxweb_send_http_error(resp, 500, "Internal Server Error");
          return NXWEB_ERROR;
        }
      }
    }
  }


  nxweb_log_debug("invoke python");

  PyGILState_STATE gstate=PyGILState_Ensure();

  PyObject* py_func_args=PyTuple_New(1);
  PyObject* py_environ=PyDict_New();
  assert(PyDict_Check(py_environ));

  dict_set(py_environ, "SERVER_NAME", PyString_FromStringAndSize(req->host, host_port? (host_port-req->host) : strlen(req->host)));
  dict_set(py_environ, "SERVER_PORT", PyString_FromString(host_port? host_port+1 : ""));
  dict_set(py_environ, "SERVER_PROTOCOL", PyString_FromString(req->http11? "HTTP/1.1" : "HTTP/1.0"));
  dict_set(py_environ, "SERVER_SOFTWARE", PyString_FromString(PACKAGE_STRING));
  dict_set(py_environ, "GATEWAY_INTERFACE", PyString_FromString("CGI/1.1"));
  dict_set(py_environ, "REQUEST_METHOD", PyString_FromString(req->method));
  dict_set(py_environ, "REQUEST_URI", PyString_FromStringAndSize(request_uri, ulen));
  dict_set(py_environ, "SCRIPT_NAME", PyString_FromStringAndSize(request_uri, pfxlen));
  dict_set(py_environ, "PATH_INFO", PyString_FromStringAndSize(path_info, plen));
  dict_set(py_environ, "QUERY_STRING", PyString_FromString(query_string? query_string : ""));
  dict_set(py_environ, "REMOTE_ADDR", PyString_FromString(conn->remote_addr));
  dict_set(py_environ, "CONTENT_TYPE", PyString_FromString(req->content_type? req->content_type : ""));
  dict_set(py_environ, "CONTENT_LENGTH", PyInt_FromLong(req->content_received));
  if (req->cookie) dict_set(py_environ, "HTTP_COOKIE", PyString_FromString(req->cookie));
  if (req->host) dict_set(py_environ, "HTTP_HOST", PyString_FromString(req->host));
  if (req->user_agent) dict_set(py_environ, "HTTP_USER_AGENT", PyString_FromString(req->user_agent));
  if (req->if_modified_since) {
    struct tm tm;
    gmtime_r(&req->if_modified_since, &tm);
    char ims[32];
    nxweb_format_http_time(ims, &tm);
    dict_set(py_environ, "HTTP_IF_MODIFIED_SINCE", PyString_FromString(ims));
  }

  if (req->headers) {
    // write added headers
    // encode http headers into CGI variables; see 4.1.18 in https://tools.ietf.org/html/rfc3875
    char hname[256];
    memcpy(hname, "HTTP_", 5);
    char* h=hname+5;
    nx_simple_map_entry* itr;
    for (itr=nx_simple_map_itr_begin(req->headers); itr; itr=nx_simple_map_itr_next(itr)) {
      nx_strtoupper(h, itr->name);
      char* p;
      for (p=h; *p; p++) {
        if (*p=='-') *p='_';
      }
      dict_set(py_environ, hname, PyString_FromString(itr->value));
    }
  }

  dict_set(py_environ, "wsgi.url_scheme", PyString_FromString(conn->secure? "https" : "http"));

  if (req->content_length) {
    if (content_fd) {
      dict_set(py_environ, "nxweb.req.content_fd", PyInt_FromLong(content_fd));
    }
    else {
      dict_set(py_environ, "nxweb.req.content", PyByteArray_FromStringAndSize(req->content? req->content : "", req->content_received));
    }
  }
  if (req->if_modified_since) dict_set(py_environ, "nxweb.req.if_modified_since", PyLong_FromLong(req->if_modified_since));
  dict_set(py_environ, "nxweb.req.uid", PyLong_FromLongLong(req->uid));
  if (req->parent_req) {
    nxweb_http_request* preq=req->parent_req;
    while (preq->parent_req) preq=preq->parent_req; // find root request
    if (preq->uid) {
      dict_set(py_environ, "nxweb.req.root_uid", PyLong_FromLongLong(preq->uid));
    }
  }

  // call python
  PyTuple_SetItem(py_func_args, 0, py_environ);
  PyObject* py_result=PyObject_CallObject(py_nxweb_on_request_func, py_func_args);
  Py_DECREF(py_func_args);
  if (py_result && PyTuple_Check(py_result) && PyTuple_Size(py_result)==3) {
    PyObject* py_status=PyTuple_GET_ITEM(py_result, 0);
    PyObject* py_headers=PyTuple_GET_ITEM(py_result, 1);
    PyObject* py_body=PyTuple_GET_ITEM(py_result, 2);

    if (py_status && PyString_Check(py_status)) {
      const char* status_string=PyString_AS_STRING(py_status);
      int status_code=0;
      const char* p=status_string;
      while (*p && *p>='0' && *p<='9') {
        status_code=status_code*10+(*p-'0');
        p++;
      }
      while (*p && *p==' ') p++;
      if (status_code>=200 && status_code<600 && *p) {
        resp->status_code=status_code;
        resp->status=nxb_copy_str(nxb, p);
      }
    }

    if (py_headers && PyList_Check(py_headers)) {
      const int size=PyList_Size(py_headers);
      int i;
      for (i=0; i<size; i++) {
        PyObject* py_header_tuple=PyList_GET_ITEM(py_headers, i);
        if (py_header_tuple && PyTuple_Check(py_header_tuple) && PyTuple_Size(py_header_tuple)==2) {
          PyObject* py_name=PyTuple_GET_ITEM(py_header_tuple, 0);
          PyObject* py_value=PyTuple_GET_ITEM(py_header_tuple, 1);
          if (py_name && PyString_Check(py_name) && py_value && PyString_Check(py_value)) {
            nxweb_add_response_header_safe(resp, PyString_AS_STRING(py_name), PyString_AS_STRING(py_value));
          }
        }
      }
    }

    if ((!resp->status_code || resp->status_code==200) && !resp->content_type) resp->content_type="text/html";

    char* rcontent=0;
    nxe_ssize_t rsize=0;
    if (PyByteArray_Check(py_body)) {
      rcontent=PyByteArray_AS_STRING(py_body);
      rsize=PyByteArray_Size(py_body);
    }
    else if (PyString_Check(py_body)) {
      rcontent=PyString_AS_STRING(py_body);
      rsize=PyString_Size(py_body);
    }
    if (rcontent && rsize>0) nxweb_response_append_data(resp, rcontent, rsize);
  }
  else if (py_result && PyString_Check(py_result)) {
    resp->status_code=500;
    resp->status="Internal Server Error";
    resp->content_type="text/html";
    nxweb_log_error("python call failed: %s", PyString_AS_STRING(py_result));
    nxweb_response_printf(resp, "python call failed: %H", PyString_AS_STRING(py_result));
  }
  else {
    PyErr_Print();
    nxweb_log_error("python call failed");
    nxweb_response_printf(resp, "python call failed");
  }
  Py_XDECREF(py_result);

  // Release the thread. No Python API allowed beyond this point.
  PyGILState_Release(gstate);

  nxweb_log_debug("invoke python complete");

  return NXWEB_OK;
}
static PyObject *
_lookup(lookup *self,
        PyObject *required, PyObject *provided, PyObject *name,
        PyObject *default_)
{
  PyObject *result, *key, *cache;

#ifdef PY3K
  if ( name && !PyUnicode_Check(name) )
#else
  if ( name && !PyString_Check(name) && !PyUnicode_Check(name) )
#endif
  {
    PyErr_SetString(PyExc_ValueError,
                    "name is not a string or unicode");
    return NULL;
  }
  cache = _getcache(self, provided, name);
  if (cache == NULL)
    return NULL;

  required = tuplefy(required);
  if (required == NULL)
    return NULL;

  if (PyTuple_GET_SIZE(required) == 1)
    key = PyTuple_GET_ITEM(required, 0);
  else
    key = required;

  result = PyDict_GetItem(cache, key);
  if (result == NULL)
    {
      int status;

      result = PyObject_CallMethodObjArgs(OBJECT(self), str_uncached_lookup,
                                          required, provided, name, NULL);
      if (result == NULL)
        {
          Py_DECREF(required);
          return NULL;
        }
      status = PyDict_SetItem(cache, key, result);
      Py_DECREF(required);
      if (status < 0)
        {
          Py_DECREF(result);
          return NULL;
        }
    }
  else
    {
      Py_INCREF(result);
      Py_DECREF(required);
    }

  if (result == Py_None && default_ != NULL)
    {
      Py_DECREF(Py_None);
      Py_INCREF(default_);
      return default_;
    }

  return result;
}
Пример #15
0
static PyObject *get(PyObject *self, PyObject *args) {
  int i, molid, frame;
  PyObject *selected;
  int num_selected;
  char *attr = 0;

  //
  // get molid, list, and attribute
  //
  if (!PyArg_ParseTuple(args, (char *)"iiO!s", 
                        &molid, &frame, &PyTuple_Type, &selected, &attr))
    return NULL;  // bad args

  //
  // check molecule
  //
  VMDApp *app = get_vmdapp();
  Molecule *mol = app->moleculeList->mol_from_id(molid);
  if (!mol) {
    PyErr_SetString(PyExc_ValueError, "molecule no longer exists");
    return NULL;
  }
  const int num_atoms = mol->nAtoms;
 
  // 
  // Check for a valid attribute
  //
  SymbolTable *table = app->atomSelParser;
  int attrib_index = table->find_attribute(attr);
  if (attrib_index == -1) {
    PyErr_SetString(PyExc_ValueError, "unknown atom attribute");
    return NULL;
  }
  SymbolTableElement *elem = table->fctns.data(attrib_index);
  if (elem->is_a != SymbolTableElement::KEYWORD &&
      elem->is_a != SymbolTableElement::SINGLEWORD) {
    PyErr_SetString(PyExc_ValueError, "attribute is not a keyword or singleword");
    return NULL;
  }
 
  // 
  // fetch the data
  //

  atomsel_ctxt context(table, mol, frame, attr);
  num_selected = PyTuple_Size(selected);
  PyObject *newlist = PyList_New(num_selected); 

  // XXX should check that selected contains valid indices
  int *flgs = new int[num_atoms];
  memset(flgs,0,num_atoms*sizeof(int));
  for (i=0; i<num_selected; i++) 
    flgs[PyInt_AsLong(PyTuple_GET_ITEM(selected,i))] = 1;

  if (elem->is_a == SymbolTableElement::SINGLEWORD) {
    int *tmp = new int[num_atoms];
    memcpy(tmp, flgs, num_atoms*sizeof(int));
    elem->keyword_single(&context, num_atoms, tmp);
    int j=0;
    for (i=0; i<num_atoms; i++) {
      if (flgs[i]) {
        if (tmp[i]) {
          PyList_SET_ITEM(newlist, j++, PyInt_FromLong(1));       
        } else {
          PyList_SET_ITEM(newlist, j++, PyInt_FromLong(0));       
        }
      }
    }
    delete [] tmp;
  } else {
    switch(table->fctns.data(attrib_index)->returns_a) {
      case (SymbolTableElement::IS_STRING):
      {
        const char **tmp= new const char *[num_atoms];
        elem->keyword_string(&context, num_atoms, tmp, flgs);
        int j=0;
        for (int i=0; i<num_atoms; i++) {
          if (flgs[i]) {
            PyList_SET_ITEM(newlist, j++, PyString_FromString(tmp[i]));
          }
        }
        delete [] tmp;
      }
      break;
      case (SymbolTableElement::IS_INT):
      {
        int *tmp = new int[num_atoms];
        elem->keyword_int(&context, num_atoms, tmp, flgs);
        int j=0;
        for (int i=0; i<num_atoms; i++) {
          if (flgs[i]) {
            PyList_SET_ITEM(newlist, j++, PyInt_FromLong(tmp[i]));
          }
        }
        delete [] tmp;
      }
      break;
      case (SymbolTableElement::IS_FLOAT):
      {
        double *tmp = new double[num_atoms];
        elem->keyword_double(&context, num_atoms, tmp, flgs);
        int j=0;
        for (int i=0; i<num_atoms; i++) {
          if (flgs[i])  
            PyList_SET_ITEM(newlist, j++, PyFloat_FromDouble(tmp[i]));
        }
        delete [] tmp;
      }
      break;
    } // end switch
  }   // end else
  delete [] flgs;
  return newlist;
}
Пример #16
0
static PyObject *
GMPy_MPZ_pack(PyObject *self, PyObject *args)
{
    mp_bitcnt_t nbits, total_bits, tempx_bits;
    Py_ssize_t index, lst_count, i, temp_bits, limb_count;
    PyObject *lst;
    mpz_t temp;
    MPZ_Object *result, *tempx = 0;
    CTXT_Object *context = NULL;

    if (PyTuple_GET_SIZE(args) != 2) {
        TYPE_ERROR("pack() requires 'list','int' arguments");
        return NULL;
    }

    nbits = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1));
    if (nbits == (mp_bitcnt_t)(-1) && PyErr_Occurred()) {
        return NULL;
    }

    if (!PyList_Check(PyTuple_GET_ITEM(args, 0))) {
        TYPE_ERROR("pack() requires 'list','int' arguments");
        return NULL;
    }

    if (!(result = GMPy_MPZ_New(context)))
        return NULL;

    lst = PyTuple_GET_ITEM(args, 0);
    lst_count = PyList_GET_SIZE(lst);
    total_bits = nbits * lst_count;

    if ((total_bits / lst_count) != nbits) {
        VALUE_ERROR("result too large to store in an 'mpz'");
        return NULL;
    }

    mpz_set_ui(result->z, 0);
    mpz_setbit(result->z, total_bits + (mp_bits_per_limb * 2));

    mpz_init(temp);
    mpz_set_ui(temp, 0);
    limb_count = 0;
    tempx_bits = 0;

    for (index = 0; index < lst_count; index++) {
        if (!(tempx = GMPy_MPZ_From_Integer(PyList_GetItem(lst, index), context))
            || (mpz_sgn(tempx->z) < 0)
            || (mpz_sizeinbase(tempx->z,2) > (size_t)nbits)) {
            TYPE_ERROR("pack() requires list elements be positive integers < 2^n bits");
            mpz_clear(temp);
            Py_XDECREF((PyObject*)tempx);
            Py_DECREF((PyObject*)result);
            return NULL;
        }
        mpz_mul_2exp(tempx->z, tempx->z, tempx_bits);
        mpz_add(temp, temp, tempx->z);
        tempx_bits += nbits;
        i = 0;
        temp_bits = mpz_sizeinbase(temp, 2) * mpz_sgn(temp);
        while (tempx_bits >= (mp_bitcnt_t)mp_bits_per_limb) {
            if (temp_bits > 0) {
                result->z->_mp_d[limb_count] = mpz_getlimbn(temp, i);
            }
            i += 1;
            tempx_bits -= mp_bits_per_limb;
            limb_count += 1;
            temp_bits -= mp_bits_per_limb;
        }
        if (temp_bits > 0) {
            mpz_tdiv_q_2exp(temp, temp, mp_bits_per_limb * i);
        }
        else {
            mpz_set_ui(temp, 0);
        }
        Py_DECREF((PyObject*)tempx);
    }
    result->z->_mp_d[limb_count] = mpz_getlimbn(temp, 0);
    mpz_clrbit(result->z, total_bits + (mp_bits_per_limb * 2));
    mpz_clear(temp);
    return (PyObject*)result;
}
  if (acdk2python(retv, ret) == true)
    return ret;
  return 0;
}



PyObject* 
AcdkPythonProxy::peek_static(PyObject* self, PyObject* args)
{
  CHECK_ARGS(args, 2, !=, "acdk.peek_static expects 2 string arg");
  
  const char* classname;
  const char* membername;
  EXTRACT_STRING( classname
                , PyTuple_GET_ITEM(args, 0)
                , "acdk.peek_static expect name of class as argument 1");
  EXTRACT_STRING( membername
                , PyTuple_GET_ITEM(args, 1)
                , "acdk.peek_static expect name field as argument 2");
  /*
  RClass cls;
  try {
    cls = Class::forName(classname);
  } catch (RClassNotFoundException ex) {
    PyErr_SetString(PyExc_RuntimeError, "acdk.peek_static: classname cannot be found");
    return 0;
  }*/
  try {
    ScriptVar retv = ::acdk::lang::dmi::StdDispatch::peek_static(classname, membername);
    //ScriptVar retv = cls->getStaticMember(membername);
Пример #18
0
static PyObject* mod_connect(PyObject* self, PyObject* args, PyObject* kwargs)
{
    UNUSED(self);
    
    Object pConnectString = 0;
    int fAutoCommit = 0;
    int fAnsi = 0;              // force ansi
    int fUnicodeResults = 0;
    long timeout = 0;

    Py_ssize_t size = args ? PyTuple_Size(args) : 0;

    if (size > 1)
    {
        PyErr_SetString(PyExc_TypeError, "function takes at most 1 non-keyword argument");
        return 0;
    }

    if (size == 1)
    {
        if (!PyString_Check(PyTuple_GET_ITEM(args, 0)) && !PyUnicode_Check(PyTuple_GET_ITEM(args, 0)))
            return PyErr_Format(PyExc_TypeError, "argument 1 must be a string or unicode object");

        pConnectString.Attach(PyUnicode_FromObject(PyTuple_GetItem(args, 0)));
        if (!pConnectString.IsValid())
            return 0;
    }

    if (kwargs && PyDict_Size(kwargs) > 0)
    {
        Object partsdict(PyDict_New());
        if (!partsdict.IsValid())
            return 0;

        Object unicodeT;            // used to temporarily hold Unicode objects if we have to convert values to unicode

        Py_ssize_t pos = 0;
        PyObject* key = 0;
        PyObject* value = 0;

        while (PyDict_Next(kwargs, &pos, &key, &value))
        {
            // Note: key and value are *borrowed*.

            // Check for the two non-connection string keywords we accept.  (If we get many more of these, create something
            // table driven.  Are we sure there isn't a Python function to parse keywords but leave those it doesn't know?)
            const char* szKey = PyString_AsString(key);

            if (_strcmpi(szKey, "autocommit") == 0)
            {
                fAutoCommit = PyObject_IsTrue(value);
                continue;
            }
            if (_strcmpi(szKey, "ansi") == 0)
            {
                fAnsi = PyObject_IsTrue(value);
                continue;
            }
            if (_strcmpi(szKey, "unicode_results") == 0)
            {
                fUnicodeResults = PyObject_IsTrue(value);
                continue;
            }
            if (_strcmpi(szKey, "timeout") == 0)
            {
                timeout = PyInt_AsLong(value);
                if (PyErr_Occurred())
                    return 0;
                continue;
            }
        
            // Anything else must be a string that is appended, along with the keyword to the connection string.

            if (!(PyString_Check(value) || PyUnicode_Check(value)))
                return PyErr_Format(PyExc_TypeError, "'%s' is not a string or unicode value'", szKey);

            // Map DB API recommended names to ODBC names (e.g. user --> uid).
            for (size_t i = 0; i < _countof(keywordmaps); i++)
            {
                if (_strcmpi(szKey, keywordmaps[i].oldname) == 0)
                {
                    if (keywordmaps[i].newnameObject == 0)
                    {
                        keywordmaps[i].newnameObject = PyString_FromString(keywordmaps[i].newname);
                        if (keywordmaps[i].newnameObject == 0)
                            return 0;
                    }

                    key = keywordmaps[i].newnameObject;
                    break;
                }
            }

            if (PyString_Check(value))
            {
                unicodeT.Attach(PyUnicode_FromObject(value));
                if (!unicodeT.IsValid())
                    return 0;
                value = unicodeT.Get();
            }

            if (PyDict_SetItem(partsdict.Get(), key, value) == -1)
                return 0;

            unicodeT.Detach();
        }

        if (PyDict_Size(partsdict.Get()))
            pConnectString.Attach(MakeConnectionString(pConnectString.Get(), partsdict));
    }
    
    if (!pConnectString.IsValid())
        return PyErr_Format(PyExc_TypeError, "no connection information was passed");

    if (henv == SQL_NULL_HANDLE)
    {
        if (!AllocateEnv())
            return 0;
    }
     
    return (PyObject*)Connection_New(pConnectString.Get(), fAutoCommit != 0, fAnsi != 0, fUnicodeResults != 0, timeout);
}
Пример #19
0
static bool
output_val(PyObject* output, PyObject* value, TType type, PyObject* typeargs) {
    /*
     * Refcounting Strategy:
     *
     * We assume that elements of the thrift_spec tuple are not going to be
     * mutated, so we don't ref count those at all. Other than that, we try to
     * keep a reference to all the user-created objects while we work with them.
     * output_val assumes that a reference is already held. The *caller* is
     * responsible for handling references
     */

    switch (type) {

    case T_BOOL: {
        int v = PyObject_IsTrue(value);
        if (v == -1) {
            return false;
        }

        writeByte(output, (int8_t) v);
        break;
    }
    case T_I08: {
        int32_t val;

        if (!parse_pyint(value, &val, INT8_MIN, INT8_MAX)) {
            return false;
        }

        writeByte(output, (int8_t) val);
        break;
    }
    case T_I16: {
        int32_t val;

        if (!parse_pyint(value, &val, INT16_MIN, INT16_MAX)) {
            return false;
        }

        writeI16(output, (int16_t) val);
        break;
    }
    case T_I32: {
        int32_t val;

        if (!parse_pyint(value, &val, INT32_MIN, INT32_MAX)) {
            return false;
        }

        writeI32(output, val);
        break;
    }
    case T_I64: {
        int64_t nval = PyLong_AsLongLong(value);

        if (INT_CONV_ERROR_OCCURRED(nval)) {
            return false;
        }

        if (!CHECK_RANGE(nval, INT64_MIN, INT64_MAX)) {
            PyErr_SetString(PyExc_OverflowError, "int out of range");
            return false;
        }

        writeI64(output, nval);
        break;
    }

    case T_DOUBLE: {
        double nval = PyFloat_AsDouble(value);
        if (nval == -1.0 && PyErr_Occurred()) {
            return false;
        }

        writeDouble(output, nval);
        break;
    }

    case T_STRING: {
        Py_ssize_t len = 0;
        if (is_utf8(typeargs) && PyUnicode_Check(value))
            value = PyUnicode_AsUTF8String(value);
        len = PyString_Size(value);

        if (!check_ssize_t_32(len)) {
            return false;
        }

        writeI32(output, (int32_t) len);
        PycStringIO->cwrite(output, PyString_AsString(value), (int32_t) len);
        break;
    }

    case T_LIST:
    case T_SET: {
        Py_ssize_t len;
        SetListTypeArgs parsedargs;
        PyObject *item;
        PyObject *iterator;

        if (!parse_set_list_args(&parsedargs, typeargs)) {
            return false;
        }

        len = PyObject_Length(value);

        if (!check_ssize_t_32(len)) {
            return false;
        }

        writeByte(output, parsedargs.element_type);
        writeI32(output, (int32_t) len);

        iterator =  PyObject_GetIter(value);
        if (iterator == NULL) {
            return false;
        }

        while ((item = PyIter_Next(iterator))) {
            if (!output_val(output, item, parsedargs.element_type, parsedargs.typeargs)) {
                Py_DECREF(item);
                Py_DECREF(iterator);
                return false;
            }
            Py_DECREF(item);
        }

        Py_DECREF(iterator);

        if (PyErr_Occurred()) {
            return false;
        }

        break;
    }

    case T_MAP: {
        PyObject *k, *v;
        Py_ssize_t pos = 0;
        Py_ssize_t len;

        MapTypeArgs parsedargs;

        len = PyDict_Size(value);
        if (!check_ssize_t_32(len)) {
            return false;
        }

        if (!parse_map_args(&parsedargs, typeargs)) {
            return false;
        }

        writeByte(output, parsedargs.ktag);
        writeByte(output, parsedargs.vtag);
        writeI32(output, len);

        // TODO(bmaurer): should support any mapping, not just dicts
        while (PyDict_Next(value, &pos, &k, &v)) {
            // TODO(dreiss): Think hard about whether these INCREFs actually
            //               turn any unsafe scenarios into safe scenarios.
            Py_INCREF(k);
            Py_INCREF(v);

            if (!output_val(output, k, parsedargs.ktag, parsedargs.ktypeargs)
                    || !output_val(output, v, parsedargs.vtag, parsedargs.vtypeargs)) {
                Py_DECREF(k);
                Py_DECREF(v);
                return false;
            }
            Py_DECREF(k);
            Py_DECREF(v);
        }
        break;
    }

    // TODO(dreiss): Consider breaking this out as a function
    //               the way we did for decode_struct.
    case T_STRUCT: {
        StructTypeArgs parsedargs;
        Py_ssize_t nspec;
        Py_ssize_t i;

        if (!parse_struct_args(&parsedargs, typeargs)) {
            return false;
        }

        nspec = PyTuple_Size(parsedargs.spec);

        if (nspec == -1) {
            return false;
        }

        for (i = 0; i < nspec; i++) {
            StructItemSpec parsedspec;
            PyObject* spec_tuple;
            PyObject* instval = NULL;

            spec_tuple = PyTuple_GET_ITEM(parsedargs.spec, i);
            if (spec_tuple == Py_None) {
                continue;
            }

            if (!parse_struct_item_spec (&parsedspec, spec_tuple)) {
                return false;
            }

            instval = PyObject_GetAttr(value, parsedspec.attrname);

            if (!instval) {
                return false;
            }

            if (instval == Py_None) {
                Py_DECREF(instval);
                continue;
            }

            writeByte(output, (int8_t) parsedspec.type);
            writeI16(output, parsedspec.tag);

            if (!output_val(output, instval, parsedspec.type, parsedspec.typeargs)) {
                Py_DECREF(instval);
                return false;
            }

            Py_DECREF(instval);
        }

        writeByte(output, (int8_t)T_STOP);
        break;
    }

    case T_STOP:
    case T_VOID:
    case T_UTF16:
    case T_UTF8:
    case T_U64:
    default:
        PyErr_SetString(PyExc_TypeError, "Unexpected TType");
        return false;

    }

    return true;
}
Пример #20
0
				      fname==NULL ? "" : "()",
				      min==max ? "exactly"
				      : len < min ? "at least" : "at most",
				      len < min ? min : max,
				      (len < min ? min : max) == 1 ? "" : "s",
				      Py_SAFE_DOWNCAST(len, Py_ssize_t, long));
			message = msgbuf;
		}
		PyErr_SetString(PyExc_TypeError, message);
		return 0;
	}
	
	for (i = 0; i < len; i++) {
		if (*format == '|')
			format++;
		msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va,
				  flags, levels, msgbuf, 
				  sizeof(msgbuf), &freelist);
		if (msg) {
			seterror(i+1, msg, levels, fname, message);
			return cleanreturn(0, freelist);
		}
	}

	if (*format != '\0' && !isalpha(Py_CHARMASK(*format)) &&
	    *format != '(' &&
	    *format != '|' && *format != ':' && *format != ';') {
		PyErr_Format(PyExc_SystemError,
			     "bad format string: %.200s", formatsave);
		return cleanreturn(0, freelist);
	}
Пример #21
0
PyObject *
PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
                PyObject *lineno_obj)
{
    Py_ssize_t i, j, codelen;
    int nops, h, adj;
    int tgt, tgttgt, opcode;
    unsigned char *codestr = NULL;
    unsigned char *lineno;
    int *addrmap = NULL;
    int new_line, cum_orig_line, last_line, tabsiz;
    int cumlc=0, lastlc=0;      /* Count runs of consecutive LOAD_CONSTs */
    unsigned int *blocks = NULL;
    char *name;

    /* Bail out if an exception is set */
    if (PyErr_Occurred())
        goto exitError;

    /* Bypass optimization when the lineno table is too complex */
    assert(PyBytes_Check(lineno_obj));
    lineno = (unsigned char*)PyBytes_AS_STRING(lineno_obj);
    tabsiz = PyBytes_GET_SIZE(lineno_obj);
    if (memchr(lineno, 255, tabsiz) != NULL)
        goto exitUnchanged;

    /* Avoid situations where jump retargeting could overflow */
    assert(PyBytes_Check(code));
    codelen = PyBytes_GET_SIZE(code);
    if (codelen > 32700)
        goto exitUnchanged;

    /* Make a modifiable copy of the code string */
    codestr = (unsigned char *)PyMem_Malloc(codelen);
    if (codestr == NULL)
        goto exitError;
    codestr = (unsigned char *)memcpy(codestr,
                                      PyBytes_AS_STRING(code), codelen);

    /* Verify that RETURN_VALUE terminates the codestring.      This allows
       the various transformation patterns to look ahead several
       instructions without additional checks to make sure they are not
       looking beyond the end of the code string.
    */
    if (codestr[codelen-1] != RETURN_VALUE)
        goto exitUnchanged;

    /* Mapping to new jump targets after NOPs are removed */
    addrmap = (int *)PyMem_Malloc(codelen * sizeof(int));
    if (addrmap == NULL)
        goto exitError;

    blocks = markblocks(codestr, codelen);
    if (blocks == NULL)
        goto exitError;
    assert(PyList_Check(consts));

    for (i=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
      reoptimize_current:
        opcode = codestr[i];

        lastlc = cumlc;
        cumlc = 0;

        switch (opcode) {
            /* Replace UNARY_NOT POP_JUMP_IF_FALSE
               with    POP_JUMP_IF_TRUE */
            case UNARY_NOT:
                if (codestr[i+1] != POP_JUMP_IF_FALSE
                    || !ISBASICBLOCK(blocks,i,4))
                    continue;
                j = GETARG(codestr, i+1);
                codestr[i] = POP_JUMP_IF_TRUE;
                SETARG(codestr, i, j);
                codestr[i+3] = NOP;
                goto reoptimize_current;

                /* not a is b -->  a is not b
                   not a in b -->  a not in b
                   not a is not b -->  a is b
                   not a not in b -->  a in b
                */
            case COMPARE_OP:
                j = GETARG(codestr, i);
                if (j < 6  ||  j > 9  ||
                    codestr[i+3] != UNARY_NOT  ||
                    !ISBASICBLOCK(blocks,i,4))
                    continue;
                SETARG(codestr, i, (j^1));
                codestr[i+3] = NOP;
                break;

                /* Replace LOAD_GLOBAL/LOAD_NAME None/True/False
                   with LOAD_CONST None/True/False */
            case LOAD_NAME:
            case LOAD_GLOBAL:
                j = GETARG(codestr, i);
                name = _PyUnicode_AsString(PyTuple_GET_ITEM(names, j));
                h = load_global(codestr, i, name, consts);
                if (h < 0)
                    goto exitError;
                else if (h == 0)
                    continue;
                cumlc = lastlc + 1;
                break;

                /* Skip over LOAD_CONST trueconst
                   POP_JUMP_IF_FALSE xx. This improves
                   "while 1" performance. */
            case LOAD_CONST:
                cumlc = lastlc + 1;
                j = GETARG(codestr, i);
                if (codestr[i+3] != POP_JUMP_IF_FALSE  ||
                    !ISBASICBLOCK(blocks,i,6)  ||
                    !PyObject_IsTrue(PyList_GET_ITEM(consts, j)))
                    continue;
                memset(codestr+i, NOP, 6);
                cumlc = 0;
                break;

                /* Try to fold tuples of constants (includes a case for lists and sets
                   which are only used for "in" and "not in" tests).
                   Skip over BUILD_SEQN 1 UNPACK_SEQN 1.
                   Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2.
                   Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */
            case BUILD_TUPLE:
            case BUILD_LIST:
            case BUILD_SET:
                j = GETARG(codestr, i);
                h = i - 3 * j;
                if (h >= 0  &&
                    j <= lastlc                  &&
                    ((opcode == BUILD_TUPLE &&
                      ISBASICBLOCK(blocks, h, 3*(j+1))) ||
                     ((opcode == BUILD_LIST || opcode == BUILD_SET) &&
                      codestr[i+3]==COMPARE_OP &&
                      ISBASICBLOCK(blocks, h, 3*(j+2)) &&
                      (GETARG(codestr,i+3)==6 ||
                       GETARG(codestr,i+3)==7))) &&
                    tuple_of_constants(&codestr[h], j, consts)) {
                    assert(codestr[i] == LOAD_CONST);
                    cumlc = 1;
                    break;
                }
                if (codestr[i+3] != UNPACK_SEQUENCE  ||
                    !ISBASICBLOCK(blocks,i,6) ||
                    j != GETARG(codestr, i+3) ||
                    opcode == BUILD_SET)
                    continue;
                if (j == 1) {
                    memset(codestr+i, NOP, 6);
                } else if (j == 2) {
                    codestr[i] = ROT_TWO;
                    memset(codestr+i+1, NOP, 5);
                } else if (j == 3) {
                    codestr[i] = ROT_THREE;
                    codestr[i+1] = ROT_TWO;
                    memset(codestr+i+2, NOP, 4);
                }
                break;

                /* Fold binary ops on constants.
                   LOAD_CONST c1 LOAD_CONST c2 BINOP -->  LOAD_CONST binop(c1,c2) */
            case BINARY_POWER:
            case BINARY_MULTIPLY:
            case BINARY_TRUE_DIVIDE:
            case BINARY_FLOOR_DIVIDE:
            case BINARY_MODULO:
            case BINARY_ADD:
            case BINARY_SUBTRACT:
            case BINARY_SUBSCR:
            case BINARY_LSHIFT:
            case BINARY_RSHIFT:
            case BINARY_AND:
            case BINARY_XOR:
            case BINARY_OR:
                if (lastlc >= 2                  &&
                    ISBASICBLOCK(blocks, i-6, 7)  &&
                    fold_binops_on_constants(&codestr[i-6], consts)) {
                    i -= 2;
                    assert(codestr[i] == LOAD_CONST);
                    cumlc = 1;
                }
                break;

                /* Fold unary ops on constants.
                   LOAD_CONST c1  UNARY_OP -->                  LOAD_CONST unary_op(c) */
            case UNARY_NEGATIVE:
            case UNARY_INVERT:
            case UNARY_POSITIVE:
                if (lastlc >= 1                  &&
                    ISBASICBLOCK(blocks, i-3, 4)  &&
                    fold_unaryops_on_constants(&codestr[i-3], consts))                  {
                    i -= 2;
                    assert(codestr[i] == LOAD_CONST);
                    cumlc = 1;
                }
                break;

                /* Simplify conditional jump to conditional jump where the
                   result of the first test implies the success of a similar
                   test or the failure of the opposite test.
                   Arises in code like:
                   "if a and b:"
                   "if a or b:"
                   "a and b or c"
                   "(a and b) and c"
                   x:JUMP_IF_FALSE_OR_POP y   y:JUMP_IF_FALSE_OR_POP z
                      -->  x:JUMP_IF_FALSE_OR_POP z
                   x:JUMP_IF_FALSE_OR_POP y   y:JUMP_IF_TRUE_OR_POP z
                      -->  x:POP_JUMP_IF_FALSE y+3
                   where y+3 is the instruction following the second test.
                */
            case JUMP_IF_FALSE_OR_POP:
            case JUMP_IF_TRUE_OR_POP:
                tgt = GETJUMPTGT(codestr, i);
                j = codestr[tgt];
                if (CONDITIONAL_JUMP(j)) {
                    /* NOTE: all possible jumps here are
                       absolute! */
                    if (JUMPS_ON_TRUE(j) == JUMPS_ON_TRUE(opcode)) {
                        /* The second jump will be
                           taken iff the first is. */
                        tgttgt = GETJUMPTGT(codestr, tgt);
                        /* The current opcode inherits
                           its target's stack behaviour */
                        codestr[i] = j;
                        SETARG(codestr, i, tgttgt);
                        goto reoptimize_current;
                    } else {
                        /* The second jump is not taken
                           if the first is (so jump past
                           it), and all conditional
                           jumps pop their argument when
                           they're not taken (so change
                           the first jump to pop its
                           argument when it's taken). */
                        if (JUMPS_ON_TRUE(opcode))
                            codestr[i] = POP_JUMP_IF_TRUE;
                        else
                            codestr[i] = POP_JUMP_IF_FALSE;
                        SETARG(codestr, i, (tgt + 3));
                        goto reoptimize_current;
                    }
                }
                /* Intentional fallthrough */

                /* Replace jumps to unconditional jumps */
            case POP_JUMP_IF_FALSE:
            case POP_JUMP_IF_TRUE:
            case FOR_ITER:
            case JUMP_FORWARD:
            case JUMP_ABSOLUTE:
            case CONTINUE_LOOP:
            case SETUP_LOOP:
            case SETUP_EXCEPT:
            case SETUP_FINALLY:
            case SETUP_WITH:
                tgt = GETJUMPTGT(codestr, i);
                /* Replace JUMP_* to a RETURN into just a RETURN */
                if (UNCONDITIONAL_JUMP(opcode) &&
                    codestr[tgt] == RETURN_VALUE) {
                    codestr[i] = RETURN_VALUE;
                    memset(codestr+i+1, NOP, 2);
                    continue;
                }
                if (!UNCONDITIONAL_JUMP(codestr[tgt]))
                    continue;
                tgttgt = GETJUMPTGT(codestr, tgt);
                if (opcode == JUMP_FORWARD) /* JMP_ABS can go backwards */
                    opcode = JUMP_ABSOLUTE;
                if (!ABSOLUTE_JUMP(opcode))
                    tgttgt -= i + 3;     /* Calc relative jump addr */
                if (tgttgt < 0)                           /* No backward relative jumps */
                    continue;
                codestr[i] = opcode;
                SETARG(codestr, i, tgttgt);
                break;

            case EXTENDED_ARG:
                if (codestr[i+3] != MAKE_FUNCTION)
                    goto exitUnchanged;
                /* don't visit MAKE_FUNCTION as GETARG will be wrong */
                i += 3;
                break;

                /* Replace RETURN LOAD_CONST None RETURN with just RETURN */
                /* Remove unreachable JUMPs after RETURN */
            case RETURN_VALUE:
                if (i+4 >= codelen)
                    continue;
                if (codestr[i+4] == RETURN_VALUE &&
                    ISBASICBLOCK(blocks,i,5))
                    memset(codestr+i+1, NOP, 4);
                else if (UNCONDITIONAL_JUMP(codestr[i+1]) &&
                         ISBASICBLOCK(blocks,i,4))
                    memset(codestr+i+1, NOP, 3);
                break;
        }
    }

    /* Fixup linenotab */
    for (i=0, nops=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
        addrmap[i] = i - nops;
        if (codestr[i] == NOP)
            nops++;
    }
    cum_orig_line = 0;
    last_line = 0;
    for (i=0 ; i < tabsiz ; i+=2) {
        cum_orig_line += lineno[i];
        new_line = addrmap[cum_orig_line];
        assert (new_line - last_line < 255);
        lineno[i] =((unsigned char)(new_line - last_line));
        last_line = new_line;
    }

    /* Remove NOPs and fixup jump targets */
    for (i=0, h=0 ; i<codelen ; ) {
        opcode = codestr[i];
        switch (opcode) {
            case NOP:
                i++;
                continue;

            case JUMP_ABSOLUTE:
            case CONTINUE_LOOP:
            case POP_JUMP_IF_FALSE:
            case POP_JUMP_IF_TRUE:
            case JUMP_IF_FALSE_OR_POP:
            case JUMP_IF_TRUE_OR_POP:
                j = addrmap[GETARG(codestr, i)];
                SETARG(codestr, i, j);
                break;

            case FOR_ITER:
            case JUMP_FORWARD:
            case SETUP_LOOP:
            case SETUP_EXCEPT:
            case SETUP_FINALLY:
            case SETUP_WITH:
                j = addrmap[GETARG(codestr, i) + i + 3] - addrmap[i] - 3;
                SETARG(codestr, i, j);
                break;
        }
        adj = CODESIZE(opcode);
        while (adj--)
            codestr[h++] = codestr[i++];
    }
    assert(h + nops == codelen);

    code = PyBytes_FromStringAndSize((char *)codestr, h);
    PyMem_Free(addrmap);
    PyMem_Free(codestr);
    PyMem_Free(blocks);
    return code;

 exitError:
    code = NULL;

 exitUnchanged:
    if (blocks != NULL)
        PyMem_Free(blocks);
    if (addrmap != NULL)
        PyMem_Free(addrmap);
    if (codestr != NULL)
        PyMem_Free(codestr);
    Py_XINCREF(code);
    return code;
}
Пример #22
0
static PyObject* py_set_colors(PyObject *self, PyObject *args, PyObject *kwargs)
{
  PyObject *newdict, *newtuple, *keys, *vals;
  const char *kwnames[] = {"colors", NULL};
  PyObject *retval = NULL;
  char *keyname;
  float rgb[3];
  VMDApp *app;

  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!:color.set_colors",
                                   (char**) kwnames, &PyDict_Type, &newdict))
    return NULL;

  if (!(app = get_vmdapp()))
    return NULL;

  keys = PyDict_Keys(newdict);
  vals = PyDict_Values(newdict);

  for (int i=0; i<PyList_Size(keys); i++) {
    // Get color name from input dictionary
    keyname = as_charptr(PyList_GetItem(keys, i));
    if (PyErr_Occurred())
        goto cleanup;

    // Check this color name actually exists
    if (app->color_index(keyname) < 0) {
      PyErr_Format(PyExc_ValueError, "Unknown color '%s'", keyname);
      goto cleanup;
    }

    // Unpack value tuples into 3 floats
    newtuple = PyList_GetItem(vals, i);
    if (!PyTuple_Check(newtuple) || PyTuple_Size(newtuple) != 3) {
      PyErr_SetString(PyExc_ValueError,
                      "color definition must be 3-tuple of floats");
      goto cleanup;
    }

    for (int j=0; j<3; j++) {
      rgb[j] = (float)PyFloat_AsDouble(PyTuple_GET_ITEM(newtuple, j));

      if (PyErr_Occurred()) {
        PyErr_SetString(PyExc_ValueError, "color definition must be floats");
        goto cleanup;
      }
    }

    // Finally actually change the color
    app->color_change_rgb(keyname, rgb[0], rgb[1], rgb[2]);
  }
  retval = Py_None;

  // Getting the keys and values from the dictionary makes a new reference.
  // We tell Python we're done with it so as to not leak memory.
  // This needs to happen even if there was a problem setting color, which is
  // why we don't return NULL from the error checking statements above.
cleanup:
  Py_DECREF(keys);
  Py_DECREF(vals);

  Py_XINCREF(retval);
  return retval;
}
Пример #23
0
/*
 * array_from_elements - classmethod to build an array
 */
static PyObj
array_from_elements(PyObj self, PyObj args, PyObj kw)
{
	static char *kwlist[] = {"elements", "dimensions", "lowerbounds", NULL};
	PyObj rob = NULL, iter, listob, dims_ob = NULL, lbs_ob = NULL;
	int dims[MAXDIM];
	int lbs[MAXDIM] = {1, 0,};
	int ndims = 1, nelems;
	Py_ssize_t i;
	ArrayType *rat = NULL;

	if (!PyArg_ParseTupleAndKeywords(args, kw, "O|OO:from_elements",
		kwlist, &iter, &dims_ob, &lbs_ob))
	{
		return(NULL);
	}

	listob = Py_Call((PyObj) &PyList_Type, iter);
	if (listob == NULL)
		return(NULL);
	Assert(PyList_CheckExact(listob));

	/*
	 * Convert the dimensions keyword into a tuple and extract the values
	 * into the dims[] array.
	 */
	if (dims_ob != NULL && dims_ob != Py_None)
	{
		PyObj tdims_ob;

		tdims_ob = Py_Call((PyObj) &PyTuple_Type, dims_ob);
		if (tdims_ob == NULL)
			goto fail;

		ndims = PyTuple_GET_SIZE(tdims_ob);
		if (ndims > MAXDIM)
		{
			Py_DECREF(tdims_ob);
			PyErr_Format(PyExc_ValueError, "too many dimensions (%d) for array",
							ndims);
			goto fail;
		}

		if (ndims > 0)
		{
			for (i = 0; i < ndims; ++i)
			{
				dims[i] = (int) PyNumber_AsSsize_t(PyTuple_GET_ITEM(tdims_ob, i),
													NULL);
				if (PyErr_Occurred())
				{
					Py_DECREF(tdims_ob);
					goto fail;
				}
			}
		}
		else
			dims[0] = 0;

		Py_DECREF(tdims_ob);
	}
	else
	{
		dims[0] = PyList_GET_SIZE(listob);
		if (dims[0] == 0)
			ndims = 0;
	}

	nelems = dims[0];
	if (ndims > 1)
	{
		for (i = 1; i < ndims; ++i)
			nelems = nelems * dims[i];
	}

	if (nelems != PyList_GET_SIZE(listob))
	{
		PyErr_Format(PyExc_ValueError,
			"dimension capacity (%d) does not accommodate the given elements (%d)",
			nelems, PyList_GET_SIZE(listob));
		goto fail;
	}

	if (lbs_ob != NULL && lbs_ob != Py_None)
	{
		PyObj tlbs_ob;

		tlbs_ob = Py_Call((PyObj) &PyTuple_Type, lbs_ob);
		if (tlbs_ob == NULL)
			goto fail;

		if (PyTuple_GET_SIZE(tlbs_ob) > MAXDIM)
		{
			Py_DECREF(tlbs_ob);
			PyErr_SetString(PyExc_ValueError, "too many dimensions for array");
			goto fail;
		}

		if (PyTuple_GET_SIZE(tlbs_ob) != ndims)
		{
			Py_DECREF(tlbs_ob);
			PyErr_Format(PyExc_ValueError, "number of lower bounds (%d) is "
				"inconsistent with dimensions (%d)",
				PyTuple_GET_SIZE(tlbs_ob), ndims);
			goto fail;
		}

		for (i = 0; i < PyTuple_GET_SIZE(tlbs_ob); ++i)
		{
			lbs[i] = (int) PyNumber_AsSsize_t(PyTuple_GET_ITEM(tlbs_ob, i),
												NULL);
			if (PyErr_Occurred())
			{
				Py_DECREF(tlbs_ob);
				goto fail;
			}
		}

		Py_DECREF(tlbs_ob);
	}
	else
	{
		/*
		 * No lower bounds specified, fill in with 1's.
		 */
		for (i = 0; i < ndims; ++i)
		{
			lbs[i] = 1;
		}
	}

	rat = array_from_list_and_info(
		PyPgType_GetElementType(self),
		listob, -1, ndims, dims, lbs);
	Py_DECREF(listob);

	if (rat != NULL)
	{
		rob = PyPgObject_New(self, PointerGetDatum(rat));
		pfree(rat);
	}

	return(rob);
fail:
	Py_XDECREF(listob);
	return(NULL);
}
Пример #24
0
static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, int *defvalue, const short is_enum_flag)
{
	EnumPropertyItem *items;
	PyObject *item;
	const Py_ssize_t seq_len= PySequence_Fast_GET_SIZE(seq_fast);
	Py_ssize_t totbuf= 0;
	int i;
	short def_used= 0;
	const char *def_cmp= NULL;

	if(is_enum_flag) {
		if(seq_len > RNA_ENUM_BITFLAG_SIZE) {
			PyErr_SetString(PyExc_TypeError, "EnumProperty(...): maximum " STRINGIFY(RNA_ENUM_BITFLAG_SIZE) " members for a ENUM_FLAG type property");
			return NULL;
		}
		if(def && !PySet_Check(def)) {
			PyErr_Format(PyExc_TypeError,
			             "EnumProperty(...): default option must be a 'set' "
			             "type when ENUM_FLAG is enabled, not a '%.200s'",
			             Py_TYPE(def)->tp_name);
			return NULL;
		}
	}
	else {
		if(def) {
			def_cmp= _PyUnicode_AsString(def);
			if(def_cmp==NULL) {
				PyErr_Format(PyExc_TypeError,
				             "EnumProperty(...): default option must be a 'str' "
				             "type when ENUM_FLAG is disabled, not a '%.200s'",
				             Py_TYPE(def)->tp_name);
				return NULL;
			}
		}
	}

	/* blank value */
	*defvalue= 0;

	items= MEM_callocN(sizeof(EnumPropertyItem) * (seq_len + 1), "enum_items_from_py1");

	for(i=0; i<seq_len; i++) {
		EnumPropertyItem tmp= {0, "", 0, "", ""};
		Py_ssize_t id_str_size;
		Py_ssize_t name_str_size;
		Py_ssize_t desc_str_size;

		item= PySequence_Fast_GET_ITEM(seq_fast, i);

		if(		(PyTuple_CheckExact(item)) &&
		        (PyTuple_GET_SIZE(item) == 3) &&
		        (tmp.identifier=  _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 0), &id_str_size)) &&
		        (tmp.name=        _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 1), &name_str_size)) &&
		        (tmp.description= _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 2), &desc_str_size))
		) {
			if(is_enum_flag) {
				tmp.value= 1<<i;

				if(def && PySet_Contains(def, PyTuple_GET_ITEM(item, 0))) {
					*defvalue |= tmp.value;
					def_used++;
				}
			}
			else {
				tmp.value= i;

				if(def && def_used == 0 && strcmp(def_cmp, tmp.identifier)==0) {
					*defvalue= tmp.value;
					def_used++; /* only ever 1 */
				}
			}

			items[i]= tmp;

			/* calculate combine string length */
			totbuf += id_str_size + name_str_size + desc_str_size + 3; /* 3 is for '\0's */
		}
		else {
			MEM_freeN(items);
			PyErr_SetString(PyExc_TypeError, "EnumProperty(...): expected an tuple containing (identifier, name description)");
			return NULL;
		}

	}

	if(is_enum_flag) {
		/* strict check that all set members were used */
		if(def && def_used != PySet_GET_SIZE(def)) {
			MEM_freeN(items);

			PyErr_Format(PyExc_TypeError,
			             "EnumProperty(..., default={...}): set has %d unused member(s)",
			             PySet_GET_SIZE(def) - def_used);
			return NULL;
		}
	}
	else {
		if(def && def_used == 0) {
			MEM_freeN(items);

			PyErr_Format(PyExc_TypeError,
			             "EnumProperty(..., default=\'%s\'): not found in enum members",
			             def);
			return NULL;
		}
	}

	/* disabled duplicating strings because the array can still be freed and
	 * the strings from it referenced, for now we can't support dynamically
	 * created strings from python. */
#if 0
	/* this would all work perfectly _but_ the python strings may be freed
	 * immediately after use, so we need to duplicate them, ugh.
	 * annoying because it works most of the time without this. */
	{
		EnumPropertyItem *items_dup= MEM_mallocN((sizeof(EnumPropertyItem) * (seq_len + 1)) + (sizeof(char) * totbuf), "enum_items_from_py2");
		EnumPropertyItem *items_ptr= items_dup;
		char *buf= ((char *)items_dup) + (sizeof(EnumPropertyItem) * (seq_len + 1));
		memcpy(items_dup, items, sizeof(EnumPropertyItem) * (seq_len + 1));
		for(i=0; i<seq_len; i++, items_ptr++) {
			buf += strswapbufcpy(buf, &items_ptr->identifier);
			buf += strswapbufcpy(buf, &items_ptr->name);
			buf += strswapbufcpy(buf, &items_ptr->description);
		}
		MEM_freeN(items);
		items=items_dup;
	}
	/* end string duplication */
#endif

	return items;
}
Пример #25
0
/* pygi_invoke_marshal_in_args:
 *
 * Fills out the state struct argument lists. arg_values will always hold
 * actual values marshaled either to or from Python and C. arg_pointers will
 * hold pointers (via v_pointer) to auxilary value storage. This will normally
 * point to values stored in arg_values. In the case of caller allocated
 * out args, arg_pointers[x].v_pointer will point to newly allocated memory.
 * arg_pointers inserts a level of pointer indirection between arg_values
 * and the argument list ffi receives when dealing with non-caller allocated
 * out arguments.
 *
 * For example:
 * [[
 *  void callee (int *i, int j) { *i = 50 - j; }
 *  void caller () {
 *    int i = 0;
 *    callee (&i, 8);
 *  }
 *
 *  args[0] == &arg_pointers[0];
 *  arg_pointers[0].v_pointer == &arg_values[0];
 *  arg_values[0].v_int == 42;
 *
 *  args[1] == &arg_values[1];
 *  arg_values[1].v_int == 8;
 * ]]
 *
 */
static gboolean
_invoke_marshal_in_args (PyGIInvokeState *state, PyGIFunctionCache *function_cache)
{
    PyGICallableCache *cache = (PyGICallableCache *) function_cache;
    gssize i;

    if (state->n_py_in_args > cache->n_py_args) {
        char *full_name = pygi_callable_cache_get_full_name (cache);
        PyErr_Format (PyExc_TypeError,
                      "%s() takes exactly %zd argument(s) (%zd given)",
                      full_name,
                      cache->n_py_args,
                      state->n_py_in_args);
        g_free (full_name);
        return FALSE;
    }

    for (i = 0; i < _pygi_callable_cache_args_len (cache); i++) {
        GIArgument *c_arg = &state->args[i].arg_value;
        PyGIArgCache *arg_cache = g_ptr_array_index (cache->args_cache, i);
        PyObject *py_arg = NULL;

        switch (arg_cache->direction) {
            case PYGI_DIRECTION_FROM_PYTHON:
                /* The ffi argument points directly at memory in arg_values. */
                state->ffi_args[i] = c_arg;

                if (arg_cache->meta_type == PYGI_META_ARG_TYPE_CLOSURE) {
                    state->ffi_args[i]->v_pointer = state->user_data;
                    continue;
                } else if (arg_cache->meta_type != PYGI_META_ARG_TYPE_PARENT)
                    continue;

                if (arg_cache->py_arg_index >= state->n_py_in_args) {
                    char *full_name = pygi_callable_cache_get_full_name (cache);
                    PyErr_Format (PyExc_TypeError,
                                  "%s() takes exactly %zd argument(s) (%zd given)",
                                   full_name,
                                   cache->n_py_args,
                                   state->n_py_in_args);
                    g_free (full_name);

                    /* clean up all of the args we have already marshalled,
                     * since invoke will not be called
                     */
                    pygi_marshal_cleanup_args_from_py_parameter_fail (state,
                                                                      cache,
                                                                      i);
                    return FALSE;
                }

                py_arg =
                    PyTuple_GET_ITEM (state->py_in_args,
                                      arg_cache->py_arg_index);

                break;
            case PYGI_DIRECTION_BIDIRECTIONAL:
                if (arg_cache->meta_type != PYGI_META_ARG_TYPE_CHILD) {
                    if (arg_cache->py_arg_index >= state->n_py_in_args) {
                        char *full_name = pygi_callable_cache_get_full_name (cache);
                        PyErr_Format (PyExc_TypeError,
                                      "%s() takes exactly %zd argument(s) (%zd given)",
                                       full_name,
                                       cache->n_py_args,
                                       state->n_py_in_args);
                        g_free (full_name);
                        pygi_marshal_cleanup_args_from_py_parameter_fail (state,
                                                                          cache,
                                                                          i);
                        return FALSE;
                    }

                    py_arg =
                        PyTuple_GET_ITEM (state->py_in_args,
                                          arg_cache->py_arg_index);
                }
                /* Fall through */

            case PYGI_DIRECTION_TO_PYTHON:
                /* arg_pointers always stores a pointer to the data to be marshaled "to python"
                 * even in cases where arg_pointers is not being used as indirection between
                 * ffi and arg_values. This gives a guarantee that out argument marshaling
                 * (_invoke_marshal_out_args) can always rely on arg_pointers pointing to
                 * the correct chunk of memory to marshal.
                 */
                state->args[i].arg_pointer.v_pointer = c_arg;

                if (arg_cache->is_caller_allocates) {
                    /* In the case of caller allocated out args, we don't use
                     * an extra level of indirection and state->args will point
                     * directly at the data to be marshaled. However, as noted
                     * above, arg_pointers will also point to this caller allocated
                     * chunk of memory used by out argument marshaling.
                     */
                    state->ffi_args[i] = c_arg;

                    if (!_caller_alloc (arg_cache, c_arg)) {
                        char *full_name = pygi_callable_cache_get_full_name (cache);
                        PyErr_Format (PyExc_TypeError,
                                      "Could not caller allocate argument %zd of callable %s",
                                      i, full_name);
                        g_free (full_name);
                        pygi_marshal_cleanup_args_from_py_parameter_fail (state,
                                                                          cache,
                                                                          i);
                        return FALSE;
                    }
                } else {
                    /* Non-caller allocated out args will use arg_pointers as an
                     * extra level of indirection */
                    state->ffi_args[i] = &state->args[i].arg_pointer;
                }

                break;
        }

        if (py_arg == _PyGIDefaultArgPlaceholder) {
            *c_arg = arg_cache->default_value;
        } else if (arg_cache->from_py_marshaller != NULL &&
                   arg_cache->meta_type != PYGI_META_ARG_TYPE_CHILD) {
            gboolean success;
            gpointer cleanup_data = NULL;

            if (!arg_cache->allow_none && py_arg == Py_None) {
                PyErr_Format (PyExc_TypeError,
                              "Argument %zd does not allow None as a value",
                              i);

                 pygi_marshal_cleanup_args_from_py_parameter_fail (state,
                                                                   cache,
                                                                   i);
                 return FALSE;
            }
            success = arg_cache->from_py_marshaller (state,
                                                     cache,
                                                     arg_cache,
                                                     py_arg,
                                                     c_arg,
                                                     &cleanup_data);
            state->args[i].arg_cleanup_data = cleanup_data;

            if (!success) {
                pygi_marshal_cleanup_args_from_py_parameter_fail (state,
                                                                  cache,
                                                                  i);
                return FALSE;
            }

        }

    }

    return TRUE;
}
Пример #26
0
/* This function is called by the tp_dealloc handler to clear weak references.
 *
 * This iterates through the weak references for 'object' and calls callbacks
 * for those references which have one.  It returns when all callbacks have
 * been attempted.
 */
void
PyObject_ClearWeakRefs(PyObject *object)
{
    PyWeakReference **list;

    if (object == NULL
        || !PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))
        //|| object->ob_refcnt != 0
        ) {
        PyErr_BadInternalCall();
        return;
    }
    list = GET_WEAKREFS_LISTPTR(object);
    /* Remove the callback-less basic and proxy references */
    if (*list != NULL && (*list)->wr_callback == NULL) {
        clear_weakref(*list);
        if (*list != NULL && (*list)->wr_callback == NULL)
            clear_weakref(*list);
    }
    if (*list != NULL) {
        PyWeakReference *current = *list;
        Py_ssize_t count = _PyWeakref_GetWeakrefCount(current);
        int restore_error = PyErr_Occurred() ? 1 : 0;
        PyObject *err_type, *err_value, *err_tb;

        if (restore_error)
            PyErr_Fetch(&err_type, &err_value, &err_tb);
        if (count == 1) {
            PyObject *callback = current->wr_callback;

            current->wr_callback = NULL;
            clear_weakref(current);
            if (callback != NULL) {
                // Pyston change:
                // current is a stack reference to a GC allocated object.  If it wasn't null when we fetched it from *list, it won't
                // be collected, and we can trust that it's still valid here.
                if (true /*current->ob_refcnt > 0*/)
                    handle_callback(current, callback);
                Py_DECREF(callback);
            }
        }
        else {
            PyObject *tuple;
            Py_ssize_t i = 0;

            tuple = PyTuple_New(count * 2);
            if (tuple == NULL) {
                if (restore_error)
                    PyErr_Fetch(&err_type, &err_value, &err_tb);
                return;
            }

            for (i = 0; i < count; ++i) {
                PyWeakReference *next = current->wr_next;

                // Pyston change:
                // current is a stack reference to a GC allocated object.  If it wasn't null when we fetched it from *list, it won't
                // be collected, and we can trust that it's still valid here.
                if (true /*current->ob_refcnt > 0*/)
                {
                    Py_INCREF(current);
                    PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current);
                    PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback);
                }
                else {
                    Py_DECREF(current->wr_callback);
                }
                current->wr_callback = NULL;
                clear_weakref(current);
                current = next;
            }
            for (i = 0; i < count; ++i) {
                PyObject *callback = PyTuple_GET_ITEM(tuple, i * 2 + 1);

                /* The tuple may have slots left to NULL */
                if (callback != NULL) {
                    PyObject *item = PyTuple_GET_ITEM(tuple, i * 2);
                    handle_callback((PyWeakReference *)item, callback);
                }
            }
            Py_DECREF(tuple);
        }
        if (restore_error)
            PyErr_Restore(err_type, err_value, err_tb);
    }
}
Пример #27
0
static PyObject *
optimize_code(PyObject *code, PyObject* consts)
{
	int i, j, codelen;
	int tgt, tgttgt, opcode;
	unsigned char *codestr;

	/* Make a modifiable copy of the code string */
	if (!PyString_Check(code))
		goto exitUnchanged;
	codelen = PyString_Size(code);
	codestr = PyMem_Malloc(codelen);
	if (codestr == NULL) 
		goto exitUnchanged;
	codestr = memcpy(codestr, PyString_AS_STRING(code), codelen);
	assert(PyTuple_Check(consts));

	for (i=0 ; i<codelen-7 ; i += HAS_ARG(codestr[i]) ? 3 : 1) {
		opcode = codestr[i];
		switch (opcode) {

		/* Skip over LOAD_CONST trueconst  JUMP_IF_FALSE xx  POP_TOP. 
		   Note, only the first opcode is changed, the others still
		   perform normally if they happen to be jump targets. */
		case LOAD_CONST:
			j = GETARG(codestr, i);
			if (codestr[i+3] != JUMP_IF_FALSE  ||
			    codestr[i+6] != POP_TOP  ||
			    !PyObject_IsTrue(PyTuple_GET_ITEM(consts, j)))
				continue;
			codestr[i] = JUMP_FORWARD;
			SETARG(codestr, i, 4);
			break;

		/* Replace jumps to unconditional jumps */
		case FOR_ITER:
		case JUMP_FORWARD:
		case JUMP_IF_FALSE:
		case JUMP_IF_TRUE:
		case JUMP_ABSOLUTE:
		case CONTINUE_LOOP:
		case SETUP_LOOP:
		case SETUP_EXCEPT:
		case SETUP_FINALLY:
			tgt = GETJUMPTGT(codestr, i);
			if (!UNCONDITIONAL_JUMP(codestr[tgt])) 
				continue;
			tgttgt = GETJUMPTGT(codestr, tgt);
			if (opcode == JUMP_FORWARD) /* JMP_ABS can go backwards */
				opcode = JUMP_ABSOLUTE;
			if (!ABSOLUTE_JUMP(opcode))
				tgttgt -= i + 3;     /* Calc relative jump addr */
			if (tgttgt < 0)           /* No backward relative jumps */
				 continue;
			codestr[i] = opcode;
			SETARG(codestr, i, tgttgt);
			break;

		case EXTENDED_ARG:
			PyMem_Free(codestr);
			goto exitUnchanged;
		}
	}
	code = PyString_FromStringAndSize((char *)codestr, codelen);
	PyMem_Free(codestr);
	return code;

exitUnchanged:
	Py_INCREF(code);
	return code;
}
Пример #28
0
static PyObject *set(PyObject *self, PyObject *args) {
  int i, molid, frame;
  PyObject *selected, *val;
  char *attr = 0;

  //
  // get molid, frame, list, attribute, and value
  //
  if (!PyArg_ParseTuple(args, (char *)"iiO!sO!", &molid, &frame,
                        &PyTuple_Type, &selected, 
                        &attr, &PyTuple_Type, &val ))
    return NULL;  // bad args

  // 
  // check that we have been given either one value or one for each selected
  // atom
  //
  int num_selected = PyTuple_Size(selected);
  int tuplesize = PyTuple_Size(val);
  if (tuplesize != 1 && tuplesize != num_selected) {
    PyErr_SetString(PyExc_ValueError, "wrong number of items");
    return NULL; 
  }
 
  //
  // check molecule
  //
  VMDApp *app = get_vmdapp();
  Molecule *mol = app->moleculeList->mol_from_id(molid);
  if (!mol) {
    PyErr_SetString(PyExc_ValueError, "molecule no longer exists");
    return NULL;
  }
  const int num_atoms = mol->nAtoms;

  //
  // Check for a valid attribute
  //
  SymbolTable *table = app->atomSelParser;
  int attrib_index = table->find_attribute(attr);
  if (attrib_index == -1) {
    PyErr_SetString(PyExc_ValueError, "unknown atom attribute");
    return NULL;
  }
  SymbolTableElement *elem = table->fctns.data(attrib_index);
  if (elem->is_a != SymbolTableElement::KEYWORD &&
      elem->is_a != SymbolTableElement::SINGLEWORD) {
    PyErr_SetString(PyExc_ValueError, "attribute is not a keyword or singleword");
    return NULL;
  }
  if (!table->is_changeable(attrib_index)) {
    PyErr_SetString(PyExc_ValueError, "attribute is not modifiable");
    return NULL; 
  }

  // 
  // convert the list of selected atoms into an array of integer flags
  //
  // XXX should check that selected contains valid indices
  int *flgs = new int[num_atoms];
  memset(flgs,0,num_atoms*sizeof(int));
  for (i=0; i<num_selected; i++)
    flgs[PyInt_AsLong(PyTuple_GET_ITEM(selected,i))] = 1;
 
  //  
  // set the data
  //

  // singlewords can never be set, so macro is NULL.
  atomsel_ctxt context(table, mol, frame, NULL);
  if (elem->returns_a == SymbolTableElement::IS_INT) {
    int *list = new int[num_atoms];
    if (tuplesize > 1) {
      int j=0;
      for (int i=0; i<num_atoms; i++) {
        if (flgs[i])
          list[i] = PyInt_AsLong(PyTuple_GET_ITEM(val, j++));
      }
    } else {
      for (int i=0; i<num_atoms; i++) {
        if (flgs[i])
          list[i] = PyInt_AsLong(PyTuple_GET_ITEM(val, 0));
      }
    }
    elem->set_keyword_int(&context, num_atoms, list, flgs);
    delete [] list;

  } else if (elem->returns_a == SymbolTableElement::IS_FLOAT) {
    double *list = new double[num_atoms];
    if (tuplesize > 1) { 
      int j=0;
      for (int i=0; i<num_atoms; i++) { 
        if (flgs[i])
          list[i] = PyFloat_AsDouble(PyTuple_GET_ITEM(val, j++));
      }
    } else {
      for (int i=0; i<num_atoms; i++) {
        if (flgs[i])
          list[i] = PyFloat_AsDouble(PyTuple_GET_ITEM(val, 0));
      }
    }
    elem->set_keyword_double(&context, num_atoms, list, flgs);
    delete [] list;


  } else if (elem->returns_a == SymbolTableElement::IS_STRING) {

    const char **list = new const char *[num_atoms];
    if (tuplesize > 1) { 
      int j=0;
      for (int i=0; i<num_atoms; i++) { 
        if (flgs[i])
          list[i] = PyString_AsString(PyTuple_GET_ITEM(val, j++));
      }
    } else {
      for (int i=0; i<num_atoms; i++) {
        if (flgs[i])
          list[i] = PyString_AsString(PyTuple_GET_ITEM(val, 0));
      }
    }
    elem->set_keyword_string(&context, num_atoms, list, flgs);
    delete [] list;
  }

  // Recompute the color assignments if certain atom attributes are changed.
  if (!strcmp(attr, "name") ||
      !strcmp(attr, "type") ||
      !strcmp(attr, "resname") ||
      !strcmp(attr, "chain") ||
      !strcmp(attr, "segid") ||
      !strcmp(attr, "segname")) 
    app->moleculeList->add_color_names(molid);

  mol->force_recalc(DrawMolItem::SEL_REGEN | DrawMolItem::COL_REGEN); 
  delete [] flgs;
  Py_INCREF(Py_None);
  return Py_None;
}
Пример #29
0
static PyObject *Nuitka_Frame_getlocals(struct Nuitka_FrameObject *frame, void *closure) {
    if (frame->m_type_description == NULL) {
        if (frame->m_frame.f_locals == NULL) {
            frame->m_frame.f_locals = PyDict_New();
        }

        Py_INCREF(frame->m_frame.f_locals);
        return frame->m_frame.f_locals;
    } else {
        PyObject *result = PyDict_New();
        PyObject **varnames = &PyTuple_GET_ITEM(frame->m_frame.f_code->co_varnames, 0);

        char const *w = frame->m_type_description;
        char const *t = frame->m_locals_storage;

        while (*w != 0) {
            switch (*w) {
            case NUITKA_TYPE_DESCRIPTION_OBJECT:
            case NUITKA_TYPE_DESCRIPTION_OBJECT_PTR: {
                PyObject *value = *(PyObject **)t;

                if (value != NULL) {
                    PyDict_SetItem(result, *varnames, value);
                }

                t += sizeof(value);

                break;
            }
            case NUITKA_TYPE_DESCRIPTION_CELL: {
                struct Nuitka_CellObject *value = *(struct Nuitka_CellObject **)t;
                PyDict_SetItem(result, *varnames, value->ob_ref);
                t += sizeof(value);

                break;
            }
            case NUITKA_TYPE_DESCRIPTION_NULL: {
                t += sizeof(void *);
                break;
            }
            case NUITKA_TYPE_DESCRIPTION_BOOL: {
                int value = *(int *)t;
                t += sizeof(int);
                switch ((nuitka_bool)value) {
                case NUITKA_BOOL_TRUE: {
                    PyDict_SetItem(result, *varnames, Py_True);
                    break;
                }
                case NUITKA_BOOL_FALSE: {
                    PyDict_SetItem(result, *varnames, Py_False);
                    break;
                }
                default:
                    break;
                }
                break;
            }
            default:
                assert(false);
            }

            w += 1;
            varnames += 1;
        }

        return result;
    }
}
Пример #30
0
static void mod_vptuple(TALLOC_CTX *ctx, VALUE_PAIR **vps, PyObject *pValue,
			char const *funcname)
{
	int	     i;
	int	     tuplesize;
	VALUE_PAIR      *vp;

	/*
	 *	If the Python function gave us None for the tuple,
	 *	then just return.
	 */
	if (pValue == Py_None)
		return;

	if (!PyTuple_CheckExact(pValue)) {
		ERROR("rlm_python:%s: non-tuple passed", funcname);
		return;
	}
	/* Get the tuple tuplesize. */
	tuplesize = PyTuple_GET_SIZE(pValue);
	for (i = 0; i < tuplesize; i++) {
		PyObject *pTupleElement = PyTuple_GET_ITEM(pValue, i);
		PyObject *pStr1;
		PyObject *pStr2;
		PyObject *pOp;
		int pairsize;
		char const *s1;
		char const *s2;
		long op;

		if (!PyTuple_CheckExact(pTupleElement)) {
			ERROR("rlm_python:%s: tuple element %d is not a tuple", funcname, i);
			continue;
		}
		/* Check if it's a pair */

		pairsize = PyTuple_GET_SIZE(pTupleElement);
		if ((pairsize < 2) || (pairsize > 3)) {
			ERROR("rlm_python:%s: tuple element %d is a tuple of size %d. Must be 2 or 3.", funcname, i, pairsize);
			continue;
		}

		if (pairsize == 2) {
			pStr1	= PyTuple_GET_ITEM(pTupleElement, 0);
			pStr2	= PyTuple_GET_ITEM(pTupleElement, 1);
			op	= T_OP_EQ;
		} else {
			pStr1	= PyTuple_GET_ITEM(pTupleElement, 0);
			pStr2	= PyTuple_GET_ITEM(pTupleElement, 2);
			pOp	= PyTuple_GET_ITEM(pTupleElement, 1);
			op	= PyInt_AsLong(pOp);
		}

		if ((!PyString_CheckExact(pStr1)) || (!PyString_CheckExact(pStr2))) {
			ERROR("rlm_python:%s: tuple element %d must be as (str, str)", funcname, i);
			continue;
		}
		s1 = PyString_AsString(pStr1);
		s2 = PyString_AsString(pStr2);
		vp = pairmake(ctx, vps, s1, s2, op);
		if (vp != NULL) {
			DEBUG("rlm_python:%s: '%s' = '%s'", funcname, s1, s2);
		} else {
			DEBUG("rlm_python:%s: Failed: '%s' = '%s'", funcname, s1, s2);
		}
	}
}