183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom test.test_support import verbose, TESTFN
283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport random
383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport os
483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# From SF bug #422121:  Insecurities in dict comparison.
683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Safety of code doing comparisons has been an historical Python weak spot.
883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# The problem is that comparison of structures written in C *naturally*
983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# wants to hold on to things like the size of the container, or "the
1083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# biggest" containee so far, across a traversal of the container; but
1183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# code to do containee comparisons can call back into Python and mutate
1283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# the container in arbitrary ways while the C loop is in midstream.  If the
1383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# C code isn't extremely paranoid about digging things out of memory on
1483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# each trip, and artificially boosting refcounts for the duration, anything
1583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# from infinite loops to OS crashes can result (yes, I use Windows <wink>).
1683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#
1783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# The other problem is that code designed to provoke a weakness is usually
1883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# white-box code, and so catches only the particular vulnerabilities the
1983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# author knew to protect against.  For example, Python's list.sort() code
2083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# went thru many iterations as one "new" vulnerability after another was
2183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# discovered.
2283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#
2383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# So the dict comparison test here uses a black-box approach instead,
2483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# generating dicts of various sizes at random, and performing random
2583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# mutations on them at random times.  This proved very effective,
2683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# triggering at least six distinct failure modes the first 20 times I
2783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# ran it.  Indeed, at the start, the driver never got beyond 6 iterations
2883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# before the test died.
2983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
3083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# The dicts are global to make it easy to mutate tham from within functions.
3183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdict1 = {}
3283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdict2 = {}
3383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
3483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# The current set of keys in dict1 and dict2.  These are materialized as
3583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# lists to make it easy to pick a dict key at random.
3683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdict1keys = []
3783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdict2keys = []
3883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
3983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Global flag telling maybe_mutate() whether to *consider* mutating.
4083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehmutate = 0
4183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
4283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# If global mutate is true, consider mutating a dict.  May or may not
4383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# mutate a dict even if mutate is true.  If it does decide to mutate a
4483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# dict, it picks one of {dict1, dict2} at random, and deletes a random
4583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# entry from it; or, more rarely, adds a random element.
4683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
4783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef maybe_mutate():
4883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    global mutate
4983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if not mutate:
5083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return
5183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if random.random() < 0.5:
5283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return
5383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
5483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if random.random() < 0.5:
5583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        target, keys = dict1, dict1keys
5683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    else:
5783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        target, keys = dict2, dict2keys
5883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
5983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if random.random() < 0.2:
6083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Insert a new key.
6183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        mutate = 0   # disable mutation until key inserted
6283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        while 1:
6383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            newkey = Horrid(random.randrange(100))
6483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if newkey not in target:
6583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                break
6683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        target[newkey] = Horrid(random.randrange(100))
6783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        keys.append(newkey)
6883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        mutate = 1
6983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
7083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    elif keys:
7183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Delete a key at random.
7283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        mutate = 0   # disable mutation until key deleted
7383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        i = random.randrange(len(keys))
7483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        key = keys[i]
7583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        del target[key]
7683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        del keys[i]
7783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        mutate = 1
7883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
7983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# A horrid class that triggers random mutations of dict1 and dict2 when
8083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# instances are compared.
8183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
8283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass Horrid:
8383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def __init__(self, i):
8483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Comparison outcomes are determined by the value of i.
8583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.i = i
8683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
8783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # An artificial hashcode is selected at random so that we don't
8883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # have any systematic relationship between comparison outcomes
8983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # (based on self.i and other.i) and relative position within the
9083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # hash vector (based on hashcode).
9183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.hashcode = random.randrange(1000000000)
9283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
9383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def __hash__(self):
9483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return 42
9583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return self.hashcode
9683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
9783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def __cmp__(self, other):
9883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        maybe_mutate()   # The point of the test.
9983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return cmp(self.i, other.i)
10083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
10183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def __eq__(self, other):
10283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        maybe_mutate()   # The point of the test.
10383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return self.i == other.i
10483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
10583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def __repr__(self):
10683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return "Horrid(%d)" % self.i
10783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
10883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Fill dict d with numentries (Horrid(i), Horrid(j)) key-value pairs,
10983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# where i and j are selected at random from the candidates list.
11083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Return d.keys() after filling.
11183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
11283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef fill_dict(d, candidates, numentries):
11383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    d.clear()
11483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    for i in xrange(numentries):
11583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        d[Horrid(random.choice(candidates))] = \
11683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            Horrid(random.choice(candidates))
11783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    return d.keys()
11883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
11983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Test one pair of randomly generated dicts, each with n entries.
12083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Note that dict comparison is trivial if they don't have the same number
12183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# of entires (then the "shorter" dict is instantly considered to be the
12283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# smaller one, without even looking at the entries).
12383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
12483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef test_one(n):
12583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    global mutate, dict1, dict2, dict1keys, dict2keys
12683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
12783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Fill the dicts without mutating them.
12883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    mutate = 0
12983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    dict1keys = fill_dict(dict1, range(n), n)
13083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    dict2keys = fill_dict(dict2, range(n), n)
13183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
13283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Enable mutation, then compare the dicts so long as they have the
13383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # same size.
13483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    mutate = 1
13583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if verbose:
13683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        print "trying w/ lengths", len(dict1), len(dict2),
13783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    while dict1 and len(dict1) == len(dict2):
13883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if verbose:
13983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            print ".",
14083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if random.random() < 0.5:
14183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            c = cmp(dict1, dict2)
14283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
14383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            c = dict1 == dict2
14483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    if verbose:
14583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        print
14683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
14783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Run test_one n times.  At the start (before the bugs were fixed), 20
14883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# consecutive runs of this test each blew up on or before the sixth time
14983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# test_one was run.  So n doesn't have to be large to get an interesting
15083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# test.
15183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# OTOH, calling with large n is also interesting, to ensure that the fixed
15283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# code doesn't hold on to refcounts *too* long (in which case memory would
15383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# leak).
15483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
15583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef test(n):
15683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    for i in xrange(n):
15783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        test_one(random.randrange(1, 100))
15883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
15983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# See last comment block for clues about good values for n.
16083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehtest(100)
16183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
16283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh##########################################################################
16383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Another segfault bug, distilled by Michael Hudson from a c.l.py post.
16483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
16583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass Child:
16683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def __init__(self, parent):
16783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.__dict__['parent'] = parent
16883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def __getattr__(self, attr):
16983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.parent.a = 1
17083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.parent.b = 1
17183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.parent.c = 1
17283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.parent.d = 1
17383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.parent.e = 1
17483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.parent.f = 1
17583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.parent.g = 1
17683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.parent.h = 1
17783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.parent.i = 1
17883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return getattr(self.parent, attr)
17983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
18083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass Parent:
18183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def __init__(self):
18283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.a = Child(self)
18383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
18483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Hard to say what this will print!  May vary from time to time.  But
18583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# we're specifically trying to test the tp_print slot here, and this is
18683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# the clearest way to do it.  We print the result to a temp file so that
18783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# the expected-output file doesn't need to change.
18883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
18983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehf = open(TESTFN, "w")
19083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehprint >> f, Parent().__dict__
19183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehf.close()
19283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehos.unlink(TESTFN)
19383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
19483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh##########################################################################
19583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# And another core-dumper from Michael Hudson.
19683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
19783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdict = {}
19883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
19983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Force dict to malloc its table.
20083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfor i in range(1, 10):
20183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    dict[i] = i
20283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
20383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehf = open(TESTFN, "w")
20483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
20583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass Machiavelli:
20683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def __repr__(self):
20783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        dict.clear()
20883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
20983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Michael sez:  "doesn't crash without this.  don't know why."
21083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Tim sez:  "luck of the draw; crashes with or without for me."
21183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        print >> f
21283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
21383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return repr("machiavelli")
21483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
21583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def __hash__(self):
21683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return 0
21783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
21883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdict[Machiavelli()] = Machiavelli()
21983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
22083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehprint >> f, str(dict)
22183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehf.close()
22283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehos.unlink(TESTFN)
22383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdel f, dict
22483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
22583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
22683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh##########################################################################
22783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# And another core-dumper from Michael Hudson.
22883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
22983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdict = {}
23083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
23183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# let's force dict to malloc its table
23283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfor i in range(1, 10):
23383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    dict[i] = i
23483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
23583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass Machiavelli2:
23683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def __eq__(self, other):
23783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        dict.clear()
23883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return 1
23983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
24083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def __hash__(self):
24183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return 0
24283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
24383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdict[Machiavelli2()] = Machiavelli2()
24483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
24583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehtry:
24683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    dict[Machiavelli2()]
24783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehexcept KeyError:
24883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    pass
24983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
25083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdel dict
25183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
25283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh##########################################################################
25383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# And another core-dumper from Michael Hudson.
25483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
25583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdict = {}
25683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
25783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# let's force dict to malloc its table
25883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfor i in range(1, 10):
25983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    dict[i] = i
26083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
26183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass Machiavelli3:
26283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def __init__(self, id):
26383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.id = id
26483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
26583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def __eq__(self, other):
26683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if self.id == other.id:
26783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            dict.clear()
26883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            return 1
26983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
27083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            return 0
27183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
27283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def __repr__(self):
27383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return "%s(%s)"%(self.__class__.__name__, self.id)
27483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
27583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def __hash__(self):
27683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return 0
27783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
27883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdict[Machiavelli3(1)] = Machiavelli3(0)
27983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdict[Machiavelli3(2)] = Machiavelli3(0)
28083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
28183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehf = open(TESTFN, "w")
28283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehtry:
28383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    try:
28483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        print >> f, dict[Machiavelli3(2)]
28583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    except KeyError:
28683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        pass
28783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfinally:
28883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    f.close()
28983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    os.unlink(TESTFN)
29083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
29183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdel dict
29283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdel dict1, dict2, dict1keys, dict2keys
293