⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dictobject.c

📁 python s60 1.4.5版本的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifdef SYMBIAN
	SPy_Python_globals* pyglobals = PYTHON_GLOBALS; // avoid TLS reads
#endif
	/* Allocate the result tuple before checking the size.  Believe it
	 * or not, this allocation could trigger a garbage collection which
	 * could empty the dict, so if we checked the size first and that
	 * happened, the result would be an infinite loop (searching for an
	 * entry that no longer exists).  Note that the usual popitem()
	 * idiom is "while d: k, v = d.popitem()". so needing to throw the
	 * tuple away  if the dict *is* empty isn't a significant
	 * inefficiency -- possible, but unlikely in practice.
	 */
	res = PyTuple_New(2);
	if (res == NULL)
		return NULL;
	if (mp->ma_used == 0) {
		Py_DECREF(res);
		PyErr_SetString(PyExc_KeyError,
				"popitem(): dictionary is empty");
		return NULL;
	}
	/* Set ep to "the first" dict entry with a value.  We abuse the hash
	 * field of slot 0 to hold a search finger:
	 * If slot 0 has a value, use slot 0.
	 * Else slot 0 is being used to hold a search finger,
	 * and we use its hash value as the first index to look.
	 */
	ep = &mp->ma_table[0];
	if (ep->me_value == NULL) {
		i = (int)ep->me_hash;
		/* The hash field may be a real hash value, or it may be a
		 * legit search finger, or it may be a once-legit search
		 * finger that's out of bounds now because it wrapped around
		 * or the table shrunk -- simply make sure it's in bounds now.
		 */
		if (i > mp->ma_mask || i < 1)
			i = 1;	/* skip slot 0 */
		while ((ep = &mp->ma_table[i])->me_value == NULL) {
			i++;
			if (i > mp->ma_mask)
				i = 1;
		}
	}
	PyTuple_SET_ITEM(res, 0, ep->me_key);
	PyTuple_SET_ITEM(res, 1, ep->me_value);
	Py_INCREF(dummy);
	ep->me_key = dummy;
	ep->me_value = NULL;
	mp->ma_used--;
	assert(mp->ma_table[0].me_value == NULL);
	mp->ma_table[0].me_hash = i + 1;  /* next place to start */
	return res;
}

static int
dict_traverse(PyObject *op, visitproc visit, void *arg)
{
	int i = 0, err;
	PyObject *pk;
	PyObject *pv;

	while (PyDict_Next(op, &i, &pk, &pv)) {
		err = visit(pk, arg);
		if (err)
			return err;
		err = visit(pv, arg);
		if (err)
			return err;
	}
	return 0;
}

static int
dict_tp_clear(PyObject *op)
{
	PyDict_Clear(op);
	return 0;
}


staticforward PyObject *dictiter_new(dictobject *, binaryfunc);

static PyObject *
select_key(PyObject *key, PyObject *value)
{
	Py_INCREF(key);
	return key;
}

static PyObject *
select_value(PyObject *key, PyObject *value)
{
	Py_INCREF(value);
	return value;
}

static PyObject *
select_item(PyObject *key, PyObject *value)
{
	PyObject *res = PyTuple_New(2);

	if (res != NULL) {
		Py_INCREF(key);
		Py_INCREF(value);
		PyTuple_SET_ITEM(res, 0, key);
		PyTuple_SET_ITEM(res, 1, value);
	}
	return res;
}

static PyObject *
dict_iterkeys(dictobject *dict)
{
	return dictiter_new(dict, select_key);
}

static PyObject *
dict_itervalues(dictobject *dict)
{
	return dictiter_new(dict, select_value);
}

static PyObject *
dict_iteritems(dictobject *dict)
{
	return dictiter_new(dict, select_item);
}


static const char has_key__doc__[] =
"D.has_key(k) -> 1 if D has a key k, else 0";

static const char get__doc__[] =
"D.get(k[,d]) -> D[k] if D.has_key(k), else d.  d defaults to None.";

static const char setdefault_doc__[] =
"D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if not D.has_key(k)";

