static PyObject * islice_next(isliceobject *lz) { PyObject *item; PyObject *it = lz->it; long oldnext; while (lz->cnt < lz->next) { assert(PyIter_Check(it)); item = (*it->ob_type->tp_iternext)(it); if (item == NULL) return NULL; Py_DECREF(item); lz->cnt++; } if (lz->stop != -1 && lz->cnt >= lz->stop) return NULL; assert(PyIter_Check(it)); item = (*it->ob_type->tp_iternext)(it); if (item == NULL) return NULL; lz->cnt++; oldnext = lz->next; lz->next += lz->step; if (lz->next < oldnext) /* Check for overflow */ lz->next = lz->stop; return item; }
static PyObject * dropwhile_next(dropwhileobject *lz) { PyObject *item, *good; PyObject *it = lz->it; long ok; for (;;) { assert(PyIter_Check(it)); item = (*it->ob_type->tp_iternext)(it); if (item == NULL) return NULL; if (lz->start == 1) return item; good = PyObject_CallFunctionObjArgs(lz->func, item, NULL); if (good == NULL) { Py_DECREF(item); return NULL; } ok = PyObject_IsTrue(good); Py_DECREF(good); if (!ok) { lz->start = 1; return item; } Py_DECREF(item); } }
static PyObject * takewhile_next(takewhileobject *lz) { PyObject *item, *good; PyObject *it = lz->it; long ok; if (lz->stop == 1) return NULL; assert(PyIter_Check(it)); item = (*it->ob_type->tp_iternext)(it); if (item == NULL) return NULL; good = PyObject_CallFunctionObjArgs(lz->func, item, NULL); if (good == NULL) { Py_DECREF(item); return NULL; } ok = PyObject_IsTrue(good); Py_DECREF(good); if (ok) return item; Py_DECREF(item); lz->stop = 1; return NULL; }
PyObject* py_timing_bloom_add(PyObject* self, PyObject* args) { PyArrayObject* data; PyObject* indexes; uint8_t tick; if (!PyArg_ParseTuple(args, "OOB", &data, &indexes, &tick)) { PyErr_SetString(PyExc_RuntimeError, "Invalid arguments"); return NULL; } if (!PyArray_Check(data) || !PyArray_ISCONTIGUOUS(data)) { PyErr_SetString(PyExc_RuntimeError,"inputted data not in the correct format"); return NULL; } if (!PyIter_Check(indexes)) { PyErr_SetString(PyExc_RuntimeError,"indexes argument must be an iterator"); return NULL; } uint8_t *values = PyArray_DATA(data); uint8_t temp, n; int num_non_zero = 0; PyObject *pyindex; long index, access_index; while ((pyindex = PyIter_Next(indexes)) != NULL) { index = PyInt_AsLong(pyindex); Py_DECREF(pyindex); access_index = index / 2; n = values[access_index]; if (index % 2 == 0) { temp = (n & 0xf0) >> 4; n = ((tick << 4) & 0xf0) + (n & 0x0f); } else {
static PyObject * thunk_next(thunk *self) { PyObject *tmp; PyObject *ret; if (!(tmp = _strict_eval_borrowed((PyObject*) self))) { return NULL; } if (!PyIter_Check(tmp)) { PyErr_Format(PyExc_TypeError, "'%s' object is not an iterator'", Py_TYPE(tmp)->tp_name); return NULL; } if (!(tmp = PyIter_Next(tmp)) || PyErr_Occurred()) { return NULL; } ret = thunk_fromvalue(Py_TYPE(self), tmp); Py_DECREF(tmp); return ret; }
static int PyBobLearnMLPMachine_setBiases (PyBobLearnMLPMachineObject* self, PyObject* biases, void* /*closure*/) { if (PyBob_NumberCheck(biases)){ double v = PyFloat_AsDouble(biases); if (PyErr_Occurred()) return -1; self->cxx->setBiases(v); return 0; } if (!PyIter_Check(biases) && !PySequence_Check(biases)) { PyErr_Format(PyExc_TypeError, "setting attribute `biases' of `%s' requires either a float or an iterable, but you passed `%s' which does not implement the iterator protocol", Py_TYPE(self)->tp_name, Py_TYPE(biases)->tp_name); return -1; } /* Checks and converts all entries */ std::vector<blitz::Array<double,1> > biases_seq; std::vector<boost::shared_ptr<PyBlitzArrayObject>> biases_seq_; PyObject* iterator = PyObject_GetIter(biases); if (!iterator) return -1; auto iterator_ = make_safe(iterator); while (PyObject* item = PyIter_Next(iterator)) { auto item_ = make_safe(item); PyBlitzArrayObject* bz = 0; if (!PyBlitzArray_Converter(item, &bz)) { PyErr_Format(PyExc_TypeError, "`%s' could not convert object of type `%s' at position %" PY_FORMAT_SIZE_T "d of input sequence into an array - check your input", Py_TYPE(self)->tp_name, Py_TYPE(item)->tp_name, biases_seq.size()); return -1; } if (bz->ndim != 1 || bz->type_num != NPY_FLOAT64) { PyErr_Format(PyExc_TypeError, "`%s' only supports 1D 64-bit float arrays for attribute `biases' (or any other object coercible to that), but at position %" PY_FORMAT_SIZE_T "d I have found an object with %" PY_FORMAT_SIZE_T "d dimensions and with type `%s' which is not compatible - check your input", Py_TYPE(self)->tp_name, biases_seq.size(), bz->ndim, PyBlitzArray_TypenumAsString(bz->type_num)); Py_DECREF(bz); return -1; } biases_seq_.push_back(make_safe(bz)); ///< prevents data deletion biases_seq.push_back(*PyBlitzArrayCxx_AsBlitz<double,1>(bz)); ///< only a view! } if (PyErr_Occurred()) return -1; try { self->cxx->setBiases(biases_seq); } catch (std::exception& ex) { PyErr_SetString(PyExc_RuntimeError, ex.what()); return -1; } catch (...) { PyErr_Format(PyExc_RuntimeError, "cannot reset `biases' of %s: unknown exception caught", Py_TYPE(self)->tp_name); return -1; } return 0; }
static PyObject * ifilterfalse_next(ifilterfalseobject *lz) { PyObject *item; PyObject *it = lz->it; long ok; for (;;) { assert(PyIter_Check(it)); item = (*it->ob_type->tp_iternext)(it); if (item == NULL) return NULL; if (lz->func == Py_None) { ok = PyObject_IsTrue(item); } else { PyObject *good; good = PyObject_CallFunctionObjArgs(lz->func, item, NULL); if (good == NULL) { Py_DECREF(item); return NULL; } ok = PyObject_IsTrue(good); Py_DECREF(good); } if (!ok) return item; Py_DECREF(item); } }
static PyObject * izip_next(izipobject *lz) { int i; long tuplesize = lz->tuplesize; PyObject *result = lz->result; PyObject *it; PyObject *item; PyObject *olditem; if (tuplesize == 0) return NULL; if (result->ob_refcnt == 1) { Py_INCREF(result); for (i=0 ; i < tuplesize ; i++) { it = PyTuple_GET_ITEM(lz->ittuple, i); assert(PyIter_Check(it)); item = (*it->ob_type->tp_iternext)(it); if (item == NULL) { Py_DECREF(result); return NULL; } olditem = PyTuple_GET_ITEM(result, i); PyTuple_SET_ITEM(result, i, item); Py_DECREF(olditem); } } else { result = PyTuple_New(tuplesize); if (result == NULL) return NULL; for (i=0 ; i < tuplesize ; i++) { it = PyTuple_GET_ITEM(lz->ittuple, i); assert(PyIter_Check(it)); item = (*it->ob_type->tp_iternext)(it); if (item == NULL) { Py_DECREF(result); return NULL; } PyTuple_SET_ITEM(result, i, item); } } return result; }
/* * This helper function returns an awaitable for `o`: * - `o` if `o` is a coroutine-object; * - `type(o)->tp_as_async->am_await(o)` * * Raises a TypeError if it's not possible to return * an awaitable and returns NULL. */ PyObject * _PyGen_GetAwaitableIter(PyObject *o) { unaryfunc getter = NULL; PyTypeObject *ot; if (PyGen_CheckCoroutineExact(o)) { /* Fast path. It's a central function for 'await'. */ Py_INCREF(o); return o; } ot = Py_TYPE(o); if (ot->tp_as_async != NULL) { getter = ot->tp_as_async->am_await; } if (getter != NULL) { PyObject *res = (*getter)(o); if (res != NULL) { if (!PyIter_Check(res)) { PyErr_Format(PyExc_TypeError, "__await__() returned non-iterator " "of type '%.100s'", Py_TYPE(res)->tp_name); Py_CLEAR(res); } else { if (PyGen_CheckCoroutineExact(res)) { /* __await__ must return an *iterator*, not a coroutine or another awaitable (see PEP 492) */ PyErr_SetString(PyExc_TypeError, "__await__() returned a coroutine"); Py_CLEAR(res); } } } return res; } PyErr_Format(PyExc_TypeError, "object %.100s can't be used in 'await' expression", ot->tp_name); return NULL; }
static PyObject * starmap_next(starmapobject *lz) { PyObject *args; PyObject *result; PyObject *it = lz->it; assert(PyIter_Check(it)); args = (*it->ob_type->tp_iternext)(it); if (args == NULL) return NULL; if (!PyTuple_CheckExact(args)) { Py_DECREF(args); PyErr_SetString(PyExc_TypeError, "iterator must return a tuple"); return NULL; } result = PyObject_Call(lz->func, args, NULL); Py_DECREF(args); return result; }
static int load_rows(PyObj self, PyObj row_iter, uint32 *total) { MemoryContext former = CurrentMemoryContext; volatile PyObj row = NULL; Datum *datums; bool *nulls; char *cnulls; int r = 0; SPIPlanPtr plan; Assert(!ext_state); Assert(PyIter_Check(row_iter)); plan = PyPgStatement_GetPlan(self); if (plan == NULL) return(-1); PG_TRY(); { PyObj tdo = PyPgStatement_GetInput(self); PyObj typs = PyPgTupleDesc_GetTypesTuple(tdo); PyObj namemap = PyPgTupleDesc_GetNameMap(tdo); TupleDesc td = PyPgTupleDesc_GetTupleDesc(tdo); int rnatts = PyPgTupleDesc_GetNatts(tdo); int *freemap = PyPgTupleDesc_GetFreeMap(tdo); int spi_r; datums = palloc(sizeof(Datum) * td->natts); nulls = palloc(sizeof(bool) * td->natts); cnulls = palloc(sizeof(char) * td->natts); while ((row = PyIter_Next(row_iter))) { PyObj pargs; pargs = Py_NormalizeRow(rnatts, td, namemap, row); Py_DECREF(row); if (pargs == NULL) { r = -1; break; } row = pargs; Py_BuildDatumsAndNulls(td, typs, row, datums, nulls); Py_DECREF(row); row = NULL; /* borrow spi_r for a moment */ for (spi_r = 0; spi_r < td->natts; ++spi_r) { cnulls[spi_r] = nulls[spi_r] ? 'n' : ' '; } spi_r = SPI_execute_plan(plan, datums, cnulls, false, 1); /* * Free the built datums. */ FreeReferences(freemap, datums, nulls); if (spi_r < 0) raise_spi_error(spi_r); *total = *total + SPI_processed; } pfree(datums); pfree(nulls); pfree(cnulls); } PG_CATCH(); { /* * WARNING: Leaks datums & nulls on error. Yay, procCxt. */ PyErr_SetPgError(false); Py_XDECREF(row); r = -1; } PG_END_TRY(); MemoryContextSwitchTo(former); return(r); }
// originally copied from Py3's builtin_next() static CYTHON_INLINE PyObject *__Pyx_PyIter_Next2(PyObject* iterator, PyObject* defval) { PyObject* next; iternextfunc iternext = Py_TYPE(iterator)->tp_iternext; #if CYTHON_COMPILING_IN_CPYTHON if (unlikely(!iternext)) { #else if (unlikely(!iternext) || unlikely(!PyIter_Check(iterator))) { #endif PyErr_Format(PyExc_TypeError, "%.200s object is not an iterator", Py_TYPE(iterator)->tp_name); return NULL; } next = iternext(iterator); if (likely(next)) return next; #if CYTHON_COMPILING_IN_CPYTHON #if PY_VERSION_HEX >= 0x03010000 || (PY_MAJOR_VERSION < 3 && PY_VERSION_HEX >= 0x02070000) if (unlikely(iternext == &_PyObject_NextNotImplemented)) return NULL; #endif #endif if (defval) { PyObject* exc_type = PyErr_Occurred(); if (exc_type) { if (unlikely(exc_type != PyExc_StopIteration) && !PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)) return NULL; PyErr_Clear(); } Py_INCREF(defval); return defval; } if (!PyErr_Occurred()) PyErr_SetNone(PyExc_StopIteration); return NULL; } /////////////// IterFinish.proto /////////////// static CYTHON_INLINE int __Pyx_IterFinish(void); /*proto*/ /////////////// IterFinish /////////////// // When PyIter_Next(iter) has returned NULL in order to signal termination, // this function does the right cleanup and returns 0 on success. If it // detects an error that occurred in the iterator, it returns -1. static CYTHON_INLINE int __Pyx_IterFinish(void) { #if CYTHON_COMPILING_IN_CPYTHON PyThreadState *tstate = PyThreadState_GET(); PyObject* exc_type = tstate->curexc_type; if (unlikely(exc_type)) { if (likely(exc_type == PyExc_StopIteration) || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)) { PyObject *exc_value, *exc_tb; exc_value = tstate->curexc_value; exc_tb = tstate->curexc_traceback; tstate->curexc_type = 0; tstate->curexc_value = 0; tstate->curexc_traceback = 0; Py_DECREF(exc_type); Py_XDECREF(exc_value); Py_XDECREF(exc_tb); return 0; } else { return -1; } } return 0; #else if (unlikely(PyErr_Occurred())) { if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) { PyErr_Clear(); return 0; } else { return -1; } } return 0; #endif }
void Object_beginTypeContext (JSOBJ _obj, JSONTypeContext *tc) { PyObject *obj, *exc, *toDictFunc, *iter; TypeContext *pc; PRINTMARK(); if (!_obj) { tc->type = JT_INVALID; return; } obj = (PyObject*) _obj; pc = (TypeContext *) tc->prv; if (!pc) { tc->type = JT_INVALID; PyErr_NoMemory(); return; } pc->newObj = NULL; pc->dictObj = NULL; pc->itemValue = NULL; pc->itemName = NULL; pc->iterator = NULL; pc->attrList = NULL; pc->index = 0; pc->size = 0; pc->longValue = 0; if (PyIter_Check(obj)) { PRINTMARK(); goto ISITERABLE; } if (PyBool_Check(obj)) { PRINTMARK(); tc->type = (obj == Py_True) ? JT_TRUE : JT_FALSE; return; } else if (PyLong_Check(obj)) { PRINTMARK(); pc->PyTypeToJSON = PyLongToINT64; tc->type = JT_LONG; GET_TC(tc)->longValue = PyLong_AsLongLong(obj); exc = PyErr_Occurred(); if (exc && PyErr_ExceptionMatches(PyExc_OverflowError)) { PRINTMARK(); goto INVALID; } return; } else if (PyInt_Check(obj)) { PRINTMARK(); #ifdef _LP64 pc->PyTypeToJSON = PyIntToINT64; tc->type = JT_LONG; #else pc->PyTypeToJSON = PyIntToINT32; tc->type = JT_INT; #endif return; } else if (PyString_Check(obj)) { PRINTMARK(); pc->PyTypeToJSON = PyStringToUTF8; tc->type = JT_UTF8; return; } else if (PyUnicode_Check(obj)) { PRINTMARK(); pc->PyTypeToJSON = PyUnicodeToUTF8; tc->type = JT_UTF8; return; } else if (PyFloat_Check(obj) || (type_decimal && PyObject_IsInstance(obj, type_decimal))) { PRINTMARK(); pc->PyTypeToJSON = PyFloatToDOUBLE; tc->type = JT_DOUBLE; return; } else if (PyDateTime_Check(obj)) { PRINTMARK(); pc->PyTypeToJSON = PyDateTimeToINT64; tc->type = JT_LONG; return; } else if (PyDate_Check(obj)) { PRINTMARK(); pc->PyTypeToJSON = PyDateToINT64; tc->type = JT_LONG; return; } else if (obj == Py_None) { PRINTMARK(); tc->type = JT_NULL; return; } ISITERABLE: if (PyDict_Check(obj)) { PRINTMARK(); tc->type = JT_OBJECT; SetupDictIter(obj, pc); Py_INCREF(obj); return; } else if (PyList_Check(obj)) { PRINTMARK(); tc->type = JT_ARRAY; pc->iterEnd = List_iterEnd; pc->iterNext = List_iterNext; pc->iterGetValue = List_iterGetValue; pc->iterGetName = List_iterGetName; GET_TC(tc)->index = 0; GET_TC(tc)->size = PyList_GET_SIZE( (PyObject *) obj); return; } else if (PyTuple_Check(obj)) { PRINTMARK(); tc->type = JT_ARRAY; pc->iterEnd = Tuple_iterEnd; pc->iterNext = Tuple_iterNext; pc->iterGetValue = Tuple_iterGetValue; pc->iterGetName = Tuple_iterGetName; GET_TC(tc)->index = 0; GET_TC(tc)->size = PyTuple_GET_SIZE( (PyObject *) obj); GET_TC(tc)->itemValue = NULL; return; } /* else if (PyAnySet_Check(obj)) { PRINTMARK(); tc->type = JT_ARRAY; pc->iterBegin = NULL; pc->iterEnd = Iter_iterEnd; pc->iterNext = Iter_iterNext; pc->iterGetValue = Iter_iterGetValue; pc->iterGetName = Iter_iterGetName; return; } */ toDictFunc = PyObject_GetAttrString(obj, "toDict"); if (toDictFunc) { PyObject* tuple = PyTuple_New(0); PyObject* toDictResult = PyObject_Call(toDictFunc, tuple, NULL); Py_DECREF(tuple); Py_DECREF(toDictFunc); if (toDictResult == NULL) { PyErr_Clear(); tc->type = JT_NULL; return; } if (!PyDict_Check(toDictResult)) { Py_DECREF(toDictResult); tc->type = JT_NULL; return; } PRINTMARK(); tc->type = JT_OBJECT; SetupDictIter(toDictResult, pc); return; } PRINTMARK(); PyErr_Clear(); iter = PyObject_GetIter(obj); if (iter != NULL) { PRINTMARK(); tc->type = JT_ARRAY; pc->iterator = iter; pc->iterEnd = Iter_iterEnd; pc->iterNext = Iter_iterNext; pc->iterGetValue = Iter_iterGetValue; pc->iterGetName = Iter_iterGetName; return; } PRINTMARK(); PyErr_Clear(); PRINTMARK(); tc->type = JT_OBJECT; GET_TC(tc)->attrList = PyObject_Dir(obj); if (GET_TC(tc)->attrList == NULL) { PyErr_Clear(); goto INVALID; } GET_TC(tc)->index = 0; GET_TC(tc)->size = PyList_GET_SIZE(GET_TC(tc)->attrList); PRINTMARK(); pc->iterEnd = Dir_iterEnd; pc->iterNext = Dir_iterNext; pc->iterGetValue = Dir_iterGetValue; pc->iterGetName = Dir_iterGetName; return; INVALID: PRINTMARK(); tc->type = JT_INVALID; PyObject_Free(tc->prv); tc->prv = NULL; return; }
/* This is the write call back registered within the event loop */ void write_cb(struct ev_loop *loop, struct ev_io *w, int revents) { char response[1024]; int stop=0; //0: not stop, 1: stop, 2: stop and call tp close int ret; //python_handler return struct client *cli= ((struct client*) (((char*)w) - offsetof(struct client,ev_write))); if (cli->response_iter_sent==-2) { //we must send an header or an error ret=python_handler(cli); //look for python callback and execute it if (ret==0) //look for python callback and execute it { //uri not found snprintf(response, sizeof(response), "HTTP/1.0 500 Not found\r\nContent-Type: text/html\r\nServer: %s\r\n\r\n<html><head><title>Page not found</title></head><body><p>Page not found!!!</p></body></html>", VERSION ); if (response) write_cli(cli,response, strlen(response), revents); else printf("problem with error 500: Page not found\n"); stop=1; } else if (ret==-411) { snprintf(response, sizeof(response), "HTTP/1.0 411 Length Required\r\nContent-Type: text/html\r\nServer: %s\r\n\r\n<html><head><title>Length Required</head><body><p>Length Required!!!</p></body></html>", VERSION); if (response) write_cli(cli,response, strlen(response), revents); else printf("problem with error 411\n"); stop=1; } else if (ret==-500) { snprintf(response, sizeof(response), "HTTP/1.0 500 Internal Server Error\r\nContent-Type: text/html\r\nServer: %s\r\n\r\n<html><head><title>Internal Server Error</title></head><body><p>Internal Server Error!!!</p></body></html>", VERSION); if (response) write_cli(cli,response, strlen(response), revents); else printf("problem with error 500: Internal server error\n"); stop=1; } else if (ret==-501) { //problem to parse the request snprintf(response,sizeof(response), "HTTP/1.0 501 Not Implemented\r\nContent-Type: text/html\r\nServer: %s\r\n\r\n<html><head><title>Not Implemented</head><body><p>Not Implemented!!!</p></body></html>", VERSION); if (response) write_cli(cli,response, strlen(response), revents); else printf("problem with error 501\n"); stop=1; } else { //uri found, we thus send the html header write_cli(cli, cli->response_header, cli->response_header_length, revents); cli->response_iter_sent++; //-1: header sent } } else if (strcmp(cli->cmd,"HEAD")==0) { //we don't send additonal data for a HEAD command stop=2; } else { //we let the python developer to manage other HTTP command if (((PyList_Check(cli->response_content))||(PyTuple_Check(cli->response_content))) && (cli->response_content_obj==NULL)) //we treat list object { int tuple = PyTuple_Check(cli->response_content); cli->response_iter_sent++; if (cli->response_iter_sent<(tuple ? PyTuple_Size(cli->response_content) : PyList_Size(cli->response_content))) { PyObject *pydummy = tuple ? PyTuple_GetItem(cli->response_content, cli->response_iter_sent) : PyList_GetItem(cli->response_content, cli->response_iter_sent); char *buff; #if (PY_VERSION_HEX < 0x02050000) int buflen; if (PyObject_AsReadBuffer(pydummy, (const void **) &buff, &buflen)==0) #else Py_ssize_t buflen; if (PyObject_AsReadBuffer(pydummy, (const void **) &buff, &buflen)==0) #endif { // if this is a readable buffer, we send it. Other else, we ignore it. if (write_cli(cli, buff, buflen, revents)==0) { cli->response_iter_sent = tuple ? PyTuple_Size(cli->response_content) : PyList_Size(cli->response_content); //break the for loop } } else { printf("The item %i of your list is not a string!!!! It will be skipped\n",cli->response_iter_sent); } } else // all iterations has been sent { stop=2; } } else if (PyFile_Check(cli->response_content) && (cli->response_content_obj==NULL)) // we treat file object { if (cli->response_iter_sent==-1) // we need to initialise the file descriptor { cli->response_fp=PyFile_AsFile(cli->response_content); } cli->response_iter_sent++; char buff[MAX_BUFF]=""; size_t len=fread(buff, sizeof(char), MAX_BUFF, cli->response_fp); if ((int)len==0) { stop=2; } else { if (write_cli(cli,buff, len, revents)==0) { stop=2; } if ((int)len<MAX_BUFF) { //we have send the whole file stop=2; } } //free(buff); } else if ((cli->response_content_obj!=NULL) && (PyIter_Check(cli->response_content_obj))) { //we treat Iterator object cli->response_iter_sent++; PyObject *pyelem = cli->response_content; if (pyelem == NULL) { stop = 2; } else { char *buff; #if (PY_VERSION_HEX < 0x02050000) int buflen; if (PyObject_AsReadBuffer(pyelem, (const void **) &buff, &buflen)==0) #else Py_ssize_t buflen; if (PyObject_AsReadBuffer(pyelem, (const void **) &buff, &buflen)==0) #endif { // if this is a readable buffer, we send it. Other else, we ignore it. if (write_cli(cli, buff, buflen, revents)==0) { stop=2; //break the iterator loop } } else { printf("The item %i of your iterator is not a string!!!! It will be skipped\n",cli->response_iter_sent); } Py_DECREF(pyelem); cli->response_content = PyIter_Next(cli->response_content_obj); if (cli->response_content==NULL) { if (debug) { printf("host=%s,port=%i iterator ended uri=%s\n", cli->remote_addr, cli->remote_port, cli->uri ); } stop=2; } } } else { printf("wsgi output of is neither a list, neither a fileobject, neither an iterable object!!!!!\n"); //PyErr_SetString(PyExc_TypeError, "Result must be a list, a fileobject or an iterable object"); stop=1; } }// end of GET OR POST request if (stop==2) { if (cli->response_content!=NULL) { if (PyObject_HasAttrString(cli->response_content, "close")) { PyObject *pydummy=PyObject_GetAttrString(cli->response_content, "close"); PyObject_CallFunction(pydummy, NULL); Py_DECREF(pydummy); } } ev_io_stop(EV_A_ w); close_connection(cli); } if (stop==1) { ev_io_stop(EV_A_ w); close_connection(cli); } }
/* This is the main python handler that will transform and treat the client html request. return 1 if we have found a python object to treat the requested uri return 0 if not (page not found) return -1 in case of problem return -2 in case the request command is not implemented */ int python_handler(struct client *cli) { PyObject *pydict, *pydummy; int ret; if (debug) printf("host=%s,port=%i:python_handler:HEADER:\n%s**\n", cli->remote_addr, cli->remote_port, cli->input_header); // 1)initialise environ PyObject *pyenviron_class=PyObject_GetAttrString(py_base_module, "Environ"); if (!pyenviron_class) { printf("load Environ failed from base module"); exit(1); } PyObject *pyenviron=PyObject_CallObject(pyenviron_class, NULL); if (!pyenviron) { printf("Failed to create an instance of Environ"); exit(1); } Py_DECREF(pyenviron_class); // 2)transform headers into a dictionary and send it to environ.update_headers pydict=header_to_dict(cli); if (pydict==Py_None) { Py_DECREF(pyenviron); return -500; } update_environ(pyenviron, pydict, "update_headers"); Py_DECREF(pydict); // 2bis) we check if the request method is supported PyObject *pysupportedhttpcmd = PyObject_GetAttrString(py_base_module, "supported_HTTP_command"); if (cli->cmd==NULL) pydummy=Py_None; else pydummy = PyString_FromString(cli->cmd); if (PySequence_Contains(pysupportedhttpcmd,pydummy)!=1) { //return not implemented Py_DECREF(pysupportedhttpcmd); Py_DECREF(pydummy); Py_DECREF(pyenviron); return -501; } Py_DECREF(pydummy); // 2ter) we treat directly the OPTIONS command if (strcmp(cli->cmd,"OPTIONS")==0) { pydummy=PyString_FromFormat("HTTP/1.0 200 OK\r\nServer: %s\r\nAllow: ", VERSION) ; PyObject *pyitem; int index, max; max = PyList_Size(pysupportedhttpcmd); for (index=0; index<max; index++) { pyitem=PyList_GetItem(pysupportedhttpcmd, index); // no need to decref pyitem PyString_Concat(&pydummy, PyObject_Str(pyitem)); if (index<max-1) PyString_Concat(&pydummy, PyString_FromString(", ")); } PyString_Concat(&pydummy, PyString_FromString("\r\nContent-Length: 0\r\n\r\n")); cli->response_header = PyString_AsString(pydummy); cli->response_header_length=(int)PyString_Size(pydummy); cli->response_content=PyList_New(0); Py_DECREF(pyenviron); return 1; } Py_DECREF(pysupportedhttpcmd); // 3)find if the uri is registered if (handle_uri(cli)!=1) { if (py_generic_cb==NULL) { //printf("uri not found\n"); Py_DECREF(pyenviron); return 0; } else { cli->wsgi_cb=py_generic_cb; Py_INCREF(cli->wsgi_cb); cli->uri_path=(char *)calloc(1, sizeof(char)); strcpy(cli->uri_path,""); } } // 4) build path_info, ... pydict=py_build_method_variables(cli); update_environ(pyenviron, pydict, "update_uri"); Py_DECREF(pydict); // 5) in case of POST, put it into the wsgi.input if (strcmp(cli->cmd,"POST")==0) { ret=manage_header_body(cli, pyenviron); if (ret < 0) { return ret; } } // 6) add some request info pydict=py_get_request_info(cli); update_environ(pyenviron, pydict, "update_from_request"); Py_DECREF(pydict); // 7) build response object PyObject *pystart_response_class=PyObject_GetAttrString(py_base_module, "Start_response"); PyObject *pystart_response=PyInstance_New(pystart_response_class, NULL, NULL); Py_DECREF(pystart_response_class); if (PyErr_Occurred()) { PyErr_Print(); return -500; } // 7b) add the current date to the response object PyObject *py_response_header=PyObject_GetAttrString(pystart_response,"response_headers"); char *sftime; sftime=cur_time_rfc1123(); pydummy = PyString_FromString(sftime); PyDict_SetItemString(py_response_header, "Date", pydummy); Py_DECREF(pydummy); Py_DECREF(py_response_header); free(sftime); pydummy = PyString_FromString(VERSION); PyDict_SetItemString(py_response_header, "Server", pydummy); Py_DECREF(pydummy); // 8) execute python callbacks with his parameters PyObject *pyarglist = Py_BuildValue("(OO)", pyenviron, pystart_response ); cli->response_content = PyEval_CallObject(cli->wsgi_cb,pyarglist); if (cli->response_content!=NULL) { if ((PyFile_Check(cli->response_content)==0) && (PyIter_Check(cli->response_content)==1)) { //This is an Iterator object. We have to execute it first cli->response_content_obj = cli->response_content; cli->response_content = PyIter_Next(cli->response_content_obj); } } Py_DECREF(pyarglist); Py_XDECREF(cli->wsgi_cb); if (cli->response_content!=NULL) { PyObject *pydummy = PyObject_Str(pystart_response); cli->response_header = PyString_AsString(pydummy); cli->response_header_length = (int)PyString_Size(pydummy); Py_DECREF(pydummy); } else //python call return is NULL { printf("Python error!!!\n"); char buff[200]; sprintf(buff, "HTTP/1.0 500 Not found\r\nContent-Type: text/html\r\nServer: %s* \r\n\r\n", VERSION); cli->response_header = buff; if (cli->response_header == NULL) { printf("ERROR!!!! Memory allocation error in the Python error handling procedure\n"); cli->response_header_length=0; goto leave_python_handler; } cli->response_header_length=strlen(cli->response_header); if (PyErr_Occurred()) { //get_traceback();py_b PyObject *pyerrormsg_method=PyObject_GetAttrString(py_base_module,"redirectStdErr"); PyObject *pyerrormsg=PyObject_CallFunction(pyerrormsg_method, NULL); Py_DECREF(pyerrormsg_method); Py_DECREF(pyerrormsg); PyErr_Print(); PyObject *pysys=PyObject_GetAttrString(py_base_module,"sys"); PyObject *pystderr=PyObject_GetAttrString(pysys,"stderr"); Py_DECREF(pysys); PyObject *pygetvalue=PyObject_GetAttrString(pystderr, "getvalue"); Py_DECREF(pystderr); PyObject *pyres=PyObject_CallFunction(pygetvalue, NULL); Py_DECREF(pygetvalue); printf("%s\n", PyString_AsString(pyres)); //test if we must send it to the page PyObject *pysendtraceback = PyObject_GetAttrString(py_config_module,"send_traceback_to_browser"); cli->response_content=PyList_New(0); if (pysendtraceback==Py_True) { pydummy = PyString_FromString("<h1>Error</h1><pre>"); PyList_Append(cli->response_content, pydummy ); Py_DECREF(pydummy); PyList_Append(cli->response_content, pyres); pydummy = PyString_FromString("</pre>"); PyList_Append(cli->response_content, pydummy); Py_DECREF(pydummy); } else { PyObject *pyshortmsg = PyObject_GetAttrString(py_config_module,"send_traceback_short"); PyList_Append(cli->response_content, pyshortmsg); Py_DECREF(pyshortmsg); } Py_DECREF(pyres); Py_DECREF(pysendtraceback); } else { cli->response_content=PyList_New(0); pydummy = PyString_FromString("Page not found."); PyList_Append(cli->response_content, pydummy ); Py_DECREF(pydummy); } } leave_python_handler: Py_XDECREF(pystart_response); Py_XDECREF(pyenviron); return 1; }
static PyObject * transpose(PyObject *self,PyObject *obj) { int i; Py_ssize_t nrow; Py_ssize_t ncol = L_UNKNOWN, currow = 0; PyObject * res = NULL, * tmp; PyObject * iter = NULL; PyObject *item = NULL; if(PyArray_Check(obj)) { Py_INCREF(obj); return obj; } if(!PySequence_Check(obj)) { PyErr_SetString(PyExc_TypeError,"argument should be a sequence"); return NULL; } nrow = PySequence_Length(obj); if(nrow == L_UNKNOWN) return NULL; if(nrow == 0) { Py_INCREF(obj); return obj; } iter = PyObject_GetIter(obj); if(iter == NULL || PyErr_Occurred() || !PyIter_Check(iter)) return NULL; while((item = PyIter_Next(iter))) { if(ncol == L_UNKNOWN) //initialization { if(!PySequence_Check(item)) { PyErr_SetString(PyExc_TypeError,"argument should be a nested sequence"); goto error; } ncol = PySequence_Length(item); if(ncol == L_UNKNOWN) goto error; res = PyTuple_New(ncol); if(res == NULL) goto error; for(i = 0; i < ncol; i++) { tmp = PyTuple_New(nrow); if(tmp == NULL) goto error; PyTuple_SET_ITEM(res,i,tmp); } } /* Special casing for speed */ if(PyTuple_Check(item)) { if(PyTuple_GET_SIZE(item) != ncol) { PyErr_SetString(PyExc_TypeError,"Nested sequences should have equal length."); goto error; } for(i = 0; i < ncol; i++) { tmp = PyTuple_GET_ITEM(item,i); Py_INCREF(tmp); PyTuple_SET_ITEM(PyTuple_GET_ITEM(res,i),currow,tmp); } } else if(PyList_Check(item)) { if(PyList_GET_SIZE(item) != ncol) { PyErr_SetString(PyExc_TypeError,"Nested sequences should have equal length."); goto error; } for(i = 0; i < ncol; i++) { tmp = PyList_GET_ITEM(item,i); Py_INCREF(tmp); PyTuple_SET_ITEM(PyTuple_GET_ITEM(res,i),currow,tmp); } } else if(PySequence_Check(item)) { if(PySequence_Length(item) != ncol) { PyErr_SetString(PyExc_TypeError,"Nested sequences should have equal length."); goto error; } for(i = 0; i < ncol; i++) { tmp = PySequence_GetItem(item,i); if(tmp == NULL) goto error; PyTuple_SET_ITEM(PyTuple_GET_ITEM(res,i),currow,tmp); } } else { PyErr_SetString(PyExc_TypeError,"argument should be a nested sequence"); goto error; } currow++; Py_DECREF(item); } Py_DECREF(iter); return res; error: Py_XDECREF(res); Py_XDECREF(item); Py_XDECREF(iter); return NULL; }
static PyObject * b_py_database_check_all_( PyObject *self, PyObject *args, PyObject *kwargs) { static char *keywords[] = {"question_classes", NULL}; PyObject *question_classes; if (!PyArg_ParseTupleAndKeywords( args, kwargs, "O", keywords, &question_classes)) { return NULL; } struct B_PyDatabase *db_py = b_py_database(self); if (!db_py) { return NULL; } struct B_QuestionVTable const **vtables; size_t vtable_count; if (PySequence_Check(question_classes)) { ssize_t length_signed = PySequence_Length(question_classes); if (length_signed == -1) { __builtin_trap(); } if (length_signed < -1) { __builtin_trap(); } vtable_count = (size_t) length_signed; // TODO(strager): Check for overflow. vtables = PyMem_Malloc(sizeof(*vtables) * vtable_count); if (!vtables) { __builtin_trap(); } for (size_t i = 0; i < vtable_count; ++i) { assert(i < SSIZE_MAX); PyObject *o = PySequence_GetItem( question_classes, (ssize_t) i); if (!PyType_Check(o)) { PyErr_SetString( PyExc_TypeError, "Expected Question type"); __builtin_trap(); } struct B_QuestionVTable const *vtable = b_py_question_class_get_native_vtable( (PyTypeObject *) o); if (!vtable) { __builtin_trap(); } vtables[i] = vtable; Py_DECREF(o); } } else if (PyIter_Check(question_classes)) { // TODO(strager) __builtin_trap(); } else { PyErr_SetString( PyExc_TypeError, "question_classes must be iterable"); return NULL; } struct B_Error e; if (!b_database_check_all( db_py->database, vtables, vtable_count, &e)) { PyMem_Free(vtables); b_py_raise(e); return NULL; } PyMem_Free(vtables); Py_RETURN_NONE; }
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; }
void Object_beginTypeContext (PyObject *obj, JSONTypeContext *tc) { TypeContext *pc = (TypeContext *) tc->prv; PyObject *toDictFunc; tc->prv[0] = 0; tc->prv[1] = 0; tc->prv[2] = 0; tc->prv[3] = 0; tc->prv[4] = 0; tc->prv[5] = 0; tc->prv[6] = 0; tc->prv[7] = 0; tc->prv[8] = 0; tc->prv[9] = 0; tc->prv[10] = 0; tc->prv[11] = 0; tc->prv[12] = 0; tc->prv[13] = 0; tc->prv[14] = 0; if (PyIter_Check(obj)) { goto ISITERABLE; } if (PyBool_Check(obj)) { PRINTMARK(); tc->type = (obj == Py_True) ? JT_TRUE : JT_FALSE; return; } else if (PyInt_Check(obj)) { PRINTMARK(); #ifdef _LP64 pc->PyTypeToJSON = PyIntToINT64; tc->type = JT_LONG; #else pc->PyTypeToJSON = PyIntToINT32; tc->type = JT_INT; #endif return; } else if (PyLong_Check(obj)) { PyObject *exc; PRINTMARK(); pc->PyTypeToJSON = PyLongToINT64; tc->type = JT_LONG; GET_TC(tc)->longValue = PyLong_AsLongLong(obj); exc = PyErr_Occurred(); if (exc && PyErr_ExceptionMatches(PyExc_OverflowError)) { PRINTMARK(); tc->type = JT_INVALID; return; } return; } else if (PyString_Check(obj)) { PRINTMARK(); pc->PyTypeToJSON = PyStringToUTF8; tc->type = JT_UTF8; return; } else if (PyUnicode_Check(obj)) { PRINTMARK(); pc->PyTypeToJSON = PyUnicodeToUTF8; tc->type = JT_UTF8; return; } else if (PyFloat_Check(obj)) { PRINTMARK(); pc->PyTypeToJSON = PyFloatToDOUBLE; tc->type = JT_DOUBLE; return; } else if (PyDateTime_Check(obj)) { PRINTMARK(); pc->PyTypeToJSON = PyDateTimeToINT64; tc->type = JT_LONG; return; } else if (PyDate_Check(obj)) { PRINTMARK(); pc->PyTypeToJSON = PyDateToINT64; tc->type = JT_LONG; return; } else if (obj == Py_None) { PRINTMARK(); tc->type = JT_NULL; return; } ISITERABLE: if (PyDict_Check(obj)) { PRINTMARK(); tc->type = JT_OBJECT; pc->iterBegin = Dict_iterBegin; pc->iterEnd = Dict_iterEnd; pc->iterNext = Dict_iterNext; pc->iterGetValue = Dict_iterGetValue; pc->iterGetName = Dict_iterGetName; pc->dictObj = obj; Py_INCREF(obj); return; } else if (PyList_Check(obj)) { PRINTMARK(); tc->type = JT_ARRAY; pc->iterBegin = List_iterBegin; pc->iterEnd = List_iterEnd; pc->iterNext = List_iterNext; pc->iterGetValue = List_iterGetValue; pc->iterGetName = List_iterGetName; return; } else if (PyTuple_Check(obj)) { PRINTMARK(); tc->type = JT_ARRAY; pc->iterBegin = Tuple_iterBegin; pc->iterEnd = Tuple_iterEnd; pc->iterNext = Tuple_iterNext; pc->iterGetValue = Tuple_iterGetValue; pc->iterGetName = Tuple_iterGetName; return; } toDictFunc = PyObject_GetAttrString(obj, "toDict"); if (toDictFunc) { PyObject* tuple = PyTuple_New(0); PyObject* toDictResult = PyObject_Call(toDictFunc, tuple, NULL); Py_DECREF(tuple); Py_DECREF(toDictFunc); if (toDictResult == NULL) { PyErr_Clear(); tc->type = JT_NULL; return; } if (!PyDict_Check(toDictResult)) { Py_DECREF(toDictResult); tc->type = JT_NULL; return; } PRINTMARK(); tc->type = JT_OBJECT; pc->iterBegin = Dict_iterBegin; pc->iterEnd = Dict_iterEnd; pc->iterNext = Dict_iterNext; pc->iterGetValue = Dict_iterGetValue; pc->iterGetName = Dict_iterGetName; pc->dictObj = toDictResult; return; } PyErr_Clear(); tc->type = JT_OBJECT; pc->iterBegin = Dir_iterBegin; pc->iterEnd = Dir_iterEnd; pc->iterNext = Dir_iterNext; pc->iterGetValue = Dir_iterGetValue; pc->iterGetName = Dir_iterGetName; return; }
/**************************** * SV* Py2Pl(PyObject *obj) * * Converts arbitrary Python data structures to Perl data structures * Note on references: does not Py_DECREF(obj). * * Modifications by Eric Wilhelm 2004-07-11 marked as elw * ****************************/ SV *Py2Pl(PyObject * const obj) { /* elw: see what python says things are */ #if PY_MAJOR_VERSION >= 3 int const is_string = PyBytes_Check(obj) || PyUnicode_Check(obj); #else int const is_string = PyString_Check(obj) || PyUnicode_Check(obj); #endif #ifdef I_PY_DEBUG PyObject *this_type = PyObject_Type(obj); /* new reference */ PyObject *t_string = PyObject_Str(this_type); /* new reference */ #if PY_MAJOR_VERSION >= 3 PyObject *type_str_bytes = PyUnicode_AsUTF8String(t_string); /* new reference */ char *type_str = PyBytes_AsString(type_str_bytes); #else char *type_str = PyString_AsString(t_string); #endif Printf(("type is %s\n", type_str)); printf("Py2Pl object:\n\t"); PyObject_Print(obj, stdout, Py_PRINT_RAW); printf("\ntype:\n\t"); PyObject_Print(this_type, stdout, Py_PRINT_RAW); printf("\n"); Printf(("String check: %i\n", is_string)); Printf(("Number check: %i\n", PyNumber_Check(obj))); Printf(("Int check: %i\n", PyInt_Check(obj))); Printf(("Long check: %i\n", PyLong_Check(obj))); Printf(("Float check: %i\n", PyFloat_Check(obj))); Printf(("Type check: %i\n", PyType_Check(obj))); #if PY_MAJOR_VERSION < 3 Printf(("Class check: %i\n", PyClass_Check(obj))); Printf(("Instance check: %i\n", PyInstance_Check(obj))); #endif Printf(("Dict check: %i\n", PyDict_Check(obj))); Printf(("Mapping check: %i\n", PyMapping_Check(obj))); Printf(("Sequence check: %i\n", PySequence_Check(obj))); Printf(("Iter check: %i\n", PyIter_Check(obj))); Printf(("Function check: %i\n", PyFunction_Check(obj))); Printf(("Module check: %i\n", PyModule_Check(obj))); Printf(("Method check: %i\n", PyMethod_Check(obj))); #if PY_MAJOR_VERSION < 3 if ((obj->ob_type->tp_flags & Py_TPFLAGS_HEAPTYPE)) printf("heaptype true\n"); if ((obj->ob_type->tp_flags & Py_TPFLAGS_HAVE_CLASS)) printf("has class\n"); #else Py_DECREF(type_str_bytes); #endif Py_DECREF(t_string); Py_DECREF(this_type); #endif /* elw: this needs to be early */ /* None (like undef) */ if (!obj || obj == Py_None) { Printf(("Py2Pl: Py_None\n")); return &PL_sv_undef; } else #ifdef EXPOSE_PERL /* unwrap Perl objects */ if (PerlObjObject_Check(obj)) { Printf(("Py2Pl: Obj_object\n")); return ((PerlObj_object *) obj)->obj; } /* unwrap Perl code refs */ else if (PerlSubObject_Check(obj)) { Printf(("Py2Pl: Sub_object\n")); SV * ref = ((PerlSub_object *) obj)->ref; if (! ref) { /* probably an inherited method */ if (! ((PerlSub_object *) obj)->obj) croak("Error: could not find a code reference or object method for PerlSub"); SV * const sub_obj = (SV*)SvRV(((PerlSub_object *) obj)->obj); HV * const pkg = SvSTASH(sub_obj); #if PY_MAJOR_VERSION >= 3 char * const sub = PyBytes_AsString(((PerlSub_object *) obj)->sub); #else PyObject *obj_sub_str = PyObject_Str(((PerlSub_object *) obj)->sub); /* new ref. */ char * const sub = PyString_AsString(obj_sub_str); #endif GV * const gv = Perl_gv_fetchmethod_autoload(aTHX_ pkg, sub, TRUE); if (gv && isGV(gv)) { ref = (SV *)GvCV(gv); } #if PY_MAJOR_VERSION < 3 Py_DECREF(obj_sub_str); #endif } return newRV_inc((SV *) ref); } else #endif /* wrap an instance of a Python class */ /* elw: here we need to make these look like instances: */ if ((obj->ob_type->tp_flags & Py_TPFLAGS_HEAPTYPE) #if PY_MAJOR_VERSION < 3 || PyInstance_Check(obj) #endif ) { /* This is a Python class instance -- bless it into an * Inline::Python::Object. If we're being called from an * Inline::Python class, it will be re-blessed into whatever * class that is. */ SV * const inst_ptr = newSViv(0); SV * const inst = newSVrv(inst_ptr, "Inline::Python::Object");; _inline_magic priv; /* set up magic */ priv.key = INLINE_MAGIC_KEY; sv_magic(inst, inst, PERL_MAGIC_ext, (char *) &priv, sizeof(priv)); MAGIC * const mg = mg_find(inst, PERL_MAGIC_ext); mg->mg_virtual = &inline_mg_vtbl; sv_setiv(inst, (IV) obj); /*SvREADONLY_on(inst); */ /* to uncomment this means I can't re-bless it */ Py_INCREF(obj); Printf(("Py2Pl: Instance. Obj: %p, inst_ptr: %p\n", obj, inst_ptr)); sv_2mortal(inst_ptr); return inst_ptr; } /* a tuple or a list */ else if (PySequence_Check(obj) && !is_string) { AV * const retval = newAV(); int i; int const sz = PySequence_Length(obj); Printf(("sequence (%i)\n", sz)); for (i = 0; i < sz; i++) { PyObject * const tmp = PySequence_GetItem(obj, i); /* new reference */ SV * const next = Py2Pl(tmp); av_push(retval, next); if (sv_isobject(next)) // needed because objects get mortalized in Py2Pl SvREFCNT_inc(next); Py_DECREF(tmp); } if (PyTuple_Check(obj)) { _inline_magic priv; priv.key = TUPLE_MAGIC_KEY; sv_magic((SV * const)retval, (SV * const)NULL, PERL_MAGIC_ext, (char *) &priv, sizeof(priv)); } return newRV_noinc((SV *) retval); } /* a dictionary or fake Mapping object */ /* elw: PyMapping_Check() now returns true for strings */ else if (! is_string && PyMapping_Check(obj)) { HV * const retval = newHV(); int i; int const sz = PyMapping_Length(obj); PyObject * const keys = PyMapping_Keys(obj); /* new reference */ PyObject * const vals = PyMapping_Values(obj); /* new reference */ Printf(("Py2Pl: dict/map\n")); Printf(("mapping (%i)\n", sz)); for (i = 0; i < sz; i++) { PyObject * const key = PySequence_GetItem(keys, i), /* new reference */ * const val = PySequence_GetItem(vals, i); /* new reference */ SV * const sv_val = Py2Pl(val); char * key_val; if (PyUnicode_Check(key)) { PyObject * const utf8_string = PyUnicode_AsUTF8String(key); /* new reference */ #if PY_MAJOR_VERSION >= 3 key_val = PyBytes_AsString(utf8_string); SV * const utf8_key = newSVpv(key_val, PyBytes_Size(utf8_string)); #else key_val = PyString_AsString(utf8_string); SV * const utf8_key = newSVpv(key_val, PyString_Size(utf8_string)); #endif SvUTF8_on(utf8_key); hv_store_ent(retval, utf8_key, sv_val, 0); Py_DECREF(utf8_string); } else { PyObject * s = NULL; #if PY_MAJOR_VERSION >= 3 PyObject * s_bytes = NULL; if (PyBytes_Check(key)) { key_val = PyBytes_AsString(key); #else if (PyString_Check(key)) { key_val = PyString_AsString(key); #endif } else { /* Warning -- encountered a non-string key value while converting a * Python dictionary into a Perl hash. Perl can only use strings as * key values. Using Python's string representation of the key as * Perl's key value. */ s = PyObject_Str(key); /* new reference */ #if PY_MAJOR_VERSION >= 3 s_bytes = PyUnicode_AsUTF8String(s); /* new reference */ key_val = PyBytes_AsString(s_bytes); #else key_val = PyString_AsString(s); #endif Py_DECREF(s); if (PL_dowarn) warn("Stringifying non-string hash key value: '%s'", key_val); } if (!key_val) { croak("Invalid key on key %i of mapping\n", i); } hv_store(retval, key_val, strlen(key_val), sv_val, 0); #if PY_MAJOR_VERSION >= 3 Py_XDECREF(s_bytes); #endif Py_XDECREF(s); } if (sv_isobject(sv_val)) // needed because objects get mortalized in Py2Pl SvREFCNT_inc(sv_val); Py_DECREF(key); Py_DECREF(val); } Py_DECREF(keys); Py_DECREF(vals); return newRV_noinc((SV *) retval); } /* a boolean */ else if (PyBool_Check(obj)) {
void Object_beginTypeContext (JSOBJ _obj, JSONTypeContext *tc) { PyObject *obj, *exc, *toDictFunc; TypeContext *pc; PRINTMARK(); if (!_obj) { tc->type = JT_INVALID; return; } obj = (PyObject*) _obj; tc->prv = PyObject_Malloc(sizeof(TypeContext)); pc = (TypeContext *) tc->prv; if (!pc) { tc->type = JT_INVALID; PyErr_NoMemory(); return; } pc->newObj = NULL; pc->dictObj = NULL; pc->itemValue = NULL; pc->itemName = NULL; pc->attrList = NULL; pc->index = 0; pc->size = 0; pc->longValue = 0; if (PyIter_Check(obj)) { PRINTMARK(); goto ISITERABLE; } if (PyBool_Check(obj)) { PRINTMARK(); tc->type = (obj == Py_True) ? JT_TRUE : JT_FALSE; return; } else if (PyLong_Check(obj)) { PRINTMARK(); pc->PyTypeToJSON = PyLongToINT64; tc->type = JT_LONG; GET_TC(tc)->longValue = PyLong_AsLongLong(obj); exc = PyErr_Occurred(); if (exc && PyErr_ExceptionMatches(PyExc_OverflowError)) { #if HAS_JSON_HANDLE_BIGINTS PyErr_Clear(); pc->PyTypeToJSON = PyBigIntToSTR; tc->type = JT_BIGINT; GET_TC(tc)->longValue = 0; return; #endif PRINTMARK(); goto INVALID; } return; } else if (PyInt_Check(obj)) { PRINTMARK(); #ifdef _LP64 pc->PyTypeToJSON = PyIntToINT64; tc->type = JT_LONG; #else pc->PyTypeToJSON = PyIntToINT32; tc->type = JT_INT; #endif return; } else if (PyString_Check(obj)) { PRINTMARK(); pc->PyTypeToJSON = PyStringToUTF8; tc->type = JT_UTF8; return; } else if (PyUnicode_Check(obj)) { PRINTMARK(); pc->PyTypeToJSON = PyUnicodeToUTF8; tc->type = JT_UTF8; return; } else if (PyFloat_Check(obj) || (type_decimal && PyObject_IsInstance(obj, type_decimal))) { PRINTMARK(); pc->PyTypeToJSON = PyFloatToDOUBLE; tc->type = JT_DOUBLE; return; } else if (PyDateTime_Check(obj)) { PRINTMARK(); pc->PyTypeToJSON = PyDateTimeToINT64; tc->type = JT_LONG; return; } else if (PyDate_Check(obj)) { PRINTMARK(); pc->PyTypeToJSON = PyDateToINT64; tc->type = JT_LONG; return; } else if (obj == Py_None) { PRINTMARK(); tc->type = JT_NULL; return; } ISITERABLE: if (PyDict_Check(obj)) { PRINTMARK(); tc->type = JT_OBJECT; pc->iterBegin = Dict_iterBegin; pc->iterEnd = Dict_iterEnd; pc->iterNext = Dict_iterNext; pc->iterGetValue = Dict_iterGetValue; pc->iterGetName = Dict_iterGetName; pc->dictObj = obj; Py_INCREF(obj); return; } else if (PyList_Check(obj)) { PRINTMARK(); tc->type = JT_ARRAY; pc->iterBegin = List_iterBegin; pc->iterEnd = List_iterEnd; pc->iterNext = List_iterNext; pc->iterGetValue = List_iterGetValue; pc->iterGetName = List_iterGetName; return; } else if (PyTuple_Check(obj)) { PRINTMARK(); tc->type = JT_ARRAY; pc->iterBegin = Tuple_iterBegin; pc->iterEnd = Tuple_iterEnd; pc->iterNext = Tuple_iterNext; pc->iterGetValue = Tuple_iterGetValue; pc->iterGetName = Tuple_iterGetName; return; } else if (PyAnySet_Check(obj)) { PRINTMARK(); tc->type = JT_ARRAY; pc->iterBegin = Iter_iterBegin; pc->iterEnd = Iter_iterEnd; pc->iterNext = Iter_iterNext; pc->iterGetValue = Iter_iterGetValue; pc->iterGetName = Iter_iterGetName; return; } toDictFunc = PyObject_GetAttrString(obj, "toDict"); if (toDictFunc) { PyObject* tuple = PyTuple_New(0); PyObject* toDictResult = PyObject_Call(toDictFunc, tuple, NULL); Py_DECREF(tuple); Py_DECREF(toDictFunc); if (toDictResult == NULL) { PyErr_Clear(); tc->type = JT_NULL; return; } if (!PyDict_Check(toDictResult)) { Py_DECREF(toDictResult); tc->type = JT_NULL; return; } PRINTMARK(); tc->type = JT_OBJECT; pc->iterBegin = Dict_iterBegin; pc->iterEnd = Dict_iterEnd; pc->iterNext = Dict_iterNext; pc->iterGetValue = Dict_iterGetValue; pc->iterGetName = Dict_iterGetName; pc->dictObj = toDictResult; return; } PyErr_Clear(); PRINTMARK(); // Falling to INVALID case as this type of object(class instance, module, // class, function, etc..) can't be serialized. PyErr_Format (PyExc_TypeError, "%s", "Object is not JSON serializable"); INVALID: tc->type = JT_INVALID; PyObject_Free(tc->prv); tc->prv = NULL; return; }
static void Object_beginTypeContext (JSOBJ _obj, JSONTypeContext *tc, JSONObjectEncoder *enc) { PyObject *obj, *objRepr, *exc; TypeContext *pc; PRINTMARK(); if (!_obj) { tc->type = JT_INVALID; return; } obj = (PyObject*) _obj; tc->prv = PyObject_Malloc(sizeof(TypeContext)); pc = (TypeContext *) tc->prv; if (!pc) { tc->type = JT_INVALID; PyErr_NoMemory(); return; } pc->newObj = NULL; pc->dictObj = NULL; pc->itemValue = NULL; pc->itemName = NULL; pc->iterator = NULL; pc->attrList = NULL; pc->index = 0; pc->size = 0; pc->longValue = 0; pc->rawJSONValue = NULL; if (PyIter_Check(obj)) { PRINTMARK(); goto ISITERABLE; } if (PyBool_Check(obj)) { PRINTMARK(); tc->type = (obj == Py_True) ? JT_TRUE : JT_FALSE; return; } else if (PyLong_Check(obj)) { PRINTMARK(); pc->PyTypeToJSON = PyLongToINT64; tc->type = JT_LONG; GET_TC(tc)->longValue = PyLong_AsLongLong(obj); exc = PyErr_Occurred(); if (!exc) { return; } if (exc && PyErr_ExceptionMatches(PyExc_OverflowError)) { PyErr_Clear(); pc->PyTypeToJSON = PyLongToUINT64; tc->type = JT_ULONG; GET_TC(tc)->unsignedLongValue = PyLong_AsUnsignedLongLong(obj); exc = PyErr_Occurred(); if (exc && PyErr_ExceptionMatches(PyExc_OverflowError)) { PRINTMARK(); goto INVALID; } } return; } else if (PyInt_Check(obj)) { PRINTMARK(); #ifdef _LP64 pc->PyTypeToJSON = PyIntToINT64; tc->type = JT_LONG; #else pc->PyTypeToJSON = PyIntToINT32; tc->type = JT_INT; #endif return; } else if (PyString_Check(obj)) { PRINTMARK(); pc->PyTypeToJSON = PyStringToUTF8; tc->type = JT_UTF8; return; } else if (PyUnicode_Check(obj)) { PRINTMARK(); pc->PyTypeToJSON = PyUnicodeToUTF8; tc->type = JT_UTF8; return; } else if (PyFloat_Check(obj) || (type_decimal && PyObject_IsInstance(obj, type_decimal))) { PRINTMARK(); pc->PyTypeToJSON = PyFloatToDOUBLE; tc->type = JT_DOUBLE; return; } else if (obj == Py_None) { PRINTMARK(); tc->type = JT_NULL; return; } ISITERABLE: if (PyDict_Check(obj)) { PRINTMARK(); tc->type = JT_OBJECT; SetupDictIter(obj, pc, enc); Py_INCREF(obj); return; } else if (PyList_Check(obj)) { PRINTMARK(); tc->type = JT_ARRAY; pc->iterEnd = List_iterEnd; pc->iterNext = List_iterNext; pc->iterGetValue = List_iterGetValue; pc->iterGetName = List_iterGetName; GET_TC(tc)->index = 0; GET_TC(tc)->size = PyList_GET_SIZE( (PyObject *) obj); return; } else if (PyTuple_Check(obj)) { PRINTMARK(); tc->type = JT_ARRAY; pc->iterEnd = Tuple_iterEnd; pc->iterNext = Tuple_iterNext; pc->iterGetValue = Tuple_iterGetValue; pc->iterGetName = Tuple_iterGetName; GET_TC(tc)->index = 0; GET_TC(tc)->size = PyTuple_GET_SIZE( (PyObject *) obj); GET_TC(tc)->itemValue = NULL; return; } if (UNLIKELY(PyObject_HasAttrString(obj, "toDict"))) { PyObject* toDictFunc = PyObject_GetAttrString(obj, "toDict"); PyObject* tuple = PyTuple_New(0); PyObject* toDictResult = PyObject_Call(toDictFunc, tuple, NULL); Py_DECREF(tuple); Py_DECREF(toDictFunc); if (toDictResult == NULL) { goto INVALID; } if (!PyDict_Check(toDictResult)) { Py_DECREF(toDictResult); tc->type = JT_NULL; return; } PRINTMARK(); tc->type = JT_OBJECT; SetupDictIter(toDictResult, pc, enc); return; } else if (UNLIKELY(PyObject_HasAttrString(obj, "__json__"))) { PyObject* toJSONFunc = PyObject_GetAttrString(obj, "__json__"); PyObject* tuple = PyTuple_New(0); PyObject* toJSONResult = PyObject_Call(toJSONFunc, tuple, NULL); Py_DECREF(tuple); Py_DECREF(toJSONFunc); if (toJSONResult == NULL) { goto INVALID; } if (PyErr_Occurred()) { Py_DECREF(toJSONResult); goto INVALID; } if (!PyString_Check(toJSONResult) && !PyUnicode_Check(toJSONResult)) { Py_DECREF(toJSONResult); PyErr_Format (PyExc_TypeError, "expected string"); goto INVALID; } PRINTMARK(); pc->PyTypeToJSON = PyRawJSONToUTF8; tc->type = JT_RAW; GET_TC(tc)->rawJSONValue = toJSONResult; return; } PRINTMARK(); PyErr_Clear(); objRepr = PyObject_Repr(obj); PyErr_Format (PyExc_TypeError, "%s is not JSON serializable", PyString_AS_STRING(objRepr)); Py_DECREF(objRepr); INVALID: PRINTMARK(); tc->type = JT_INVALID; PyObject_Free(tc->prv); tc->prv = NULL; return; }