| /* Extracted copy of PylibMC_Client_get_multi */ | 
| static PyObject *PylibMC_Client_get_multi( | 
| PylibMC_Client *self, PyObject *args, PyObject *kwds) { | 
| PyObject *key_seq, **key_objs, *retval = NULL; | 
| char **keys, *prefix = NULL; | 
| char *err_func = NULL; | 
| memcached_result_st *res, *results = NULL; | 
| int prefix_len = 0; | 
| Py_ssize_t i; | 
| PyObject *key_it, *ckey; | 
| size_t *key_lens; | 
| size_t nkeys, nresults = 0; | 
| memcached_return rc; | 
| static char *kws[] = { "keys", "key_prefix", NULL }; | 
| if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s#:get_multi", kws, | 
| &key_seq, &prefix, &prefix_len)) | 
| return NULL; | 
| if ((nkeys = (size_t)PySequence_Length(key_seq)) == -1) | 
| return NULL; | 
| /* Populate keys and key_lens. */ | 
| keys = PyMem_New(char *, nkeys); | 
| key_lens = PyMem_New(size_t, nkeys); | 
| key_objs = PyMem_New(PyObject *, nkeys); | 
| if (!keys || !key_lens || !key_objs) { | 
| PyMem_Free(keys); | 
| PyMem_Free(key_lens); | 
| PyMem_Free(key_objs); | 
| return PyErr_NoMemory(); | 
| } | 
| /* Clear potential previous exception, because we explicitly check for | 
| * exceptions as a loop predicate. */ | 
| PyErr_Clear(); | 
| /* Iterate through all keys and set lengths etc. */ | 
| key_it = PyObject_GetIter(key_seq); | 
| i = 0; | 
| while ((ckey = PyIter_Next(key_it)) != NULL) { | 
| char *key; | 
| Py_ssize_t key_len; | 
| PyObject *rkey; | 
| assert(i < nkeys); | 
| if (PyErr_Occurred() || !_PylibMC_CheckKey(ckey)) { | 
| nkeys = i; | 
| goto earlybird; | 
| } | 
| PyString_AsStringAndSize(ckey, &key, &key_len); | 
| key_lens[i] = (size_t)(key_len + prefix_len); | 
| /* Skip empty keys */ | 
| if (!key_lens[i]) | 
| continue; | 
| /* determine rkey, the prefixed ckey */ | 
| if (prefix != NULL) { | 
| rkey = PyString_FromStringAndSize(prefix, prefix_len); | 
| PyString_Concat(&rkey, ckey); | 
| if (rkey == NULL) | 
| goto earlybird; | 
| rkey = PyString_FromFormat("%s%s", | 
| prefix, PyString_AS_STRING(ckey)); | 
| } else { | 
| Py_INCREF(ckey); | 
| rkey = ckey; | 
| } | 
| Py_DECREF(ckey); | 
| keys[i] = PyString_AS_STRING(rkey); | 
| key_objs[i++] = rkey; | 
| } | 
| nkeys = i; | 
| Py_XDECREF(key_it); | 
| if (nkeys == 0) { | 
| retval = PyDict_New(); | 
| goto earlybird; | 
| } else if (PyErr_Occurred()) { | 
| nkeys--; | 
| goto earlybird; | 
| } | 
| /* TODO Make an iterator interface for getting each key separately. | 
| * | 
| * This would help large retrievals, as a single dictionary containing all | 
| * the data at once isn't needed. (Should probably look into if it's even | 
| * worth it.) | 
| */ | 
| Py_BEGIN_ALLOW_THREADS; | 
| rc = pylibmc_memcached_fetch_multi(self->mc, | 
| keys, nkeys, key_lens, | 
| &results, &nresults, | 
| &err_func); | 
| Py_END_ALLOW_THREADS; | 
| if (rc != MEMCACHED_SUCCESS) { | 
| PylibMC_ErrFromMemcached(self, err_func, rc); | 
| goto earlybird; | 
| } | 
| retval = PyDict_New(); | 
| for (i = 0; i < nresults; i++) { | 
| PyObject *val, *key_obj; | 
| int rc; | 
| res = results + i; | 
| /* Explicitly construct a key string object so that NUL-bytes and the | 
| * likes can be contained within the keys (this is possible in the | 
| * binary protocol.) */ | 
| key_obj = PyString_FromStringAndSize(memcached_result_key_value(res) + prefix_len, | 
| memcached_result_key_length(res) - prefix_len); | 
| if (key_obj == NULL) | 
| goto unpack_error; | 
| /* Parse out value */ | 
| val = _PylibMC_parse_memcached_result(res); | 
| if (val == NULL) | 
| goto unpack_error; | 
| rc = PyDict_SetItem(retval, key_obj, val); | 
| Py_DECREF(key_obj); | 
| Py_DECREF(val); | 
| if (rc != 0) | 
| goto unpack_error; | 
| continue; | 
| unpack_error: | 
| Py_DECREF(retval); | 
| break; | 
| } | 
| earlybird: | 
| PyMem_Free(key_lens); | 
| PyMem_Free(keys); | 
| for (i = 0; i < nkeys; i++) | 
| Py_DECREF(key_objs[i]); | 
| PyMem_Free(key_objs); | 
| if (results != NULL) { | 
| for (i = 0; i < nresults && results != NULL; i++) { | 
| memcached_result_free(results + i); | 
| } | 
| PyMem_Free(results); | 
| } | 
| /* Not INCREFing because the only two outcomes are NULL and a new dict. | 
| * We're the owner of that dict already, so. */ | 
| return retval; | 
| } | 
when _PyArg_ParseTupleAndKeywords_SizeT() succeeds
taking False path
when PySequence_Size() succeeds
taking False path
when considering range: 0 <= value <= 0xfffffffffffffff
taking True path
when PyMem_Malloc() succeeds
taking True path
when PyMem_Malloc() succeeds
taking True path
when PyMem_Malloc() succeeds
taking False path
taking False path
taking False path
calling PyErr_Clear()
when PyObject_GetIter() succeeds
when PyIter_Next() retrieves a value (new ref)
taking True path
when considering range: 1 <= nkeys <= 0xfffffffffffffff
taking False path
PyErr_Occurred()
taking False path
when considering range: -0x80000000 <= value <= -1
taking False path
when considering range: -0x8000000000000000 <= value <= -1
taking False path
when treating unknown const char * from libcpychecker/html/test/example2/pylibmc-issue-68.c:68 as non-NULL
taking True path
when PyString_FromStringAndSize() succeeds
when PyString_Concat() succeeds (Py_DECREF() without deallocation on *LHS)
taking False path
when PyString_FromFormat() succeeds
when taking True path
when PyIter_Next() returns NULL without setting an exception (end of iteration)
taking False path
taking False path
when taking True path
taking False path
PyErr_Occurred()
taking False path
releasing the GIL by calling PyEval_SaveThread()
reacquiring the GIL by calling PyEval_RestoreThread()
when considering value == (int)0 from libcpychecker/html/test/example2/pylibmc-issue-68.c:148
taking False path
when PyDict_New() succeeds
when taking True path
when PyString_FromStringAndSize() succeeds
taking False path
when treating unknown struct PyObject * from libcpychecker/html/test/example2/pylibmc-issue-68.c:176 as non-NULL
taking False path
when PyDict_SetItem() fails
when taking True path
when considering range: -0x8000000000000000 <= value <= -1
taking True path
taking True path
when taking False path
calling tp_dealloc on PyDictObject allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:159
memory deallocated here
calling PyMem_Free on PyMem_Malloc allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:77
calling PyMem_Free on PyMem_Malloc allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:76
taking True path
when taking True path
taking False path
calling PyMem_Free on PyMem_Malloc allocated at libcpychecker/html/test/example2/pylibmc-issue-68.c:78
when treating unknown struct memcached_result_st * * from libcpychecker/html/test/example2/pylibmc-issue-68.c:148 as non-NULL
taking True path
when taking True path
taking True path
when taking False path
calling PyMem_Free on Region('heap-region-12')
found 11 similar trace(s) to this