static const char popitem__doc__[] =
"D.popitem() -> (k, v), remove and return some (key, value) pair as a\n\
2-tuple; but raise KeyError if D is empty";

static const char keys__doc__[] =
"D.keys() -> list of D's keys";

static const char items__doc__[] =
"D.items() -> list of D's (key, value) pairs, as 2-tuples";

static const char values__doc__[] =
"D.values() -> list of D's values";

static const char update__doc__[] =
"D.update(E) -> None.  Update D from E: for k in E.keys(): D[k] = E[k]";

static const char clear__doc__[] =
"D.clear() -> None.  Remove all items from D.";

static const char copy__doc__[] =
"D.copy() -> a shallow copy of D";

static const char iterkeys__doc__[] =
"D.iterkeys() -> an iterator over the keys of D";

static const char itervalues__doc__[] =
"D.itervalues() -> an iterator over the values of D";

static const char iteritems__doc__[] =
"D.iteritems() -> an iterator over the (key, value) items of D";

static const PyMethodDef mapp_methods[] = {
	{"has_key",	(PyCFunction)dict_has_key,      METH_O,
	 has_key__doc__},
	{"get",         (PyCFunction)dict_get,          METH_VARARGS,
	 get__doc__},
	{"setdefault",  (PyCFunction)dict_setdefault,   METH_VARARGS,
	 setdefault_doc__},
	{"popitem",	(PyCFunction)dict_popitem,	METH_NOARGS,
	 popitem__doc__},
	{"keys",	(PyCFunction)dict_keys,		METH_NOARGS,
	keys__doc__},
	{"items",	(PyCFunction)dict_items,	METH_NOARGS,
	 items__doc__},
	{"values",	(PyCFunction)dict_values,	METH_NOARGS,
	 values__doc__},
	{"update",	(PyCFunction)dict_update,	METH_O,
	 update__doc__},
	{"clear",	(PyCFunction)dict_clear,	METH_NOARGS,
	 clear__doc__},
	{"copy",	(PyCFunction)dict_copy,		METH_NOARGS,
	 copy__doc__},
	{"iterkeys",	(PyCFunction)dict_iterkeys,	METH_NOARGS,
	 iterkeys__doc__},
	{"itervalues",	(PyCFunction)dict_itervalues,	METH_NOARGS,
	 itervalues__doc__},
	{"iteritems",	(PyCFunction)dict_iteritems,	METH_NOARGS,
	 iteritems__doc__},
	{NULL,		NULL}	/* sentinel */
};

static int
dict_contains(dictobject *mp, PyObject *key)
{
	long hash;

#ifdef CACHE_HASH
	if (!PyString_CheckExact(key) ||
	    (hash = ((PyStringObject *) key)->ob_shash) == -1)
#endif
	{
		hash = PyObject_Hash(key);
		if (hash == -1)
			return -1;
	}
	return (mp->ma_lookup)(mp, key, hash)->me_value != NULL;
}

/* Hack to implement "key in dict" */
const static PySequenceMethods dict_as_sequence = {
	0,					/* sq_length */
	0,					/* sq_concat */
	0,					/* sq_repeat */
	0,					/* sq_item */
	0,					/* sq_slice */
	0,					/* sq_ass_item */
	0,					/* sq_ass_slice */
	(objobjproc)dict_contains,		/* sq_contains */
	0,					/* sq_inplace_concat */
	0,					/* sq_inplace_repeat */
};

static PyObject *
dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
	PyObject *self;

	assert(type != NULL && type->tp_alloc != NULL);
	self = type->tp_alloc(type, 0);
	if (self != NULL) {
		PyDictObject *d = (PyDictObject *)self;
		/* It's guaranteed that tp->alloc zeroed out the struct. */
		assert(d->ma_table == NULL && d->ma_fill == 0 && d->ma_used == 0);
		INIT_NONZERO_DICT_SLOTS(d);
		d->ma_lookup = lookdict_string;
#ifdef SHOW_CONVERSION_COUNTS
		++created;
#endif
	}
	return self;
}

