summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2003-12-13 11:26:12 (GMT)
committerRaymond Hettinger <python@rcn.com>2003-12-13 11:26:12 (GMT)
commit8f5cdaa784f555149adf5e94fd2e989f99d6b1db (patch)
treed6a8f66d75cc46f849b5933fb2a57b41e76a7d4f /Objects
parentfeb78c94fa444a75b912ca355c3c80d7453f03f0 (diff)
downloadcpython-8f5cdaa784f555149adf5e94fd2e989f99d6b1db.zip
cpython-8f5cdaa784f555149adf5e94fd2e989f99d6b1db.tar.gz
cpython-8f5cdaa784f555149adf5e94fd2e989f99d6b1db.tar.bz2
* Added a new method flag, METH_COEXIST.
* Used the flag to optimize set.__contains__(), dict.__contains__(), dict.__getitem__(), and list.__getitem__().
Diffstat (limited to 'Objects')
-rw-r--r--Objects/dictobject.c34
-rw-r--r--Objects/listobject.c5
-rw-r--r--Objects/methodobject.c2
-rw-r--r--Objects/setobject.c26
-rw-r--r--Objects/typeobject.c5
5 files changed, 69 insertions, 3 deletions
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 0cf71b5..013f5f2 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -498,6 +498,31 @@ PyDict_GetItem(PyObject *op, PyObject *key)
return (mp->ma_lookup)(mp, key, hash)->me_value;
}
+static PyObject *
+dict_getitem(PyObject *op, PyObject *key)
+{
+ long hash;
+ dictobject *mp = (dictobject *)op;
+ PyObject *v;
+
+ if (!PyDict_Check(op)) {
+ return NULL;
+ }
+ if (!PyString_CheckExact(key) ||
+ (hash = ((PyStringObject *) key)->ob_shash) == -1)
+ {
+ hash = PyObject_Hash(key);
+ if (hash == -1)
+ return NULL;
+ }
+ v = (mp->ma_lookup)(mp, key, hash) -> me_value;
+ if (v == NULL)
+ PyErr_SetObject(PyExc_KeyError, key);
+ else
+ Py_INCREF(v);
+ return v;
+}
+
/* CAUTION: PyDict_SetItem() must guarantee that it won't resize the
* dictionary if it is merely replacing the value for an existing key.
* This is means that it's safe to loop over a dictionary with
@@ -1735,6 +1760,11 @@ dict_iteritems(dictobject *dict)
PyDoc_STRVAR(has_key__doc__,
"D.has_key(k) -> True if D has a key k, else False");
+PyDoc_STRVAR(contains__doc__,
+"D.__contains__(k) -> True if D has a key k, else False");
+
+PyDoc_STRVAR(getitem__doc__, "x.__getitem__(y) <==> x[y]");
+
PyDoc_STRVAR(get__doc__,
"D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.");
@@ -1781,6 +1811,10 @@ PyDoc_STRVAR(iteritems__doc__,
"D.iteritems() -> an iterator over the (key, value) items of D");
static PyMethodDef mapp_methods[] = {
+ {"__contains__",(PyCFunction)dict_has_key, METH_O | METH_COEXIST,
+ contains__doc__},
+ {"__getitem__", (PyCFunction)dict_getitem, METH_O | METH_COEXIST,
+ getitem__doc__},
{"has_key", (PyCFunction)dict_has_key, METH_O,
has_key__doc__},
{"get", (PyCFunction)dict_get, METH_VARARGS,
diff --git a/Objects/listobject.c b/Objects/listobject.c
index 7d5c8b4..3915cc9 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -2371,6 +2371,8 @@ list_nohash(PyObject *self)
static PyObject *list_iter(PyObject *seq);
static PyObject *list_reversed(PyListObject* seq, PyObject* unused);
+PyDoc_STRVAR(getitem_doc,
+"x.__getitem__(y) <==> x[y]");
PyDoc_STRVAR(reversed_doc,
"L.__reversed__() -- return a reverse iterator over the list");
PyDoc_STRVAR(append_doc,
@@ -2396,7 +2398,10 @@ PyDoc_STRVAR(sorted_doc,
"list.sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list;\n\
cmp(x, y) -> -1, 0, 1");
+static PyObject *list_subscript(PyListObject*, PyObject*);
+
static PyMethodDef list_methods[] = {
+ {"__getitem__", (PyCFunction)list_subscript, METH_O|METH_COEXIST, getitem_doc},
{"__reversed__",(PyCFunction)list_reversed, METH_NOARGS, reversed_doc},
{"append", (PyCFunction)listappend, METH_O, append_doc},
{"insert", (PyCFunction)listinsert, METH_VARARGS, insert_doc},
diff --git a/Objects/methodobject.c b/Objects/methodobject.c
index 3a92fa4..5818616 100644
--- a/Objects/methodobject.c
+++ b/Objects/methodobject.c
@@ -67,7 +67,7 @@ PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw)
PyObject *self = PyCFunction_GET_SELF(func);
int size;
- switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC)) {
+ switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) {
case METH_VARARGS:
if (kw == NULL || PyDict_Size(kw) == 0)
return (*meth)(self, arg);
diff --git a/Objects/setobject.c b/Objects/setobject.c
index c060077..8e70546 100644
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -156,6 +156,28 @@ set_contains(PySetObject *so, PyObject *key)
}
static PyObject *
+set_direct_contains(PySetObject *so, PyObject *key)
+{
+ PyObject *tmp;
+ long result;
+
+ result = PyDict_Contains(so->data, key);
+ if (result == -1 && PyAnySet_Check(key)) {
+ PyErr_Clear();
+ tmp = frozenset_dict_wrapper(((PySetObject *)(key))->data);
+ if (tmp == NULL)
+ return NULL;
+ result = PyDict_Contains(so->data, tmp);
+ Py_DECREF(tmp);
+ }
+ if (result == -1)
+ return NULL;
+ return PyBool_FromLong(result);
+}
+
+PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
+
+static PyObject *
set_copy(PySetObject *so)
{
return make_new_set(so->ob_type, (PyObject *)so);
@@ -968,6 +990,8 @@ static PyMethodDef set_methods[] = {
add_doc},
{"clear", (PyCFunction)set_clear, METH_NOARGS,
clear_doc},
+ {"__contains__", (PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
+ contains_doc},
{"copy", (PyCFunction)set_copy, METH_NOARGS,
copy_doc},
{"__copy__", (PyCFunction)set_copy, METH_NOARGS,
@@ -1094,6 +1118,8 @@ PyTypeObject PySet_Type = {
static PyMethodDef frozenset_methods[] = {
+ {"__contains__", (PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
+ contains_doc},
{"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
copy_doc},
{"__copy__", (PyCFunction)frozenset_copy, METH_NOARGS,
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index e4eadb8..545dba6 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -2792,8 +2792,9 @@ add_methods(PyTypeObject *type, PyMethodDef *meth)
for (; meth->ml_name != NULL; meth++) {
PyObject *descr;
- if (PyDict_GetItemString(dict, meth->ml_name))
- continue;
+ if (PyDict_GetItemString(dict, meth->ml_name) &&
+ !(meth->ml_flags & METH_COEXIST))
+ continue;
if (meth->ml_flags & METH_CLASS) {
if (meth->ml_flags & METH_STATIC) {
PyErr_SetString(PyExc_ValueError,