Rev 4724: Do some work to handle comparison to object that aren't tuples or strings. in http://bazaar.launchpad.net/~jameinel/bzr/2.1-static-tuple
John Arbash Meinel
john at arbash-meinel.com
Wed Sep 30 20:43:41 BST 2009
At http://bazaar.launchpad.net/~jameinel/bzr/2.1-static-tuple
------------------------------------------------------------
revno: 4724
revision-id: john at arbash-meinel.com-20090930194334-9rmtwmwimmssqw19
parent: john at arbash-meinel.com-20090930191534-2mi59m6qxtsoaw7j
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 2.1-static-tuple
timestamp: Wed 2009-09-30 14:43:34 -0500
message:
Do some work to handle comparison to object that aren't tuples or strings.
-------------- next part --------------
=== modified file 'bzrlib/_static_tuple_c.c'
--- a/bzrlib/_static_tuple_c.c 2009-09-30 19:15:34 +0000
+++ b/bzrlib/_static_tuple_c.c 2009-09-30 19:43:34 +0000
@@ -304,12 +304,15 @@
* might trigger if '__op__' is defined but '__rop__' is not, sort of
* case. Such as "None == StaticTuple()"
*/
- fprintf(stderr, "self is tuple\n");
+ fprintf(stderr, "self is not StaticTuple\n");
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}
vk = (StaticTuple *)v;
- if (PyTuple_Check(w)) {
+ if (StaticTuple_CheckExact(w)) {
+ /* The most common case */
+ wk = (StaticTuple*)w;
+ } else if (PyTuple_Check(w)) {
/* One of v or w is a tuple, so we go the 'slow' route and cast up to
* tuples to compare.
*/
@@ -318,22 +321,26 @@
* other is a tuple.
*/
return StaticTuple_richcompare_to_tuple(vk, w, op);
- }
- /* TODO: Py_None is one of the other common cases here, we should probably
- * directly support it.
- */
- if (!StaticTuple_CheckExact(w)) {
- /* Both are not StaticTuple objects, and they aren't Tuple objects or the
- * previous path would have been taken. We don't support comparing with
- * anything else.
+ } else if (w == Py_None) {
+ // None is always less than the object
+ switch (op) {
+ case Py_NE:case Py_GT:case Py_GE:
+ Py_INCREF(Py_True);
+ return Py_True;
+ case Py_EQ:case Py_LT:case Py_LE:
+ Py_INCREF(Py_False);
+ return Py_False;
+ }
+ } else {
+ /* We don't special case this comparison, we just let python handle
+ * it.
*/
- fprintf(stderr, "not comparing to key: %s\n", Py_TYPE(w)->tp_name);
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}
/* Now we know that we have 2 StaticTuple objects, so let's compare them.
* This code is somewhat borrowed from tuplerichcompare, except we know our
- * objects are limited in scope, so we cheat a bit.
+ * objects are limited in scope, so we can inline some comparisons.
*/
if (v == w) {
/* Identical pointers, we can shortcut this easily. */
@@ -346,7 +353,6 @@
return Py_False;
}
}
- wk = (StaticTuple*)w;
/* It will be rare that we compare tuples of different lengths, so we don't
* start by optimizing the length comparision, same as the tuple code
=== modified file 'bzrlib/_static_tuple_py.py'
--- a/bzrlib/_static_tuple_py.py 2009-09-30 19:15:34 +0000
+++ b/bzrlib/_static_tuple_py.py 2009-09-30 19:43:34 +0000
@@ -29,7 +29,7 @@
def __new__(cls, *args):
if not args and _empty_tuple is not None:
return _empty_tuple
- return super(StaticTuple, cls).__new__(cls, *args)
+ return object.__new__(cls)
def __init__(self, *args):
"""Create a new 'StaticTuple'"""
=== modified file 'bzrlib/tests/test__static_tuple.py'
--- a/bzrlib/tests/test__static_tuple.py 2009-09-30 19:15:34 +0000
+++ b/bzrlib/tests/test__static_tuple.py 2009-09-30 19:43:34 +0000
@@ -187,6 +187,14 @@
self.assertTrue(k_small <= k_big)
self.assertTrue(k_small < k_big)
+ def test_compare_vs_none(self):
+ k1 = self.module.StaticTuple('baz', 'bing')
+ self.assertCompareDifferent(None, k1)
+ self.assertCompareDifferent(10, k1)
+ # Comparison with a string is poorly-defined, I seem to get failures
+ # regardless of which one comes first...
+ # self.assertCompareDifferent('baz', k1)
+
def test_compare_all_different_same_width(self):
k1 = self.module.StaticTuple('baz', 'bing')
k2 = self.module.StaticTuple('foo', 'bar')
@@ -264,17 +272,37 @@
from meliae import scanner
strs = ['foo', 'bar', 'baz', 'bing']
k = self.module.StaticTuple(*strs)
- if isinstance(k, _static_tuple_py.StaticTuple):
+ if self.module is _static_tuple_py:
# The python version references objects slightly different than the
# compiled version
self.assertEqual([k._tuple, _static_tuple_py.StaticTuple],
scanner.get_referents(k))
+ self.assertEqual(sorted(strs),
+ sorted(scanner.get_referents(k._tuple)))
else:
self.assertEqual(sorted(strs), sorted(scanner.get_referents(k)))
+ def test_nested_referents(self):
+ self.requireFeature(Meliae)
+
def test_empty_is_singleton(self):
key = self.module.StaticTuple()
self.assertIs(key, self.module._empty_tuple)
+ from meliae import scanner
+ strs = ['foo', 'bar', 'baz', 'bing']
+ k1 = self.module.StaticTuple(*strs[:2])
+ k2 = self.module.StaticTuple(*strs[2:])
+ k3 = self.module.StaticTuple(k1, k2)
+ if self.module is _static_tuple_py:
+ # The python version references objects slightly different than the
+ # compiled version
+ self.assertEqual([k3._tuple, _static_tuple_py.StaticTuple],
+ scanner.get_referents(k3))
+ self.assertEqual(sorted([k1, k2]),
+ sorted(scanner.get_referents(k3._tuple)))
+ else:
+ self.assertEqual(sorted([k1, k2]),
+ sorted(scanner.get_referents(k3)))
def test_intern(self):
unique_str1 = 'unique str ' + osutils.rand_chars(20)
More information about the bazaar-commits
mailing list