static int
dict_init(PyObject *self, PyObject *args, PyObject *kwds)
{
	PyObject *arg = NULL;
	static const char *const kwlist[] = {"items", 0};
	int result = 0;

	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:dict",
					 kwlist, &arg))
		result = -1;

	else if (arg != NULL) {
		if (PyObject_HasAttrString(arg, "keys"))
			result = PyDict_Merge(self, arg, 1);
		else
			result = PyDict_MergeFromSeq2(self, arg, 1);
	}
	return result;
}

static long
dict_nohash(PyObject *self)
{
	PyErr_SetString(PyExc_TypeError, "dict objects are unhashable");
	return -1;
}

static PyObject *
dict_iter(dictobject *dict)
{
	return dictiter_new(dict, select_key);
}

const static char dictionary_doc[] =
#ifdef SYMBIAN
"";
#else
"dict() -> new empty dictionary.\n"
"dict(mapping) -> new dictionary initialized from a mapping object's\n"
"    (key, value) pairs.\n"
"dict(seq) -> new dictionary initialized as if via:\n"
"    d = {}\n"
"    for k, v in seq:\n"
"        d[k] = v";
#endif

#ifndef SYMBIAN
PyTypeObject PyDict_Type = {
	PyObject_HEAD_INIT(&PyType_Type)
#else
const PyTypeObject c_PyDict_Type = {
	PyObject_HEAD_INIT(NULL)
#endif
	0,
	"dict",
	sizeof(dictobject),
	0,
	(destructor)dict_dealloc,		/* tp_dealloc */
	(printfunc)dict_print,			/* tp_print */
	0,					/* tp_getattr */
	0,					/* tp_setattr */
	(cmpfunc)dict_compare,			/* tp_compare */
	(reprfunc)dict_repr,			/* tp_repr */
	0,					/* tp_as_number */
	&dict_as_sequence,			/* tp_as_sequence */
	&dict_as_mapping,			/* tp_as_mapping */
	dict_nohash,				/* tp_hash */
	0,					/* tp_call */
	0,					/* tp_str */
	PyObject_GenericGetAttr,		/* tp_getattro */
	0,					/* tp_setattro */
	0,					/* tp_as_buffer */
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
		Py_TPFLAGS_BASETYPE,		/* tp_flags */
	dictionary_doc,				/* tp_doc */
	(traverseproc)dict_traverse,		/* tp_traverse */
	(inquiry)dict_tp_clear,			/* tp_clear */
	dict_richcompare,			/* tp_richcompare */
	0,					/* tp_weaklistoffset */
	(getiterfunc)dict_iter,			/* tp_iter */
	0,					/* tp_iternext */
	mapp_methods,				/* tp_methods */
	0,					/* tp_members */
	0,					/* tp_getset */
	0,					/* tp_base */
	0,					/* tp_dict */
	0,					/* tp_descr_get */
	0,					/* tp_descr_set */
	0,					/* tp_dictoffset */
	(initproc)dict_init,			/* tp_init */
	PyType_GenericAlloc,			/* tp_alloc */
	dict_new,				/* tp_new */
	_PyObject_GC_Del,			/* tp_free */
};

/* For backward compatibility with old dictionary interface */

// XXX:CW32
DL_EXPORT(PyObject *)
PyDict_GetItemString(PyObject *v, const char *key)
{
	PyObject *kv, *rv;
	kv = PyString_FromString(key);
	if (kv == NULL)
		return NULL;
	rv = PyDict_GetItem(v, kv);
	Py_DECREF(kv);
	return rv;
}

// XXX:CW32
DL_EXPORT(int)
PyDict_SetItemString(PyObject *v, const char *key, PyObject *item)
{
	PyObject *kv;
	int err;
	kv = PyString_FromString(key);
	if (kv == NULL)
		return -1;
	PyString_InternInPlace(&kv); /* XXX Should we really? */
	err = PyDict_SetItem(v, kv, item);
	Py_DECREF(kv);
	return err;
}

DL_EXPORT(int)
PyDict_DelItemString(PyObject *v, char *key)
{
	PyObject *kv;
	int err;
	kv = PyString_FromString(key);
	if (kv == NULL)
		return -1;
	err = PyDict_DelItem(v, kv);
	Py_DECREF(kv);
	return err;
}

/* Dictionary iterator type */

#ifndef SYMBIAN
extern const PyTypeObject PyDictIter_Type; /* Forward */
#endif

typedef struct {
	PyObject_HEAD
	dictobject *di_dict;
	int di_used;
	int di_pos;
	binaryfunc di_select;
} dictiterobject;

static PyObject *
dictiter_new(dictobject *dict, binaryfunc select)
{
	dictiterobject *di;
	di = PyObject_NEW(dictiterobject, &PyDictIter_Type);
	if (di == NULL)
		return NULL;
	Py_INCREF(dict);
	di->di_dict = dict;
	di->di_used = dict->ma_used;
	di->di_pos = 0;
	di->di_select = select;
	return (PyObject *)di;
}

static void
dictiter_dealloc(dictiterobject *di)
{
	Py_DECREF(di->di_dict);
	PyObject_DEL(di);
}

static PyObject *
dictiter_next(dictiterobject *di, PyObject *args)
{
	PyObject *key, *value;

	if (di->di_used != di->di_dict->ma_used) {
		PyErr_SetString(PyExc_RuntimeError,
				"dictionary changed size during iteration");
		return NULL;
	}
	if (PyDict_Next((PyObject *)(di->di_dict), &di->di_pos, &key, &value)) {
		return (*di->di_select)(key, value);
	}
	PyErr_SetObject(PyExc_StopIteration, Py_None);
	return NULL;
}

static PyObject *
dictiter_getiter(PyObject *it)
{
	Py_INCREF(it);
	return it;
}

const static PyMethodDef dictiter_methods[] = {
	{"next",	(PyCFunction)dictiter_next,	METH_VARARGS,
	 "it.next() -- get the next value, or raise StopIteration"},
	{NULL,		NULL}		/* sentinel */
};

static PyObject *dictiter_iternext(dictiterobject *di)
{
	PyObject *key, *value;

	if (di->di_used != di->di_dict->ma_used) {
		PyErr_SetString(PyExc_RuntimeError,
				"dictionary changed size during iteration");
		return NULL;
	}
	if (PyDict_Next((PyObject *)(di->di_dict), &di->di_pos, &key, &value)) {
		return (*di->di_select)(key, value);
	}
	return NULL;
}

#ifndef SYMBIAN
PyTypeObject PyDictIter_Type = {
	PyObject_HEAD_INIT(&PyType_Type)
#else
const PyTypeObject c_PyDictIter_Type = {
	PyObject_HEAD_INIT(NULL)
#endif
	0,					/* ob_size */
	"dictionary-iterator",			/* tp_name */
	sizeof(dictiterobject),			/* tp_basicsize */
	0,					/* tp_itemsize */
	/* methods */
	(destructor)dictiter_dealloc, 		/* tp_dealloc */
	0,					/* tp_print */
	0,					/* tp_getattr */
	0,					/* tp_setattr */
	0,					/* tp_compare */
	0,					/* tp_repr */
	0,					/* tp_as_number */
	0,					/* tp_as_sequence */
	0,					/* tp_as_mapping */
	0,					/* tp_hash */
	0,					/* tp_call */
	0,					/* tp_str */
	PyObject_GenericGetAttr,		/* tp_getattro */
	0,					/* tp_setattro */
	0,					/* tp_as_buffer */
	Py_TPFLAGS_DEFAULT,			/* tp_flags */
 	0,					/* tp_doc */
 	0,					/* tp_traverse */
 	0,					/* tp_clear */
	0,					/* tp_richcompare */
	0,					/* tp_weaklistoffset */
	(getiterfunc)dictiter_getiter,		/* tp_iter */
	(iternextfunc)dictiter_iternext,	/* tp_iternext */
	dictiter_methods,			/* tp_methods */
	0,					/* tp_members */
	0,					/* tp_getset */
	0,					/* tp_base */
	0,					/* tp_dict */
	0,					/* tp_descr_get */
	0,					/* tp_descr_set */
};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -