from test
.test_support
import verbose
from UserList
import UserList
def check(tag
, expected
, raw
, compare
=None):
orig
= raw
[:] # save input in case of error
if len(expected
) != len(raw
):
print "length mismatch;", len(expected
), len(raw
)
for i
, good
in enumerate(expected
):
print "out of order at index", i
, good
, maybe
# Try a variety of sizes at and around powers of 2, and at powers of 10.
for power
in range(1, 10):
sizes
.extend(range(n
-1, n
+2))
sizes
.extend([10, 100, 1000])
if Complains
.maybe_complain
and random
.random() < 0.001:
print " complaining at", self
, other
return "Complains(%d)" % self
.i
def __init__(self
, key
, i
):
def __cmp__(self
, other
):
return cmp(self
.key
, other
.key
)
return "Stable(%d, %d)" % (self
.key
, self
.index
)
check("random permutation", x
, s
)
check("reversed via function", y
, s
, lambda a
, b
: cmp(b
, a
))
print " Checking against an insane comparison function."
print " If the implementation isn't careful, this may segfault."
s
.sort(lambda a
, b
: int(random
.random() * 3) - 1)
check("an insane function left some permutation", x
, s
)
x
= [Complains(i
) for i
in x
]
Complains
.maybe_complain
= True
Complains
.maybe_complain
= False
check("exception during sort left some permutation", x
, s
)
s
= [Stable(random
.randrange(10), i
) for i
in xrange(n
)]
augmented
= [(e
, e
.index
) for e
in s
]
augmented
.sort() # forced stable because ties broken by index
x
= [e
for e
, i
in augmented
] # a stable sort of s
from test
import test_support
#==============================================================================
class TestBugs(unittest
.TestCase
):
def test_bug453523(self
):
# bug 453523 -- list.sort() crasher.
# If this fails, the most likely outcome is a core dump.
# Mutations during a list sort should raise a ValueError.
if L
and random
.random() < 0.75:
return random
.random() < 0.5
L
= [C() for i
in range(50)]
self
.assertRaises(ValueError, L
.sort
)
# Testing None as a comparison function.
self
.assertEqual(L
, range(50))
def test_undetected_mutation(self
):
# Python 2.4a1 did not always detect mutation
self
.assertRaises(ValueError, L
.sort
, mutating_cmp
)
self
.assertRaises(ValueError, L
.sort
, mutating_cmp
)
memorywaster
= [memorywaster
]
#==============================================================================
class TestDecorateSortUndecorate(unittest
.TestCase
):
def test_decorated(self
):
data
= 'The quick Brown fox Jumped over The lazy Dog'.split()
copy
.sort(cmp=lambda x
,y
: cmp(x
.lower(), y
.lower()))
def test_baddecorator(self
):
data
= 'The quick Brown fox Jumped over The lazy Dog'.split()
self
.assertRaises(TypeError, data
.sort
, None, lambda x
,y
: 0)
def test_stability(self
):
data
= [(random
.randrange(100), i
) for i
in xrange(200)]
data
.sort(key
=lambda (x
,y
): x
) # sort on the random first field
copy
.sort() # sort using both fields
self
.assertEqual(data
, copy
) # should get the same result
def test_cmp_and_key_combination(self
):
# Verify that the wrapper has been removed
self
.assertEqual(type(x
), str)
self
.assertEqual(type(x
), str)
data
= 'The quick Brown fox Jumped over The lazy Dog'.split()
data
.sort(cmp=compare
, key
=str.lower
)
def test_badcmp_with_key(self
):
# Verify that the wrapper has been removed
data
= 'The quick Brown fox Jumped over The lazy Dog'.split()
self
.assertRaises(TypeError, data
.sort
, "bad", str.lower
)
def test_key_with_exception(self
):
# Verify that the wrapper has been removed
self
.assertRaises(ZeroDivisionError, data
.sort
, None, lambda x
: 1/x
)
self
.assertEqual(data
, dup
)
def test_key_with_mutation(self
):
self
.assertRaises(ValueError, data
.sort
, key
=k
)
def test_key_with_mutating_del(self
):
class SortKiller(object):
self
.assertRaises(ValueError, data
.sort
, key
=SortKiller
)
def test_key_with_mutating_del_and_exception(self
):
class SortKiller(object):
self
.assertRaises(RuntimeError, data
.sort
, key
=SortKiller
)
## major honking subtlety: we *can't* do:
## self.assertEqual(data, dup)
## because there is a reference to a SortKiller in the
## traceback and by the time it dies we're outside the call to
## .sort() and so the list protection gimmicks are out of
## date (this cost some brain cells to figure out...).
self
.assertEqual(data
, range(99,-1,-1))
self
.assertRaises(TypeError, data
.sort
, "wrong type")
def test_reverse_stability(self
):
data
= [(random
.randrange(100), i
) for i
in xrange(200)]
data
.sort(cmp=lambda x
,y
: cmp(x
[0],y
[0]), reverse
=True)
copy1
.sort(cmp=lambda x
,y
: cmp(y
[0],x
[0]))
self
.assertEqual(data
, copy1
)
copy2
.sort(key
=lambda x
: x
[0], reverse
=True)
self
.assertEqual(data
, copy2
)
#==============================================================================
def test_main(verbose
=None):
TestDecorateSortUndecorate
,
test_support
.run_unittest(*test_classes
)
# verify reference counting
if verbose
and hasattr(sys
, "gettotalrefcount"):
for i
in xrange(len(counts
)):
test_support
.run_unittest(*test_classes
)
counts
[i
] = sys
.gettotalrefcount()
if __name__
== "__main__":