summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorLarry Hastings <larry@hastings.org>2014-01-06 15:24:19 (GMT)
committerLarry Hastings <larry@hastings.org>2014-01-06 15:24:19 (GMT)
commitb7f5dcadf2a929a92cfd5d0386426bc143cb01b4 (patch)
treed3ee3564eac5ff32bf9db2f90907f1979969918b /Objects
parente7ee44e9ba36fe6220ebb31c5c7faad5cfb2a250 (diff)
parent74fc8c47f66da5673ed733d21e9014e9508f2819 (diff)
downloadcpython-b7f5dcadf2a929a92cfd5d0386426bc143cb01b4.zip
cpython-b7f5dcadf2a929a92cfd5d0386426bc143cb01b4.tar.gz
cpython-b7f5dcadf2a929a92cfd5d0386426bc143cb01b4.tar.bz2
Merge 3.4.0b2 release revisions back into mainline.
Diffstat (limited to 'Objects')
-rw-r--r--Objects/setobject.c15
-rw-r--r--Objects/unicodeobject.c35
2 files changed, 41 insertions, 9 deletions
diff --git a/Objects/setobject.c b/Objects/setobject.c
index b0803f6..fa6a6d0 100644
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -738,6 +738,17 @@ set_traverse(PySetObject *so, visitproc visit, void *arg)
static Py_hash_t
frozenset_hash(PyObject *self)
{
+ /* Most of the constants in this hash algorithm are randomly choosen
+ large primes with "interesting bit patterns" and that passed
+ tests for good collision statistics on a variety of problematic
+ datasets such as:
+
+ ps = []
+ for r in range(21):
+ ps += itertools.combinations(range(20), r)
+ num_distinct_hashes = len({hash(frozenset(s)) for s in ps})
+
+ */
PySetObject *so = (PySetObject *)self;
Py_uhash_t h, hash = 1927868237UL;
setentry *entry;
@@ -754,8 +765,10 @@ frozenset_hash(PyObject *self)
hashes so that many distinct combinations collapse to only
a handful of distinct hash values. */
h = entry->hash;
- hash ^= (h ^ (h << 16) ^ 89869747UL) * 3644798167UL;
+ hash ^= ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
}
+ /* Make the final result spread-out in a different pattern
+ than the algorithem for tuples or other python objects. */
hash = hash * 69069U + 907133923UL;
if (hash == -1)
hash = 590923713UL;
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index cdbaa0c..fc6f0d0 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -13988,7 +13988,7 @@ formatlong(PyObject *val, struct unicode_format_arg_t *arg)
return result;
}
-/* Format an integer.
+/* Format an integer or a float as an integer.
* Return 1 if the number has been formatted into the writer,
* 0 if the number has been formatted into *p_output
* -1 and raise an exception on error */
@@ -14005,11 +14005,19 @@ mainformatlong(PyObject *v,
goto wrongtype;
if (!PyLong_Check(v)) {
- iobj = PyNumber_Long(v);
- if (iobj == NULL) {
- if (PyErr_ExceptionMatches(PyExc_TypeError))
- goto wrongtype;
- return -1;
+ if (type == 'o' || type == 'x' || type == 'X') {
+ iobj = PyNumber_Index(v);
+ if (iobj == NULL) {
+ return -1;
+ }
+ }
+ else {
+ iobj = PyNumber_Long(v);
+ if (iobj == NULL ) {
+ if (PyErr_ExceptionMatches(PyExc_TypeError))
+ goto wrongtype;
+ return -1;
+ }
}
assert(PyLong_Check(iobj));
}
@@ -14079,8 +14087,18 @@ formatchar(PyObject *v)
goto onError;
}
else {
- /* Integer input truncated to a character */
+ PyObject *iobj;
long x;
+ /* make sure number is a type of integer */
+ if (!PyLong_Check(v)) {
+ iobj = PyNumber_Index(v);
+ if (iobj == NULL) {
+ goto onError;
+ }
+ v = iobj;
+ Py_DECREF(iobj);
+ }
+ /* Integer input truncated to a character */
x = PyLong_AsLong(v);
if (x == -1 && PyErr_Occurred())
goto onError;
@@ -14282,7 +14300,8 @@ unicode_format_arg_parse(struct unicode_formatter_t *ctx,
/* Format one argument. Supported conversion specifiers:
- "s", "r", "a": any type
- - "i", "d", "u", "o", "x", "X": int
+ - "i", "d", "u": int or float
+ - "o", "x", "X": int
- "e", "E", "f", "F", "g", "G": float
- "c": int or str (1 character)