コード例 #1
0
static PyObject *
lru_cache_cache_info(lru_cache_object *self, PyObject *unused)
{
    return PyObject_CallFunction(self->cache_info_type, "nnOn",
                                 self->hits, self->misses, self->maxsize_O,
                                 PyDict_GET_SIZE(self->cache));
}
コード例 #2
0
ファイル: _functoolsmodule.c プロジェクト: 1st1/cpython
static PyObject *
lru_cache_make_key(PyObject *args, PyObject *kwds, int typed)
{
    PyObject *key, *keyword, *value;
    Py_ssize_t key_size, pos, key_pos, kwds_size;

    /* short path, key will match args anyway, which is a tuple */
    if (!typed && !kwds) {
        Py_INCREF(args);
        return args;
    }

    kwds_size = kwds ? PyDict_GET_SIZE(kwds) : 0;
    assert(kwds_size >= 0);

    key_size = PyTuple_GET_SIZE(args);
    if (kwds_size)
        key_size += kwds_size * 2 + 1;
    if (typed)
        key_size += PyTuple_GET_SIZE(args) + kwds_size;

    key = PyTuple_New(key_size);
    if (key == NULL)
        return NULL;

    key_pos = 0;
    for (pos = 0; pos < PyTuple_GET_SIZE(args); ++pos) {
        PyObject *item = PyTuple_GET_ITEM(args, pos);
        Py_INCREF(item);
        PyTuple_SET_ITEM(key, key_pos++, item);
    }
    if (kwds_size) {
        Py_INCREF(kwd_mark);
        PyTuple_SET_ITEM(key, key_pos++, kwd_mark);
        for (pos = 0; PyDict_Next(kwds, &pos, &keyword, &value);) {
            Py_INCREF(keyword);
            PyTuple_SET_ITEM(key, key_pos++, keyword);
            Py_INCREF(value);
            PyTuple_SET_ITEM(key, key_pos++, value);
        }
        assert(key_pos == PyTuple_GET_SIZE(args) + kwds_size * 2 + 1);
    }
    if (typed) {
        for (pos = 0; pos < PyTuple_GET_SIZE(args); ++pos) {
            PyObject *item = (PyObject *)Py_TYPE(PyTuple_GET_ITEM(args, pos));
            Py_INCREF(item);
            PyTuple_SET_ITEM(key, key_pos++, item);
        }
        if (kwds_size) {
            for (pos = 0; PyDict_Next(kwds, &pos, &keyword, &value);) {
                PyObject *item = (PyObject *)Py_TYPE(value);
                Py_INCREF(item);
                PyTuple_SET_ITEM(key, key_pos++, item);
            }
        }
    }
    assert(key_pos == key_size);
    return key;
}
コード例 #3
0
ファイル: sliceobject.c プロジェクト: adrian17/cpython
static PyObject *
ellipsis_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
    if (PyTuple_GET_SIZE(args) || (kwargs && PyDict_GET_SIZE(kwargs))) {
        PyErr_SetString(PyExc_TypeError, "EllipsisType takes no arguments");
        return NULL;
    }
    Py_INCREF(Py_Ellipsis);
    return Py_Ellipsis;
}
コード例 #4
0
static PyObject *
function_call(PyObject *func, PyObject *arg, PyObject *kw)
{
    PyObject *result;
    PyObject *argdefs;
    PyObject *kwtuple = NULL;
    PyObject **d, **k;
    Py_ssize_t nk, nd;

    argdefs = PyFunction_GET_DEFAULTS(func);
    if (argdefs != NULL && PyTuple_Check(argdefs)) {
        d = &PyTuple_GET_ITEM((PyTupleObject *)argdefs, 0);
        nd = PyTuple_GET_SIZE(argdefs);
    }
    else {
        d = NULL;
        nd = 0;
    }

    if (kw != NULL && PyDict_Check(kw)) {
        Py_ssize_t pos, i;
        nk = PyDict_GET_SIZE(kw);
        kwtuple = PyTuple_New(2*nk);
        if (kwtuple == NULL)
            return NULL;
        k = &PyTuple_GET_ITEM(kwtuple, 0);
        pos = i = 0;
        while (PyDict_Next(kw, &pos, &k[i], &k[i+1])) {
            Py_INCREF(k[i]);
            Py_INCREF(k[i+1]);
            i += 2;
        }
        nk = i/2;
    }
    else {
        k = NULL;
        nk = 0;
    }

    result = PyEval_EvalCodeEx(
        PyFunction_GET_CODE(func),
        PyFunction_GET_GLOBALS(func), (PyObject *)NULL,
        &PyTuple_GET_ITEM(arg, 0), PyTuple_GET_SIZE(arg),
        k, nk, d, nd,
        PyFunction_GET_KW_DEFAULTS(func),
        PyFunction_GET_CLOSURE(func));

    Py_XDECREF(kwtuple);

    return result;
}
コード例 #5
0
ファイル: _functoolsmodule.c プロジェクト: 1st1/cpython
static PyObject *
partial_call(partialobject *pto, PyObject *args, PyObject *kwargs)
{
    PyObject *kwargs2, *res;

    assert (PyCallable_Check(pto->fn));
    assert (PyTuple_Check(pto->args));
    assert (PyDict_Check(pto->kw));

    if (PyDict_GET_SIZE(pto->kw) == 0) {
        /* kwargs can be NULL */
        kwargs2 = kwargs;
        Py_XINCREF(kwargs2);
    }
    else {
        /* bpo-27840, bpo-29318: dictionary of keyword parameters must be
           copied, because a function using "**kwargs" can modify the
           dictionary. */
        kwargs2 = PyDict_Copy(pto->kw);
        if (kwargs2 == NULL) {
            return NULL;
        }

        if (kwargs != NULL) {
            if (PyDict_Merge(kwargs2, kwargs, 1) != 0) {
                Py_DECREF(kwargs2);
                return NULL;
            }
        }
    }


    if (pto->use_fastcall) {
        res = partial_fastcall(pto,
                               &PyTuple_GET_ITEM(args, 0),
                               PyTuple_GET_SIZE(args),
                               kwargs2);
    }
    else {
        res = partial_call_impl(pto, args, kwargs2);
    }
    Py_XDECREF(kwargs2);
    return res;
}
コード例 #6
0
static PyObject *
bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds)
{
    lru_list_elem *link;
    PyObject *key, *result;
    Py_hash_t hash;

    key = lru_cache_make_key(args, kwds, self->typed);
    if (!key)
        return NULL;
    hash = PyObject_Hash(key);
    if (hash == -1) {
        Py_DECREF(key);
        return NULL;
    }
    link  = (lru_list_elem *)_PyDict_GetItem_KnownHash(self->cache, key, hash);
    if (link) {
        lru_cache_extricate_link(link);
        lru_cache_append_link(self, link);
        self->hits++;
        result = link->result;
        Py_INCREF(result);
        Py_DECREF(key);
        return result;
    }
    if (PyErr_Occurred()) {
        Py_DECREF(key);
        return NULL;
    }
    result = PyObject_Call(self->func, args, kwds);
    if (!result) {
        Py_DECREF(key);
        return NULL;
    }
    if (self->full && self->root.next != &self->root) {
        /* Use the oldest item to store the new key and result. */
        PyObject *oldkey, *oldresult;
        /* Extricate the oldest item. */
        link = self->root.next;
        lru_cache_extricate_link(link);
        /* Remove it from the cache.
           The cache dict holds one reference to the link,
           and the linked list holds yet one reference to it. */
        if (_PyDict_DelItem_KnownHash(self->cache, link->key,
                                      link->hash) < 0) {
            lru_cache_append_link(self, link);
            Py_DECREF(key);
            Py_DECREF(result);
            return NULL;
        }
        /* Keep a reference to the old key and old result to
           prevent their ref counts from going to zero during the
           update. That will prevent potentially arbitrary object
           clean-up code (i.e. __del__) from running while we're
           still adjusting the links. */
        oldkey = link->key;
        oldresult = link->result;

        link->hash = hash;
        link->key = key;
        link->result = result;
        if (_PyDict_SetItem_KnownHash(self->cache, key, (PyObject *)link,
                                      hash) < 0) {
            Py_DECREF(link);
            Py_DECREF(oldkey);
            Py_DECREF(oldresult);
            return NULL;
        }
        lru_cache_append_link(self, link);
        Py_INCREF(result); /* for return */
        Py_DECREF(oldkey);
        Py_DECREF(oldresult);
    } else {
        /* Put result in a new link at the front of the queue. */
        link = (lru_list_elem *)PyObject_GC_New(lru_list_elem,
                                                &lru_list_elem_type);
        if (link == NULL) {
            Py_DECREF(key);
            Py_DECREF(result);
            return NULL;
        }

        link->hash = hash;
        link->key = key;
        link->result = result;
        _PyObject_GC_TRACK(link);
        if (_PyDict_SetItem_KnownHash(self->cache, key, (PyObject *)link,
                                      hash) < 0) {
            Py_DECREF(link);
            return NULL;
        }
        lru_cache_append_link(self, link);
        Py_INCREF(result); /* for return */
        self->full = (PyDict_GET_SIZE(self->cache) >= self->maxsize);
    }
    self->misses++;
    return result;
}
コード例 #7
0
static PyObject *
lru_cache_make_key(PyObject *args, PyObject *kwds, int typed)
{
    PyObject *key, *sorted_items;
    Py_ssize_t key_size, pos, key_pos;

    /* short path, key will match args anyway, which is a tuple */
    if (!typed && !kwds) {
        Py_INCREF(args);
        return args;
    }

    if (kwds && PyDict_GET_SIZE(kwds) > 0) {
        sorted_items = PyDict_Items(kwds);
        if (!sorted_items)
            return NULL;
        if (PyList_Sort(sorted_items) < 0) {
            Py_DECREF(sorted_items);
            return NULL;
        }
    } else
        sorted_items = NULL;

    key_size = PyTuple_GET_SIZE(args);
    if (sorted_items)
        key_size += PyList_GET_SIZE(sorted_items);
    if (typed)
        key_size *= 2;
    if (sorted_items)
        key_size++;

    key = PyTuple_New(key_size);
    if (key == NULL)
        goto done;

    key_pos = 0;
    for (pos = 0; pos < PyTuple_GET_SIZE(args); ++pos) {
        PyObject *item = PyTuple_GET_ITEM(args, pos);
        Py_INCREF(item);
        PyTuple_SET_ITEM(key, key_pos++, item);
    }
    if (sorted_items) {
        Py_INCREF(kwd_mark);
        PyTuple_SET_ITEM(key, key_pos++, kwd_mark);
        for (pos = 0; pos < PyList_GET_SIZE(sorted_items); ++pos) {
            PyObject *item = PyList_GET_ITEM(sorted_items, pos);
            Py_INCREF(item);
            PyTuple_SET_ITEM(key, key_pos++, item);
        }
    }
    if (typed) {
        for (pos = 0; pos < PyTuple_GET_SIZE(args); ++pos) {
            PyObject *item = (PyObject *)Py_TYPE(PyTuple_GET_ITEM(args, pos));
            Py_INCREF(item);
            PyTuple_SET_ITEM(key, key_pos++, item);
        }
        if (sorted_items) {
            for (pos = 0; pos < PyList_GET_SIZE(sorted_items); ++pos) {
                PyObject *tp_items = PyList_GET_ITEM(sorted_items, pos);
                PyObject *item = (PyObject *)Py_TYPE(PyTuple_GET_ITEM(tp_items, 1));
                Py_INCREF(item);
                PyTuple_SET_ITEM(key, key_pos++, item);
            }
        }
    }
    assert(key_pos == key_size);

done:
    if (sorted_items)
        Py_DECREF(sorted_items);
    return key;
}
コード例 #8
0
static PyObject *
partial_new(PyTypeObject *type, PyObject *args, PyObject *kw)
{
    PyObject *func, *pargs, *nargs, *pkw;
    partialobject *pto;

    if (PyTuple_GET_SIZE(args) < 1) {
        PyErr_SetString(PyExc_TypeError,
                        "type 'partial' takes at least one argument");
        return NULL;
    }

    pargs = pkw = NULL;
    func = PyTuple_GET_ITEM(args, 0);
    if (Py_TYPE(func) == &partial_type && type == &partial_type) {
        partialobject *part = (partialobject *)func;
        if (part->dict == NULL) {
            pargs = part->args;
            pkw = part->kw;
            func = part->fn;
            assert(PyTuple_Check(pargs));
            assert(PyDict_Check(pkw));
        }
    }
    if (!PyCallable_Check(func)) {
        PyErr_SetString(PyExc_TypeError,
                        "the first argument must be callable");
        return NULL;
    }

    /* create partialobject structure */
    pto = (partialobject *)type->tp_alloc(type, 0);
    if (pto == NULL)
        return NULL;

    pto->fn = func;
    Py_INCREF(func);

    nargs = PyTuple_GetSlice(args, 1, PY_SSIZE_T_MAX);
    if (nargs == NULL) {
        Py_DECREF(pto);
        return NULL;
    }
    if (pargs == NULL || PyTuple_GET_SIZE(pargs) == 0) {
        pto->args = nargs;
        Py_INCREF(nargs);
    }
    else if (PyTuple_GET_SIZE(nargs) == 0) {
        pto->args = pargs;
        Py_INCREF(pargs);
    }
    else {
        pto->args = PySequence_Concat(pargs, nargs);
        if (pto->args == NULL) {
            Py_DECREF(nargs);
            Py_DECREF(pto);
            return NULL;
        }
        assert(PyTuple_Check(pto->args));
    }
    Py_DECREF(nargs);

    if (pkw == NULL || PyDict_GET_SIZE(pkw) == 0) {
        if (kw == NULL) {
            pto->kw = PyDict_New();
        }
        else {
            Py_INCREF(kw);
            pto->kw = kw;
        }
    }
    else {
        pto->kw = PyDict_Copy(pkw);
        if (kw != NULL && pto->kw != NULL) {
            if (PyDict_Merge(pto->kw, kw, 1) != 0) {
                Py_DECREF(pto);
                return NULL;
            }
        }
    }
    if (pto->kw == NULL) {
        Py_DECREF(pto);
        return NULL;
    }

    return (PyObject *)pto;
}
コード例 #9
0
static PyObject *
partial_call(partialobject *pto, PyObject *args, PyObject *kw)
{
    PyObject *ret;
    PyObject *argappl, *kwappl;
    PyObject **stack;
    Py_ssize_t nargs;

    assert (PyCallable_Check(pto->fn));
    assert (PyTuple_Check(pto->args));
    assert (PyDict_Check(pto->kw));

    if (PyTuple_GET_SIZE(pto->args) == 0) {
        stack = &PyTuple_GET_ITEM(args, 0);
        nargs = PyTuple_GET_SIZE(args);
        argappl = NULL;
    }
    else if (PyTuple_GET_SIZE(args) == 0) {
        stack = &PyTuple_GET_ITEM(pto->args, 0);
        nargs = PyTuple_GET_SIZE(pto->args);
        argappl = NULL;
    }
    else {
        stack = NULL;
        argappl = PySequence_Concat(pto->args, args);
        if (argappl == NULL) {
            return NULL;
        }

        assert(PyTuple_Check(argappl));
    }

    if (PyDict_GET_SIZE(pto->kw) == 0) {
        kwappl = kw;
        Py_XINCREF(kwappl);
    }
    else {
        kwappl = PyDict_Copy(pto->kw);
        if (kwappl == NULL) {
            Py_XDECREF(argappl);
            return NULL;
        }

        if (kw != NULL) {
            if (PyDict_Merge(kwappl, kw, 1) != 0) {
                Py_XDECREF(argappl);
                Py_DECREF(kwappl);
                return NULL;
            }
        }
    }

    if (stack) {
        ret = _PyObject_FastCallDict(pto->fn, stack, nargs, kwappl);
    }
    else {
        ret = PyObject_Call(pto->fn, argappl, kwappl);
        Py_DECREF(argappl);
    }
    Py_XDECREF(kwappl);
    return ret;
}
コード例 #10
0
ファイル: cache.c プロジェクト: 1st1/cpython
PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* args)
{
    PyObject* key = args;
    pysqlite_Node* node;
    pysqlite_Node* ptr;
    PyObject* data;

    node = (pysqlite_Node*)PyDict_GetItem(self->mapping, key);
    if (node) {
        /* an entry for this key already exists in the cache */

        /* increase usage counter of the node found */
        if (node->count < LONG_MAX) {
            node->count++;
        }

        /* if necessary, reorder entries in the cache by swapping positions */
        if (node->prev && node->count > node->prev->count) {
            ptr = node->prev;

            while (ptr->prev && node->count > ptr->prev->count) {
                ptr = ptr->prev;
            }

            if (node->next) {
                node->next->prev = node->prev;
            } else {
                self->last = node->prev;
            }
            if (node->prev) {
                node->prev->next = node->next;
            }
            if (ptr->prev) {
                ptr->prev->next = node;
            } else {
                self->first = node;
            }

            node->next = ptr;
            node->prev = ptr->prev;
            if (!node->prev) {
                self->first = node;
            }
            ptr->prev = node;
        }
    } else {
        /* There is no entry for this key in the cache, yet. We'll insert a new
         * entry in the cache, and make space if necessary by throwing the
         * least used item out of the cache. */

        if (PyDict_GET_SIZE(self->mapping) == self->size) {
            if (self->last) {
                node = self->last;

                if (PyDict_DelItem(self->mapping, self->last->key) != 0) {
                    return NULL;
                }

                if (node->prev) {
                    node->prev->next = NULL;
                }
                self->last = node->prev;
                node->prev = NULL;

                Py_DECREF(node);
            }
        }

        data = PyObject_CallFunction(self->factory, "O", key);

        if (!data) {
            return NULL;
        }

        node = pysqlite_new_node(key, data);
        if (!node) {
            return NULL;
        }
        node->prev = self->last;

        Py_DECREF(data);

        if (PyDict_SetItem(self->mapping, key, (PyObject*)node) != 0) {
            Py_DECREF(node);
            return NULL;
        }

        if (self->last) {
            self->last->next = node;
        } else {
            self->first = node;
        }
        self->last = node;
    }

    Py_INCREF(node->data);
    return node->data;
}