mirror of
https://github.com/python/cpython.git
synced 2025-10-09 16:34:44 +00:00
Fixed issue #1564: The set implementation should special-case PyUnicode instead of PyString
I moved the unicode_eq to stringlib/eq.h to keep the function static and possible inline for setobject.c and dictobject.h. I also removed the unused _PyString_Eq method. If it's required in the future it can be added to eq.h
This commit is contained in:
parent
110194048e
commit
0ded5b54bb
7 changed files with 85 additions and 45 deletions
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "Python.h"
|
||||
#include "structmember.h"
|
||||
#include "stringlib/eq.h"
|
||||
|
||||
/* Set a key error with the specified argument, wrapping it in a
|
||||
* tuple automatically so that tuple keys are not unpacked as the
|
||||
|
@ -55,6 +56,7 @@ _PySet_Dummy(void)
|
|||
static PySetObject *free_sets[MAXFREESETS];
|
||||
static int num_free_sets = 0;
|
||||
|
||||
|
||||
/*
|
||||
The basic lookup function used by all operations.
|
||||
This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
|
||||
|
@ -144,12 +146,12 @@ set_lookkey(PySetObject *so, PyObject *key, register long hash)
|
|||
}
|
||||
|
||||
/*
|
||||
* Hacked up version of set_lookkey which can assume keys are always strings;
|
||||
* This means we can always use _PyString_Eq directly and not have to check to
|
||||
* Hacked up version of set_lookkey which can assume keys are always unicode;
|
||||
* This means we can always use unicode_eq directly and not have to check to
|
||||
* see if the comparison altered the table.
|
||||
*/
|
||||
static setentry *
|
||||
set_lookkey_string(PySetObject *so, PyObject *key, register long hash)
|
||||
set_lookkey_unicode(PySetObject *so, PyObject *key, register long hash)
|
||||
{
|
||||
register Py_ssize_t i;
|
||||
register size_t perturb;
|
||||
|
@ -158,11 +160,11 @@ set_lookkey_string(PySetObject *so, PyObject *key, register long hash)
|
|||
setentry *table = so->table;
|
||||
register setentry *entry;
|
||||
|
||||
/* Make sure this function doesn't have to handle non-string keys,
|
||||
/* Make sure this function doesn't have to handle non-unicode keys,
|
||||
including subclasses of str; e.g., one reason to subclass
|
||||
strings is to override __eq__, and for speed we don't cater to
|
||||
that here. */
|
||||
if (!PyString_CheckExact(key)) {
|
||||
if (!PyUnicode_CheckExact(key)) {
|
||||
so->lookup = set_lookkey;
|
||||
return set_lookkey(so, key, hash);
|
||||
}
|
||||
|
@ -173,7 +175,7 @@ set_lookkey_string(PySetObject *so, PyObject *key, register long hash)
|
|||
if (entry->key == dummy)
|
||||
freeslot = entry;
|
||||
else {
|
||||
if (entry->hash == hash && _PyString_Eq(entry->key, key))
|
||||
if (entry->hash == hash && unicode_eq(entry->key, key))
|
||||
return entry;
|
||||
freeslot = NULL;
|
||||
}
|
||||
|
@ -188,7 +190,7 @@ set_lookkey_string(PySetObject *so, PyObject *key, register long hash)
|
|||
if (entry->key == key
|
||||
|| (entry->hash == hash
|
||||
&& entry->key != dummy
|
||||
&& _PyString_Eq(entry->key, key)))
|
||||
&& unicode_eq(entry->key, key)))
|
||||
return entry;
|
||||
if (entry->key == dummy && freeslot == NULL)
|
||||
freeslot = entry;
|
||||
|
@ -375,8 +377,8 @@ set_add_key(register PySetObject *so, PyObject *key)
|
|||
register long hash;
|
||||
register Py_ssize_t n_used;
|
||||
|
||||
if (!PyString_CheckExact(key) ||
|
||||
(hash = ((PyStringObject *) key)->ob_shash) == -1) {
|
||||
if (!PyUnicode_CheckExact(key) ||
|
||||
(hash = ((PyUnicodeObject *) key)->hash) == -1) {
|
||||
hash = PyObject_Hash(key);
|
||||
if (hash == -1)
|
||||
return -1;
|
||||
|
@ -422,8 +424,9 @@ set_discard_key(PySetObject *so, PyObject *key)
|
|||
PyObject *old_key;
|
||||
|
||||
assert (PyAnySet_Check(so));
|
||||
if (!PyString_CheckExact(key) ||
|
||||
(hash = ((PyStringObject *) key)->ob_shash) == -1) {
|
||||
|
||||
if (!PyUnicode_CheckExact(key) ||
|
||||
(hash = ((PyUnicodeObject *) key)->hash) == -1) {
|
||||
hash = PyObject_Hash(key);
|
||||
if (hash == -1)
|
||||
return -1;
|
||||
|
@ -668,8 +671,8 @@ set_contains_key(PySetObject *so, PyObject *key)
|
|||
long hash;
|
||||
setentry *entry;
|
||||
|
||||
if (!PyString_CheckExact(key) ||
|
||||
(hash = ((PyStringObject *) key)->ob_shash) == -1) {
|
||||
if (!PyUnicode_CheckExact(key) ||
|
||||
(hash = ((PyUnicodeObject *) key)->hash) == -1) {
|
||||
hash = PyObject_Hash(key);
|
||||
if (hash == -1)
|
||||
return -1;
|
||||
|
@ -989,7 +992,7 @@ make_new_set(PyTypeObject *type, PyObject *iterable)
|
|||
INIT_NONZERO_SET_SLOTS(so);
|
||||
}
|
||||
|
||||
so->lookup = set_lookkey_string;
|
||||
so->lookup = set_lookkey_unicode;
|
||||
so->weakreflist = NULL;
|
||||
|
||||
if (iterable != NULL) {
|
||||
|
@ -1352,7 +1355,7 @@ set_isdisjoint(PySetObject *so, PyObject *other)
|
|||
while ((key = PyIter_Next(it)) != NULL) {
|
||||
int rv;
|
||||
setentry entry;
|
||||
long hash = PyObject_Hash(key);
|
||||
long hash = PyObject_Hash(key);;
|
||||
|
||||
if (hash == -1) {
|
||||
Py_DECREF(key);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue