Commits

Lukas Diekmann committed fa72864 Merge

merged pypy-default

Comments (0)

Files changed (161)

     Jim Baker
     Philip Jenvey
     Rodrigo Araújo
+    Brett Cannon
 
     Heinrich-Heine University, Germany 
     Open End AB (formerly AB Strakt), Sweden

lib-python/modified-2.7/pickle.py

 
 # Pickling machinery
 
-class Pickler:
+class Pickler(object):
 
     def __init__(self, file, protocol=None):
         """This takes a file-like object for writing a pickle data stream.

lib-python/modified-2.7/test/test_sets.py

+#!/usr/bin/env python
+
+import unittest, operator, copy, pickle, random
+from test import test_support
+
+test_support.import_module("sets", deprecated=True)
+from sets import Set, ImmutableSet
+
+empty_set = Set()
+
+#==============================================================================
+
+class TestBasicOps(unittest.TestCase):
+
+    def test_repr(self):
+        if self.repr is not None:
+            self.assertEqual(repr(self.set), self.repr)
+
+    def test_length(self):
+        self.assertEqual(len(self.set), self.length)
+
+    def test_self_equality(self):
+        self.assertEqual(self.set, self.set)
+
+    def test_equivalent_equality(self):
+        self.assertEqual(self.set, self.dup)
+
+    def test_copy(self):
+        self.assertEqual(self.set.copy(), self.dup)
+
+    def test_self_union(self):
+        result = self.set | self.set
+        self.assertEqual(result, self.dup)
+
+    def test_empty_union(self):
+        result = self.set | empty_set
+        self.assertEqual(result, self.dup)
+
+    def test_union_empty(self):
+        result = empty_set | self.set
+        self.assertEqual(result, self.dup)
+
+    def test_self_intersection(self):
+        result = self.set & self.set
+        self.assertEqual(result, self.dup)
+
+    def test_empty_intersection(self):
+        result = self.set & empty_set
+        self.assertEqual(result, empty_set)
+
+    def test_intersection_empty(self):
+        result = empty_set & self.set
+        self.assertEqual(result, empty_set)
+
+    def test_self_symmetric_difference(self):
+        result = self.set ^ self.set
+        self.assertEqual(result, empty_set)
+
+    def checkempty_symmetric_difference(self):
+        result = self.set ^ empty_set
+        self.assertEqual(result, self.set)
+
+    def test_self_difference(self):
+        result = self.set - self.set
+        self.assertEqual(result, empty_set)
+
+    def test_empty_difference(self):
+        result = self.set - empty_set
+        self.assertEqual(result, self.dup)
+
+    def test_empty_difference_rev(self):
+        result = empty_set - self.set
+        self.assertEqual(result, empty_set)
+
+    def test_iteration(self):
+        for v in self.set:
+            self.assertIn(v, self.values)
+
+    def test_pickling(self):
+        p = pickle.dumps(self.set)
+        copy = pickle.loads(p)
+        self.assertEqual(self.set, copy,
+                         "%s != %s" % (self.set, copy))
+
+#------------------------------------------------------------------------------
+
+class TestBasicOpsEmpty(TestBasicOps):
+    def setUp(self):
+        self.case   = "empty set"
+        self.values = []
+        self.set    = Set(self.values)
+        self.dup    = Set(self.values)
+        self.length = 0
+        self.repr   = "Set([])"
+
+#------------------------------------------------------------------------------
+
+class TestBasicOpsSingleton(TestBasicOps):
+    def setUp(self):
+        self.case   = "unit set (number)"
+        self.values = [3]
+        self.set    = Set(self.values)
+        self.dup    = Set(self.values)
+        self.length = 1
+        self.repr   = "Set([3])"
+
+    def test_in(self):
+        self.assertTrue(3 in self.set)
+
+    def test_not_in(self):
+        self.assertTrue(2 not in self.set)
+
+#------------------------------------------------------------------------------
+
+class TestBasicOpsTuple(TestBasicOps):
+    def setUp(self):
+        self.case   = "unit set (tuple)"
+        self.values = [(0, "zero")]
+        self.set    = Set(self.values)
+        self.dup    = Set(self.values)
+        self.length = 1
+        self.repr   = "Set([(0, 'zero')])"
+
+    def test_in(self):
+        self.assertTrue((0, "zero") in self.set)
+
+    def test_not_in(self):
+        self.assertTrue(9 not in self.set)
+
+#------------------------------------------------------------------------------
+
+class TestBasicOpsTriple(TestBasicOps):
+    def setUp(self):
+        self.case   = "triple set"
+        self.values = [0, "zero", operator.add]
+        self.set    = Set(self.values)
+        self.dup    = Set(self.values)
+        self.length = 3
+        self.repr   = None
+
+#==============================================================================
+
+def baditer():
+    raise TypeError
+    yield True
+
+def gooditer():
+    yield True
+
+class TestExceptionPropagation(unittest.TestCase):
+    """SF 628246:  Set constructor should not trap iterator TypeErrors"""
+
+    def test_instanceWithException(self):
+        self.assertRaises(TypeError, Set, baditer())
+
+    def test_instancesWithoutException(self):
+        # All of these iterables should load without exception.
+        Set([1,2,3])
+        Set((1,2,3))
+        Set({'one':1, 'two':2, 'three':3})
+        Set(xrange(3))
+        Set('abc')
+        Set(gooditer())
+
+#==============================================================================
+
+class TestSetOfSets(unittest.TestCase):
+    def test_constructor(self):
+        inner = Set([1])
+        outer = Set([inner])
+        element = outer.pop()
+        self.assertEqual(type(element), ImmutableSet)
+        outer.add(inner)        # Rebuild set of sets with .add method
+        outer.remove(inner)
+        self.assertEqual(outer, Set())   # Verify that remove worked
+        outer.discard(inner)    # Absence of KeyError indicates working fine
+
+#==============================================================================
+
+class TestBinaryOps(unittest.TestCase):
+    def setUp(self):
+        self.set = Set((2, 4, 6))
+
+    def test_eq(self):              # SF bug 643115
+        self.assertEqual(self.set, Set({2:1,4:3,6:5}))
+
+    def test_union_subset(self):
+        result = self.set | Set([2])
+        self.assertEqual(result, Set((2, 4, 6)))
+
+    def test_union_superset(self):
+        result = self.set | Set([2, 4, 6, 8])
+        self.assertEqual(result, Set([2, 4, 6, 8]))
+
+    def test_union_overlap(self):
+        result = self.set | Set([3, 4, 5])
+        self.assertEqual(result, Set([2, 3, 4, 5, 6]))
+
+    def test_union_non_overlap(self):
+        result = self.set | Set([8])
+        self.assertEqual(result, Set([2, 4, 6, 8]))
+
+    def test_intersection_subset(self):
+        result = self.set & Set((2, 4))
+        self.assertEqual(result, Set((2, 4)))
+
+    def test_intersection_superset(self):
+        result = self.set & Set([2, 4, 6, 8])
+        self.assertEqual(result, Set([2, 4, 6]))
+
+    def test_intersection_overlap(self):
+        result = self.set & Set([3, 4, 5])
+        self.assertEqual(result, Set([4]))
+
+    def test_intersection_non_overlap(self):
+        result = self.set & Set([8])
+        self.assertEqual(result, empty_set)
+
+    def test_sym_difference_subset(self):
+        result = self.set ^ Set((2, 4))
+        self.assertEqual(result, Set([6]))
+
+    def test_sym_difference_superset(self):
+        result = self.set ^ Set((2, 4, 6, 8))
+        self.assertEqual(result, Set([8]))
+
+    def test_sym_difference_overlap(self):
+        result = self.set ^ Set((3, 4, 5))
+        self.assertEqual(result, Set([2, 3, 5, 6]))
+
+    def test_sym_difference_non_overlap(self):
+        result = self.set ^ Set([8])
+        self.assertEqual(result, Set([2, 4, 6, 8]))
+
+    def test_cmp(self):
+        a, b = Set('a'), Set('b')
+        self.assertRaises(TypeError, cmp, a, b)
+
+        # You can view this as a buglet:  cmp(a, a) does not raise TypeError,
+        # because __eq__ is tried before __cmp__, and a.__eq__(a) returns True,
+        # which Python thinks is good enough to synthesize a cmp() result
+        # without calling __cmp__.
+        self.assertEqual(cmp(a, a), 0)
+
+        self.assertRaises(TypeError, cmp, a, 12)
+        self.assertRaises(TypeError, cmp, "abc", a)
+
+    def test_inplace_on_self(self):
+        t = self.set.copy()
+        t |= t
+        self.assertEqual(t, self.set)
+        t &= t
+        self.assertEqual(t, self.set)
+        t -= t
+        self.assertEqual(len(t), 0)
+        t = self.set.copy()
+        t ^= t
+        self.assertEqual(len(t), 0)
+
+
+#==============================================================================
+
+class TestUpdateOps(unittest.TestCase):
+    def setUp(self):
+        self.set = Set((2, 4, 6))
+
+    def test_union_subset(self):
+        self.set |= Set([2])
+        self.assertEqual(self.set, Set((2, 4, 6)))
+
+    def test_union_superset(self):
+        self.set |= Set([2, 4, 6, 8])
+        self.assertEqual(self.set, Set([2, 4, 6, 8]))
+
+    def test_union_overlap(self):
+        self.set |= Set([3, 4, 5])
+        self.assertEqual(self.set, Set([2, 3, 4, 5, 6]))
+
+    def test_union_non_overlap(self):
+        self.set |= Set([8])
+        self.assertEqual(self.set, Set([2, 4, 6, 8]))
+
+    def test_union_method_call(self):
+        self.set.union_update(Set([3, 4, 5]))
+        self.assertEqual(self.set, Set([2, 3, 4, 5, 6]))
+
+    def test_intersection_subset(self):
+        self.set &= Set((2, 4))
+        self.assertEqual(self.set, Set((2, 4)))
+
+    def test_intersection_superset(self):
+        self.set &= Set([2, 4, 6, 8])
+        self.assertEqual(self.set, Set([2, 4, 6]))
+
+    def test_intersection_overlap(self):
+        self.set &= Set([3, 4, 5])
+        self.assertEqual(self.set, Set([4]))
+
+    def test_intersection_non_overlap(self):
+        self.set &= Set([8])
+        self.assertEqual(self.set, empty_set)
+
+    def test_intersection_method_call(self):
+        self.set.intersection_update(Set([3, 4, 5]))
+        self.assertEqual(self.set, Set([4]))
+
+    def test_sym_difference_subset(self):
+        self.set ^= Set((2, 4))
+        self.assertEqual(self.set, Set([6]))
+
+    def test_sym_difference_superset(self):
+        self.set ^= Set((2, 4, 6, 8))
+        self.assertEqual(self.set, Set([8]))
+
+    def test_sym_difference_overlap(self):
+        self.set ^= Set((3, 4, 5))
+        self.assertEqual(self.set, Set([2, 3, 5, 6]))
+
+    def test_sym_difference_non_overlap(self):
+        self.set ^= Set([8])
+        self.assertEqual(self.set, Set([2, 4, 6, 8]))
+
+    def test_sym_difference_method_call(self):
+        self.set.symmetric_difference_update(Set([3, 4, 5]))
+        self.assertEqual(self.set, Set([2, 3, 5, 6]))
+
+    def test_difference_subset(self):
+        self.set -= Set((2, 4))
+        self.assertEqual(self.set, Set([6]))
+
+    def test_difference_superset(self):
+        self.set -= Set((2, 4, 6, 8))
+        self.assertEqual(self.set, Set([]))
+
+    def test_difference_overlap(self):
+        self.set -= Set((3, 4, 5))
+        self.assertEqual(self.set, Set([2, 6]))
+
+    def test_difference_non_overlap(self):
+        self.set -= Set([8])
+        self.assertEqual(self.set, Set([2, 4, 6]))
+
+    def test_difference_method_call(self):
+        self.set.difference_update(Set([3, 4, 5]))
+        self.assertEqual(self.set, Set([2, 6]))
+
+#==============================================================================
+
+class TestMutate(unittest.TestCase):
+    def setUp(self):
+        self.values = ["a", "b", "c"]
+        self.set = Set(self.values)
+
+    def test_add_present(self):
+        self.set.add("c")
+        self.assertEqual(self.set, Set("abc"))
+
+    def test_add_absent(self):
+        self.set.add("d")
+        self.assertEqual(self.set, Set("abcd"))
+
+    def test_add_until_full(self):
+        tmp = Set()
+        expected_len = 0
+        for v in self.values:
+            tmp.add(v)
+            expected_len += 1
+            self.assertEqual(len(tmp), expected_len)
+        self.assertEqual(tmp, self.set)
+
+    def test_remove_present(self):
+        self.set.remove("b")
+        self.assertEqual(self.set, Set("ac"))
+
+    def test_remove_absent(self):
+        try:
+            self.set.remove("d")
+            self.fail("Removing missing element should have raised LookupError")
+        except LookupError:
+            pass
+
+    def test_remove_until_empty(self):
+        expected_len = len(self.set)
+        for v in self.values:
+            self.set.remove(v)
+            expected_len -= 1
+            self.assertEqual(len(self.set), expected_len)
+
+    def test_discard_present(self):
+        self.set.discard("c")
+        self.assertEqual(self.set, Set("ab"))
+
+    def test_discard_absent(self):
+        self.set.discard("d")
+        self.assertEqual(self.set, Set("abc"))
+
+    def test_clear(self):
+        self.set.clear()
+        self.assertEqual(len(self.set), 0)
+
+    def test_pop(self):
+        popped = {}
+        while self.set:
+            popped[self.set.pop()] = None
+        self.assertEqual(len(popped), len(self.values))
+        for v in self.values:
+            self.assertIn(v, popped)
+
+    def test_update_empty_tuple(self):
+        self.set.union_update(())
+        self.assertEqual(self.set, Set(self.values))
+
+    def test_update_unit_tuple_overlap(self):
+        self.set.union_update(("a",))
+        self.assertEqual(self.set, Set(self.values))
+
+    def test_update_unit_tuple_non_overlap(self):
+        self.set.union_update(("a", "z"))
+        self.assertEqual(self.set, Set(self.values + ["z"]))
+
+#==============================================================================
+
+class TestSubsets(unittest.TestCase):
+
+    case2method = {"<=": "issubset",
+                   ">=": "issuperset",
+                  }
+
+    reverse = {"==": "==",
+               "!=": "!=",
+               "<":  ">",
+               ">":  "<",
+               "<=": ">=",
+               ">=": "<=",
+              }
+
+    def test_issubset(self):
+        x = self.left
+        y = self.right
+        for case in "!=", "==", "<", "<=", ">", ">=":
+            expected = case in self.cases
+            # Test the binary infix spelling.
+            result = eval("x" + case + "y", locals())
+            self.assertEqual(result, expected)
+            # Test the "friendly" method-name spelling, if one exists.
+            if case in TestSubsets.case2method:
+                method = getattr(x, TestSubsets.case2method[case])
+                result = method(y)
+                self.assertEqual(result, expected)
+
+            # Now do the same for the operands reversed.
+            rcase = TestSubsets.reverse[case]
+            result = eval("y" + rcase + "x", locals())
+            self.assertEqual(result, expected)
+            if rcase in TestSubsets.case2method:
+                method = getattr(y, TestSubsets.case2method[rcase])
+                result = method(x)
+                self.assertEqual(result, expected)
+#------------------------------------------------------------------------------
+
+class TestSubsetEqualEmpty(TestSubsets):
+    left  = Set()
+    right = Set()
+    name  = "both empty"
+    cases = "==", "<=", ">="
+
+#------------------------------------------------------------------------------
+
+class TestSubsetEqualNonEmpty(TestSubsets):
+    left  = Set([1, 2])
+    right = Set([1, 2])
+    name  = "equal pair"
+    cases = "==", "<=", ">="
+
+#------------------------------------------------------------------------------
+
+class TestSubsetEmptyNonEmpty(TestSubsets):
+    left  = Set()
+    right = Set([1, 2])
+    name  = "one empty, one non-empty"
+    cases = "!=", "<", "<="
+
+#------------------------------------------------------------------------------
+
+class TestSubsetPartial(TestSubsets):
+    left  = Set([1])
+    right = Set([1, 2])
+    name  = "one a non-empty proper subset of other"
+    cases = "!=", "<", "<="
+
+#------------------------------------------------------------------------------
+
+class TestSubsetNonOverlap(TestSubsets):
+    left  = Set([1])
+    right = Set([2])
+    name  = "neither empty, neither contains"
+    cases = "!="
+
+#==============================================================================
+
+class TestOnlySetsInBinaryOps(unittest.TestCase):
+
+    def test_eq_ne(self):
+        # Unlike the others, this is testing that == and != *are* allowed.
+        self.assertEqual(self.other == self.set, False)
+        self.assertEqual(self.set == self.other, False)
+        self.assertEqual(self.other != self.set, True)
+        self.assertEqual(self.set != self.other, True)
+
+    def test_ge_gt_le_lt(self):
+        self.assertRaises(TypeError, lambda: self.set < self.other)
+        self.assertRaises(TypeError, lambda: self.set <= self.other)
+        self.assertRaises(TypeError, lambda: self.set > self.other)
+        self.assertRaises(TypeError, lambda: self.set >= self.other)
+
+        self.assertRaises(TypeError, lambda: self.other < self.set)
+        self.assertRaises(TypeError, lambda: self.other <= self.set)
+        self.assertRaises(TypeError, lambda: self.other > self.set)
+        self.assertRaises(TypeError, lambda: self.other >= self.set)
+
+    def test_union_update_operator(self):
+        try:
+            self.set |= self.other
+        except TypeError:
+            pass
+        else:
+            self.fail("expected TypeError")
+
+    def test_union_update(self):
+        if self.otherIsIterable:
+            self.set.union_update(self.other)
+        else:
+            self.assertRaises(TypeError, self.set.union_update, self.other)
+
+    def test_union(self):
+        self.assertRaises(TypeError, lambda: self.set | self.other)
+        self.assertRaises(TypeError, lambda: self.other | self.set)
+        if self.otherIsIterable:
+            self.set.union(self.other)
+        else:
+            self.assertRaises(TypeError, self.set.union, self.other)
+
+    def test_intersection_update_operator(self):
+        try:
+            self.set &= self.other
+        except TypeError:
+            pass
+        else:
+            self.fail("expected TypeError")
+
+    def test_intersection_update(self):
+        if self.otherIsIterable:
+            self.set.intersection_update(self.other)
+        else:
+            self.assertRaises(TypeError,
+                              self.set.intersection_update,
+                              self.other)
+
+    def test_intersection(self):
+        self.assertRaises(TypeError, lambda: self.set & self.other)
+        self.assertRaises(TypeError, lambda: self.other & self.set)
+        if self.otherIsIterable:
+            self.set.intersection(self.other)
+        else:
+            self.assertRaises(TypeError, self.set.intersection, self.other)
+
+    def test_sym_difference_update_operator(self):
+        try:
+            self.set ^= self.other
+        except TypeError:
+            pass
+        else:
+            self.fail("expected TypeError")
+
+    def test_sym_difference_update(self):
+        if self.otherIsIterable:
+            self.set.symmetric_difference_update(self.other)
+        else:
+            self.assertRaises(TypeError,
+                              self.set.symmetric_difference_update,
+                              self.other)
+
+    def test_sym_difference(self):
+        self.assertRaises(TypeError, lambda: self.set ^ self.other)
+        self.assertRaises(TypeError, lambda: self.other ^ self.set)
+        if self.otherIsIterable:
+            self.set.symmetric_difference(self.other)
+        else:
+            self.assertRaises(TypeError, self.set.symmetric_difference, self.other)
+
+    def test_difference_update_operator(self):
+        try:
+            self.set -= self.other
+        except TypeError:
+            pass
+        else:
+            self.fail("expected TypeError")
+
+    def test_difference_update(self):
+        if self.otherIsIterable:
+            self.set.difference_update(self.other)
+        else:
+            self.assertRaises(TypeError,
+                              self.set.difference_update,
+                              self.other)
+
+    def test_difference(self):
+        self.assertRaises(TypeError, lambda: self.set - self.other)
+        self.assertRaises(TypeError, lambda: self.other - self.set)
+        if self.otherIsIterable:
+            self.set.difference(self.other)
+        else:
+            self.assertRaises(TypeError, self.set.difference, self.other)
+
+#------------------------------------------------------------------------------
+
+class TestOnlySetsNumeric(TestOnlySetsInBinaryOps):
+    def setUp(self):
+        self.set   = Set((1, 2, 3))
+        self.other = 19
+        self.otherIsIterable = False
+
+#------------------------------------------------------------------------------
+
+class TestOnlySetsDict(TestOnlySetsInBinaryOps):
+    def setUp(self):
+        self.set   = Set((1, 2, 3))
+        self.other = {1:2, 3:4}
+        self.otherIsIterable = True
+
+#------------------------------------------------------------------------------
+
+class TestOnlySetsOperator(TestOnlySetsInBinaryOps):
+    def setUp(self):
+        self.set   = Set((1, 2, 3))
+        self.other = operator.add
+        self.otherIsIterable = False
+
+    def test_ge_gt_le_lt(self):
+        with test_support.check_py3k_warnings():
+            super(TestOnlySetsOperator, self).test_ge_gt_le_lt()
+
+#------------------------------------------------------------------------------
+
+class TestOnlySetsTuple(TestOnlySetsInBinaryOps):
+    def setUp(self):
+        self.set   = Set((1, 2, 3))
+        self.other = (2, 4, 6)
+        self.otherIsIterable = True
+
+#------------------------------------------------------------------------------
+
+class TestOnlySetsString(TestOnlySetsInBinaryOps):
+    def setUp(self):
+        self.set   = Set((1, 2, 3))
+        self.other = 'abc'
+        self.otherIsIterable = True
+
+#------------------------------------------------------------------------------
+
+class TestOnlySetsGenerator(TestOnlySetsInBinaryOps):
+    def setUp(self):
+        def gen():
+            for i in xrange(0, 10, 2):
+                yield i
+        self.set   = Set((1, 2, 3))
+        self.other = gen()
+        self.otherIsIterable = True
+
+#------------------------------------------------------------------------------
+
+class TestOnlySetsofSets(TestOnlySetsInBinaryOps):
+    def setUp(self):
+        self.set   = Set((1, 2, 3))
+        self.other = [Set('ab'), ImmutableSet('cd')]
+        self.otherIsIterable = True
+
+#==============================================================================
+
+class TestCopying(unittest.TestCase):
+
+    def test_copy(self):
+        dup = self.set.copy()
+        self.assertEqual(len(dup), len(self.set))
+        dup_list = sorted(dup)
+        set_list = sorted(self.set)
+        self.assertEqual(len(dup_list), len(set_list))
+        for i, el in enumerate(dup_list):
+            # Object identity is not guarnteed for immutable objects, so we
+            # can't use assertIs here.
+            self.assertEqual(el, set_list[i])
+
+    def test_deep_copy(self):
+        dup = copy.deepcopy(self.set)
+        self.assertSetEqual(dup, self.set)
+
+#------------------------------------------------------------------------------
+
+class TestCopyingEmpty(TestCopying):
+    def setUp(self):
+        self.set = Set()
+
+#------------------------------------------------------------------------------
+
+class TestCopyingSingleton(TestCopying):
+    def setUp(self):
+        self.set = Set(["hello"])
+
+#------------------------------------------------------------------------------
+
+class TestCopyingTriple(TestCopying):
+    def setUp(self):
+        self.set = Set(["zero", 0, None])
+
+    def test_copy(self):
+        with test_support.check_py3k_warnings():
+            super(TestCopyingTriple, self).test_copy()
+
+#------------------------------------------------------------------------------
+
+class TestCopyingTuple(TestCopying):
+    def setUp(self):
+        self.set = Set([(1, 2)])
+
+#------------------------------------------------------------------------------
+
+class TestCopyingNested(TestCopying):
+    def setUp(self):
+        self.set = Set([((1, 2), (3, 4))])
+
+#==============================================================================
+
+class TestIdentities(unittest.TestCase):
+    def setUp(self):
+        self.a = Set([random.randrange(100) for i in xrange(50)])
+        self.b = Set([random.randrange(100) for i in xrange(50)])
+
+    def test_binopsVsSubsets(self):
+        a, b = self.a, self.b
+        self.assertTrue(a - b <= a)
+        self.assertTrue(b - a <= b)
+        self.assertTrue(a & b <= a)
+        self.assertTrue(a & b <= b)
+        self.assertTrue(a | b >= a)
+        self.assertTrue(a | b >= b)
+        self.assertTrue(a ^ b <= a | b)
+
+    def test_commutativity(self):
+        a, b = self.a, self.b
+        self.assertEqual(a&b, b&a)
+        self.assertEqual(a|b, b|a)
+        self.assertEqual(a^b, b^a)
+        if a != b:
+            self.assertNotEqual(a-b, b-a)
+
+    def test_reflexsive_relations(self):
+        a, zero = self.a, Set()
+        self.assertEqual(a ^ a, zero)
+        self.assertEqual(a - a, zero)
+        self.assertEqual(a | a, a)
+        self.assertEqual(a & a, a)
+        self.assertTrue(a <= a)
+        self.assertTrue(a >= a)
+        self.assertTrue(a == a)
+
+    def test_summations(self):
+        # check that sums of parts equal the whole
+        a, b = self.a, self.b
+        self.assertEqual((a-b)|(a&b)|(b-a), a|b)
+        self.assertEqual((a&b)|(a^b), a|b)
+        self.assertEqual(a|(b-a), a|b)
+        self.assertEqual((a-b)|b, a|b)
+        self.assertEqual((a-b)|(a&b), a)
+        self.assertEqual((b-a)|(a&b), b)
+        self.assertEqual((a-b)|(b-a), a^b)
+
+    def test_exclusion(self):
+        # check that inverse operations do not overlap
+        a, b, zero = self.a, self.b, Set()
+        self.assertEqual((a-b)&b, zero)
+        self.assertEqual((b-a)&a, zero)
+        self.assertEqual((a&b)&(a^b), zero)
+
+    def test_cardinality_relations(self):
+        a, b = self.a, self.b
+        self.assertEqual(len(a), len(a-b) + len(a&b))
+        self.assertEqual(len(b), len(b-a) + len(a&b))
+        self.assertEqual(len(a^b), len(a-b) + len(b-a))
+        self.assertEqual(len(a|b), len(a-b) + len(a&b) + len(b-a))
+        self.assertEqual(len(a^b) + len(a&b), len(a|b))
+
+#==============================================================================
+
+libreftest = """
+Example from the Library Reference:  Doc/lib/libsets.tex
+
+>>> from sets import Set as Base  # override _repr to get sorted output
+>>> class Set(Base):
+...     def _repr(self):
+...         return Base._repr(self, sorted=True)
+>>> engineers = Set(['John', 'Jane', 'Jack', 'Janice'])
+>>> programmers = Set(['Jack', 'Sam', 'Susan', 'Janice'])
+>>> managers = Set(['Jane', 'Jack', 'Susan', 'Zack'])
+>>> employees = engineers | programmers | managers           # union
+>>> engineering_management = engineers & managers            # intersection
+>>> fulltime_management = managers - engineers - programmers # difference
+>>> engineers.add('Marvin')
+>>> print engineers
+Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin'])
+>>> employees.issuperset(engineers)           # superset test
+False
+>>> employees.union_update(engineers)         # update from another set
+>>> employees.issuperset(engineers)
+True
+>>> for group in [engineers, programmers, managers, employees]:
+...     group.discard('Susan')                # unconditionally remove element
+...     print group
+...
+Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin'])
+Set(['Jack', 'Janice', 'Sam'])
+Set(['Jack', 'Jane', 'Zack'])
+Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin', 'Sam', 'Zack'])
+"""
+
+#==============================================================================
+
+__test__ = {'libreftest' : libreftest}
+
+def test_main(verbose=None):
+    import doctest
+    from test import test_sets
+    test_support.run_unittest(
+        TestSetOfSets,
+        TestExceptionPropagation,
+        TestBasicOpsEmpty,
+        TestBasicOpsSingleton,
+        TestBasicOpsTuple,
+        TestBasicOpsTriple,
+        TestBinaryOps,
+        TestUpdateOps,
+        TestMutate,
+        TestSubsetEqualEmpty,
+        TestSubsetEqualNonEmpty,
+        TestSubsetEmptyNonEmpty,
+        TestSubsetPartial,
+        TestSubsetNonOverlap,
+        TestOnlySetsNumeric,
+        TestOnlySetsDict,
+        TestOnlySetsOperator,
+        TestOnlySetsTuple,
+        TestOnlySetsString,
+        TestOnlySetsGenerator,
+        TestOnlySetsofSets,
+        TestCopyingEmpty,
+        TestCopyingSingleton,
+        TestCopyingTriple,
+        TestCopyingTuple,
+        TestCopyingNested,
+        TestIdentities,
+        doctest.DocTestSuite(test_sets),
+    )
+
+if __name__ == "__main__":
+    test_main(verbose=True)

lib_pypy/_ctypes/basics.py

             return self.from_param(as_parameter)
 
     def get_ffi_param(self, value):
-        return self.from_param(value)._to_ffi_param()
+        cdata = self.from_param(value)
+        return cdata, cdata._to_ffi_param()
 
     def get_ffi_argtype(self):
         if self._ffiargtype:

lib_pypy/_ctypes/function.py

                     "native COM method call without 'this' parameter"
                     )
             thisarg = cast(args[0], POINTER(POINTER(c_void_p)))
-            newargs, argtypes, outargs = self._convert_args(argtypes, args[1:], kwargs)
+            keepalives, newargs, argtypes, outargs = self._convert_args(argtypes,
+                                                                        args[1:], kwargs)
             newargs.insert(0, args[0].value)
             argtypes.insert(0, c_void_p)
         else:
             thisarg = None
-            newargs, argtypes, outargs = self._convert_args(argtypes, args, kwargs)
+            keepalives, newargs, argtypes, outargs = self._convert_args(argtypes,
+                                                                        args, kwargs)
 
         funcptr = self._getfuncptr(argtypes, self._restype_, thisarg)
         result = self._call_funcptr(funcptr, *newargs)
     @classmethod
     def _conv_param(cls, argtype, arg):
         if isinstance(argtype, _CDataMeta):
-            #arg = argtype.from_param(arg)
-            arg = argtype.get_ffi_param(arg)
-            return arg, argtype
+            cobj, ffiparam = argtype.get_ffi_param(arg)
+            return cobj, ffiparam, argtype
         
         if argtype is not None:
             arg = argtype.from_param(arg)
         if hasattr(arg, '_as_parameter_'):
             arg = arg._as_parameter_
         if isinstance(arg, _CData):
-            return arg._to_ffi_param(), type(arg)
+            return arg, arg._to_ffi_param(), type(arg)
         #
         # non-usual case: we do the import here to save a lot of code in the
         # jit trace of the normal case
         else:
             raise TypeError("Don't know how to handle %s" % (arg,))
 
-        return cobj._to_ffi_param(), type(cobj)
+        return cobj, cobj._to_ffi_param(), type(cobj)
 
     def _convert_args(self, argtypes, args, kwargs, marker=object()):
         newargs = []
         outargs = []
+        keepalives = []
         newargtypes = []
         total = len(args)
         paramflags = self._paramflags
                     val = defval
                     if val is marker:
                         val = 0
-                    newarg, newargtype = self._conv_param(argtype, val)
+                    keepalive, newarg, newargtype = self._conv_param(argtype, val)
+                    keepalives.append(keepalive)
                     newargs.append(newarg)
                     newargtypes.append(newargtype)
                 elif flag in (0, PARAMFLAG_FIN):
                         raise TypeError("required argument '%s' missing" % name)
                     else:
                         raise TypeError("not enough arguments")
-                    newarg, newargtype = self._conv_param(argtype, val)
+                    keepalive, newarg, newargtype = self._conv_param(argtype, val)
+                    keepalives.append(keepalive)
                     newargs.append(newarg)
                     newargtypes.append(newargtype)
                 elif flag == PARAMFLAG_FOUT:
                     if defval is not marker:
                         outargs.append(defval)
-                        newarg, newargtype = self._conv_param(argtype, defval)
+                        keepalive, newarg, newargtype = self._conv_param(argtype, defval)
                     else:
                         import ctypes
                         val = argtype._type_()
                         outargs.append(val)
+                        keepalive = None
                         newarg = ctypes.byref(val)
                         newargtype = type(newarg)
+                    keepalives.append(keepalive)
                     newargs.append(newarg)
                     newargtypes.append(newargtype)
                 else:
                     raise ValueError("paramflag %d not yet implemented" % flag)
             else:
                 try:
-                    newarg, newargtype = self._conv_param(argtype, args[i])
+                    keepalive, newarg, newargtype = self._conv_param(argtype, args[i])
                 except (UnicodeError, TypeError, ValueError), e:
                     raise ArgumentError(str(e))
+                keepalives.append(keepalive)
                 newargs.append(newarg)
                 newargtypes.append(newargtype)
                 inargs_idx += 1
             extra = args[len(newargs):]
             for i, arg in enumerate(extra):
                 try:
-                    newarg, newargtype = self._conv_param(None, arg)
+                    keepalive, newarg, newargtype = self._conv_param(None, arg)
                 except (UnicodeError, TypeError, ValueError), e:
                     raise ArgumentError(str(e))
+                keepalives.append(keepalive)
                 newargs.append(newarg)
                 newargtypes.append(newargtype)
-        return newargs, newargtypes, outargs
+        return keepalives, newargs, newargtypes, outargs
 
     
     def _wrap_result(self, restype, result):

lib_pypy/binascii.py

         crc = crc_32_tab[(crc ^ long(ord(c))) & 0xffL] ^ (crc >> 8)
         #/* Note:  (crc >> 8) MUST zero fill on left
 
-        result = crc ^ 0xffffffffL
+    result = crc ^ 0xffffffffL
     
     if result > 2**31:
         result = ((result + 2**31) % 2**32) - 2**31

lib_pypy/cPickle.py

             PythonPickler.__init__(self, self.__f, args[0], **kw)
         else:
             PythonPickler.__init__(self, *args, **kw)
-            
+
     def memoize(self, obj):
-        self.memo[None] = None   # cPickle starts counting at one
+        self.memo[id(None)] = None   # cPickle starts counting at one
         return PythonPickler.memoize(self, obj)
 
     def getvalue(self):

pypy/config/config.py

                                  (self.__class__, name))
         return self._cfgimpl_values[name]
 
+    def __dir__(self):
+        from_type = dir(type(self))
+        from_dict = list(self.__dict__)
+        extras = list(self._cfgimpl_values)
+        return sorted(set(extras + from_type + from_dict))
+
     def __delattr__(self, name):
         # XXX if you use delattr you are responsible for all bad things
         # happening

pypy/config/test/test_config.py

     py.test.raises(ConfigError, 'config.gc.name = "ref"')
     config.gc.name = "framework"
 
+def test___dir__():
+    descr = make_description()
+    config = Config(descr, bool=False)
+    attrs = dir(config)
+    assert '__repr__' in attrs        # from the type
+    assert '_cfgimpl_values' in attrs # from self
+    assert 'gc' in attrs              # custom attribute
+    assert 'objspace' in attrs        # custom attribute
+    #
+    attrs = dir(config.gc)
+    assert 'name' in attrs
+    assert 'dummy' in attrs
+    assert 'float' in attrs
+
 def test_arbitrary_option():
     descr = OptionDescription("top", "", [
         ArbitraryOption("a", "no help", default=None)

pypy/config/translationoption.py

                  ["annotate", "rtype", "backendopt", "database", "source",
                   "pyjitpl"],
                  default=None, cmdline="--fork-before"),
-
+    BoolOption("dont_write_c_files",
+               "Make the C backend write everyting to /dev/null. " +
+               "Useful for benchmarking, so you don't actually involve the disk",
+               default=False, cmdline="--dont-write-c-files"),
     ArbitraryOption("instrumentctl", "internal",
                default=None),
     StrOption("output", "Output file name", cmdline="--output"),

pypy/doc/extending.rst

   section
 
 * Write them in pure python and use direct libffi low-level bindings, See
-  \_rawffi_ module description.
+  \_ffi_ module description.
 
 * Write them in RPython as mixedmodule_, using *rffi* as bindings.
 
 .. _ctypes: #CTypes
-.. _\_rawffi: #LibFFI
+.. _\_ffi: #LibFFI
 .. _mixedmodule: #Mixed Modules
 
 CTypes
 platform-dependent details (compiling small snippets of C code and running
 them), so it'll benefit not pypy-related ctypes-based modules as well.
 
+ctypes call are optimized by the JIT and the resulting machine code contains a
+direct call to the target C function.  However, due to the very dynamic nature
+of ctypes, some overhead over a bare C call is still present, in particular to
+check/convert the types of the parameters.  Moreover, even if most calls are
+optimized, some cannot and thus need to follow the slow path, not optimized by
+the JIT.
+
 .. _`ctypes-configure`: ctypes-implementation.html#ctypes-configure
+.. _`CPython ctypes`: http://docs.python.org/library/ctypes.html
 
 Pros
 ----
 
-Stable, CPython-compatible API
+Stable, CPython-compatible API.  Most calls are fast, optimized by JIT.
 
 Cons
 ----
 
-Only pure-python code (slow), problems with platform-dependency (although
-we partially solve those). PyPy implementation is now very slow.
+Problems with platform-dependency (although we partially solve
+those). Although the JIT optimizes ctypes calls, some overhead is still
+present.  The slow-path is very slow.
 
-_`CPython ctypes`: http://python.net/crew/theller/ctypes/
 
 LibFFI
 ======
 
 Mostly in order to be able to write a ctypes module, we developed a very
-low-level libffi bindings. (libffi is a C-level library for dynamic calling,
+low-level libffi bindings called ``_ffi``. (libffi is a C-level library for dynamic calling,
 which is used by CPython ctypes). This library provides stable and usable API,
 although it's API is a very low-level one. It does not contain any
-magic.
+magic.  It is also optimized by the JIT, but has much less overhead than ctypes.
 
 Pros
 ----
 
-Works. Combines disadvantages of using ctypes with disadvantages of
-using mixed modules. Probably more suitable for a delicate code
-where ctypes magic goes in a way.
+It Works. Probably more suitable for a delicate code where ctypes magic goes
+in a way.  All calls are optimized by the JIT, there is no slow path as in
+ctypes.
 
 Cons
 ----
 
-Slow. CPython-incompatible API, very rough and low-level
+It combines disadvantages of using ctypes with disadvantages of using mixed
+modules. CPython-incompatible API, very rough and low-level.
 
 Mixed Modules
 =============
 * a mixed module needs to be written in RPython, which is far more
   complicated than Python (XXX link)
 
-* due to lack of separate compilation (as of April 2008), each
+* due to lack of separate compilation (as of July 2011), each
   compilation-check requires to recompile whole PyPy python interpreter,
   which takes 0.5-1h. We plan to solve this at some point in near future.
 
 * although rpython is a garbage-collected language, the border between
   C and RPython needs to be managed by hand (each object that goes into the
-  C level must be explicitly freed) XXX we try to solve this
+  C level must be explicitly freed).
 
-Some document is available `here`_
+Some documentation is available `here`_
 
 .. _`here`: rffi.html
 

pypy/doc/interpreter-optimizations.rst

 You can enable this feature with the :config:`objspace.opcodes.CALL_METHOD`
 option.
 
-.. _`call likely builtin`:
-
-CALL_LIKELY_BUILTIN
-+++++++++++++++++++
-
-A often heard "tip" for speeding up Python programs is to give an often used
-builtin a local name, since local lookups are faster than lookups of builtins,
-which involve doing two dictionary lookups: one in the globals dictionary and
-one in the the builtins dictionary. PyPy approaches this problem at the
-implementation level, with the introduction of the new ``CALL_LIKELY_BUILTIN``
-bytecode. This bytecode is produced by the compiler for a call whose target is
-the name of a builtin.  Since such a syntactic construct is very often actually
-invoking the expected builtin at run-time, this information can be used to make
-the call to the builtin directly, without going through any dictionary lookup.
-
-However, it can occur that the name is shadowed by a global name from the
-current module.  To catch this case, a special dictionary implementation for
-multidicts is introduced, which is used for the dictionaries of modules. This
-implementation keeps track which builtin name is shadowed by it.  The
-``CALL_LIKELY_BUILTIN`` bytecode asks the dictionary whether it is shadowing the
-builtin that is about to be called and asks the dictionary of ``__builtin__``
-whether the original builtin was changed.  These two checks are cheaper than
-full lookups.  In the common case, neither of these cases is true, so the
-builtin can be directly invoked.
-
-You can enable this feature with the
-:config:`objspace.opcodes.CALL_LIKELY_BUILTIN` option.
-
 .. more here?
 
 Overall Effects

pypy/interpreter/astcompiler/misc.py

     _emit_syntax_warning(space, w_msg, w_filename, w_lineno, w_offset)
 
 
-def parse_future(tree):
+def parse_future(tree, feature_flags):
     future_lineno = 0
     future_column = 0
+    flags = 0
     have_docstring = False
     body = None
     if isinstance(tree, ast.Module):
     elif isinstance(tree, ast.Interactive):
         body = tree.body
     if body is None:
-        return 0, 0
+        return 0, 0, 0
     for stmt in body:
         if isinstance(stmt, ast.Expr) and isinstance(stmt.value, ast.Str):
             if have_docstring:
             if stmt.module == "__future__":
                 future_lineno = stmt.lineno
                 future_column = stmt.col_offset
+                for alias in stmt.names:
+                    assert isinstance(alias, ast.alias)
+                    # If this is an invalid flag, it will be caught later in
+                    # codegen.py.
+                    flags |= feature_flags.get(alias.name, 0)
             else:
                 break
         else:
             break
-    return future_lineno, future_column
+    return flags, future_lineno, future_column
 
 
 class ForbiddenNameAssignment(Exception):

pypy/interpreter/baseobjspace.py

         raise operationerrfmt(space.w_TypeError,
             "cannot create weak reference to '%s' object", typename)
 
+    def delweakref(self):
+        pass
+
     def clear_all_weakrefs(self):
         """Call this at the beginning of interp-level __del__() methods
         in subclasses.  It ensures that weakrefs (if any) are cleared
             # app-level, e.g. a user-defined __del__(), and this code
             # tries to use weakrefs again, it won't reuse the broken
             # (already-cleared) weakrefs from this lifeline.
-            self.setweakref(lifeline.space, None)
+            self.delweakref()
             lifeline.clear_all_weakrefs()
 
-    __already_enqueued_for_destruction = False
+    __already_enqueued_for_destruction = ()
 
-    def _enqueue_for_destruction(self, space, call_user_del=True):
+    def enqueue_for_destruction(self, space, callback, descrname):
         """Put the object in the destructor queue of the space.
-        At a later, safe point in time, UserDelAction will use
-        space.userdel() to call the object's app-level __del__ method.
+        At a later, safe point in time, UserDelAction will call
+        callback(self).  If that raises OperationError, prints it
+        to stderr with the descrname string.
+
+        Note that 'callback' will usually need to start with:
+            assert isinstance(self, W_SpecificClass)
         """
         # this function always resurect the object, so when
         # running on top of CPython we must manually ensure that
         # we enqueue it only once
         if not we_are_translated():
-            if self.__already_enqueued_for_destruction:
+            if callback in self.__already_enqueued_for_destruction:
                 return
-            self.__already_enqueued_for_destruction = True
-        self.clear_all_weakrefs()
-        if call_user_del:
-            space.user_del_action.register_dying_object(self)
-
-    def _call_builtin_destructor(self):
-        pass     # method overridden in typedef.py
+            self.__already_enqueued_for_destruction += (callback,)
+        space.user_del_action.register_callback(self, callback, descrname)
 
     # hooks that the mapdict implementations needs:
     def _get_mapdict_map(self):
                 return self.w_True
         return self.w_False
 
+    def issequence_w(self, w_obj):
+        return (self.findattr(w_obj, self.wrap("__getitem__")) is not None)
+
     def isinstance_w(self, w_obj, w_type):
         return self.is_true(self.isinstance(w_obj, w_type))
 

pypy/interpreter/executioncontext.py

 
     def __init__(self, space):
         AsyncAction.__init__(self, space)
-        self.dying_objects_w = []
-        self.weakrefs_w = []
+        self.dying_objects = []
         self.finalizers_lock_count = 0
 
-    def register_dying_object(self, w_obj):
-        self.dying_objects_w.append(w_obj)
-        self.fire()
-
-    def register_weakref_callback(self, w_ref):
-        self.weakrefs_w.append(w_ref)
+    def register_callback(self, w_obj, callback, descrname):
+        self.dying_objects.append((w_obj, callback, descrname))
         self.fire()
 
     def perform(self, executioncontext, frame):
         if self.finalizers_lock_count > 0:
             return
-        # Each call to perform() first grabs the self.dying_objects_w
+        # Each call to perform() first grabs the self.dying_objects
         # and replaces it with an empty list.  We do this to try to
         # avoid too deep recursions of the kind of __del__ being called
         # while in the middle of another __del__ call.
-        pending_w = self.dying_objects_w
-        self.dying_objects_w = []
+        pending = self.dying_objects
+        self.dying_objects = []
         space = self.space
-        for i in range(len(pending_w)):
-            w_obj = pending_w[i]
-            pending_w[i] = None
+        for i in range(len(pending)):
+            w_obj, callback, descrname = pending[i]
+            pending[i] = (None, None, None)
             try:
-                space.userdel(w_obj)
+                callback(w_obj)
             except OperationError, e:
-                e.write_unraisable(space, 'method __del__ of ', w_obj)
+                e.write_unraisable(space, descrname, w_obj)
                 e.clear(space)   # break up reference cycles
-            # finally, this calls the interp-level destructor for the
-            # cases where there is both an app-level and a built-in __del__.
-            w_obj._call_builtin_destructor()
-        pending_w = self.weakrefs_w
-        self.weakrefs_w = []
-        for i in range(len(pending_w)):
-            w_ref = pending_w[i]
-            w_ref.activate_callback()
 
 class FrameTraceAction(AsyncAction):
     """An action that calls the local trace functions (w_f_trace)."""

pypy/interpreter/gateway.py

             fastfunc = func
         else:
             # try to avoid excessive bloat
-            if func.__module__ == 'pypy.interpreter.astcompiler.ast':
+            mod = func.__module__
+            if mod is None:
+                mod = ""
+            if mod == 'pypy.interpreter.astcompiler.ast':
                 raise FastFuncNotSupported
-            if (not func.__module__.startswith('pypy.module.__builtin__') and
-                not func.__module__.startswith('pypy.module.sys') and
-                not func.__module__.startswith('pypy.module.math')):
+            if (not mod.startswith('pypy.module.__builtin__') and
+                not mod.startswith('pypy.module.sys') and
+                not mod.startswith('pypy.module.math')):
                 if not func.__name__.startswith('descr'):
                     raise FastFuncNotSupported
             d = {}

pypy/interpreter/generator.py

  
     def descr_close(self):
         """x.close(arg) -> raise GeneratorExit inside generator."""
+        assert isinstance(self, GeneratorIterator)
         space = self.space
         try:
             w_retval = self.throw(space.w_GeneratorExit, space.w_None,
         code_name = self.pycode.co_name
         return space.wrap(code_name)
 
-    def descr__del__(self):        
-        """
-        applevel __del__, which is called at a safe point after the
-        interp-level __del__ enqueued the object for destruction
-        """
-        self.descr_close()
-
     def __del__(self):
         # Only bother enqueuing self to raise an exception if the frame is
         # still not finished and finally or except blocks are present.
-        must_call_close = False
+        self.clear_all_weakrefs()
         if self.frame is not None:
             block = self.frame.lastblock
             while block is not None:
                 if not isinstance(block, LoopBlock):
-                    must_call_close = True
+                    self.enqueue_for_destruction(self.space,
+                                                 GeneratorIterator.descr_close,
+                                                 "interrupting generator of ")
                     break
                 block = block.previous
-        self._enqueue_for_destruction(self.space, must_call_close)

pypy/interpreter/module.py

 class Module(Wrappable):
     """A module."""
 
+    _immutable_fields_ = ["w_dict?"]
+
     _frozen = False
 
     def __init__(self, space, w_name, w_dict=None, add_package=True):

pypy/interpreter/pycompiler.py

             raise OperationError(self.space.w_TypeError, self.space.wrap(
                 "invalid node type"))
 
-        future_pos = misc.parse_future(node)
+        fut = misc.parse_future(node, self.future_flags.compiler_features)
+        f_flags, f_lineno, f_col = fut
+        future_pos = f_lineno, f_col
+        flags |= f_flags
         info = pyparse.CompileInfo(filename, mode, flags, future_pos)
         return self._compile_ast(node, info)
 

pypy/interpreter/test/test_typedef.py

+import gc
 from pypy.interpreter import typedef
 from pypy.tool.udir import udir
 from pypy.interpreter.baseobjspace import Wrappable
             assert err.value.message == "'some_type' objects are unhashable"
             """)
 
+    def test_destructor(self):
+        space = self.space
+        class W_Level1(Wrappable):
+            def __init__(self, space1):
+                assert space1 is space
+            def __del__(self):
+                space.call_method(w_seen, 'append', space.wrap(1))
+        class W_Level2(Wrappable):
+            def __init__(self, space1):
+                assert space1 is space
+            def __del__(self):
+                self.enqueue_for_destruction(space, W_Level2.destructormeth,
+                                             'FOO ')
+            def destructormeth(self):
+                space.call_method(w_seen, 'append', space.wrap(2))
+        W_Level1.typedef = typedef.TypeDef(
+            'level1',
+            __new__ = typedef.generic_new_descr(W_Level1))
+        W_Level2.typedef = typedef.TypeDef(
+            'level2',
+            __new__ = typedef.generic_new_descr(W_Level2))
+        #
+        w_seen = space.newlist([])
+        W_Level1(space)
+        gc.collect(); gc.collect()
+        assert space.unwrap(w_seen) == [1]
+        #
+        w_seen = space.newlist([])
+        W_Level2(space)
+        gc.collect(); gc.collect()
+        assert space.str_w(space.repr(w_seen)) == "[]"  # not called yet
+        ec = space.getexecutioncontext()
+        self.space.user_del_action.perform(ec, None)
+        assert space.unwrap(w_seen) == [2]
+        #
+        w_seen = space.newlist([])
+        self.space.appexec([self.space.gettypeobject(W_Level1.typedef)],
+        """(level1):
+            class A3(level1):
+                pass
+            A3()
+        """)
+        gc.collect(); gc.collect()
+        assert space.unwrap(w_seen) == [1]
+        #
+        w_seen = space.newlist([])
+        self.space.appexec([self.space.gettypeobject(W_Level1.typedef),
+                            w_seen],
+        """(level1, seen):
+            class A4(level1):
+                def __del__(self):
+                    seen.append(4)
+            A4()
+        """)
+        gc.collect(); gc.collect()
+        assert space.unwrap(w_seen) == [4, 1]
+        #
+        w_seen = space.newlist([])
+        self.space.appexec([self.space.gettypeobject(W_Level2.typedef)],
+        """(level2):
+            class A5(level2):
+                pass
+            A5()
+        """)
+        gc.collect(); gc.collect()
+        assert space.unwrap(w_seen) == [2]
+        #
+        w_seen = space.newlist([])
+        self.space.appexec([self.space.gettypeobject(W_Level2.typedef),
+                            w_seen],
+        """(level2, seen):
+            class A6(level2):
+                def __del__(self):
+                    seen.append(6)
+            A6()
+        """)
+        gc.collect(); gc.collect()
+        assert space.unwrap(w_seen) == [6, 2]
+
 
 class AppTestTypeDef:
 

pypy/interpreter/typedef.py

                 return self._lifeline_
             def setweakref(self, space, weakreflifeline):
                 self._lifeline_ = weakreflifeline
+            def delweakref(self):
+                self._lifeline_ = None
         add(Proto)
 
     if "del" in features:
+        parent_destructor = getattr(supercls, '__del__', None)
+        def call_parent_del(self):
+            assert isinstance(self, subcls)
+            parent_destructor(self)
+        def call_applevel_del(self):
+            assert isinstance(self, subcls)
+            self.space.userdel(self)
         class Proto(object):
             def __del__(self):
-                self._enqueue_for_destruction(self.space)
-        # if the base class needs its own interp-level __del__,
-        # we override the _call_builtin_destructor() method to invoke it
-        # after the app-level destructor.
-        parent_destructor = getattr(supercls, '__del__', None)
-        if parent_destructor is not None:
-            def _call_builtin_destructor(self):
-                parent_destructor(self)
-            Proto._call_builtin_destructor = _call_builtin_destructor
-
+                self.clear_all_weakrefs()
+                self.enqueue_for_destruction(self.space, call_applevel_del,
+                                             'method __del__ of ')
+                if parent_destructor is not None:
+                    self.enqueue_for_destruction(self.space, call_parent_del,
+                                                 'internal destructor of ')
         add(Proto)
 
     if "slots" in features:
         return self._lifeline_
     def setweakref(self, space, weakreflifeline):
         self._lifeline_ = weakreflifeline
+    def delweakref(self):
+        self._lifeline_ = None
     cls._lifeline_ = None
     cls.getweakref = getweakref
     cls.setweakref = setweakref
+    cls.delweakref = delweakref
     return weakref_descr
 
 
                             descrmismatch='close'),
     __iter__   = interp2app(GeneratorIterator.descr__iter__,
                             descrmismatch='__iter__'),
-    __del__    = interp2app(GeneratorIterator.descr__del__,
-                            descrmismatch='__del__'),
     gi_running = interp_attrproperty('running', cls=GeneratorIterator),
     gi_frame   = GetSetProperty(GeneratorIterator.descr_gi_frame),
     gi_code    = GetSetProperty(GeneratorIterator.descr_gi_code),

pypy/jit/backend/x86/assembler.py

         fullsize = self.mc.get_relative_pos()
         #
         rawstart = self.materialize_loop(looptoken)
-        debug_print("Loop #%d (%s) has address %x to %x" % (
+        debug_start("jit-backend-addr")
+        debug_print("Loop %d (%s) has address %x to %x (bootstrap %x)" % (
             looptoken.number, loopname,
             rawstart + self.looppos,
-            rawstart + directbootstrappos))
+            rawstart + directbootstrappos,
+            rawstart))
+        debug_stop("jit-backend-addr")
         self._patch_stackadjust(rawstart + stackadjustpos,
                                 frame_depth + param_depth)
         self.patch_pending_failure_recoveries(rawstart)
         fullsize = self.mc.get_relative_pos()
         #
         rawstart = self.materialize_loop(original_loop_token)
-
-        debug_print("Bridge out of guard %d has address %x to %x" %
+        debug_start("jit-backend-addr")
+        debug_print("bridge out of Guard %d has address %x to %x" %
                     (descr_number, rawstart, rawstart + codeendpos))
+        debug_stop("jit-backend-addr")
         self._patch_stackadjust(rawstart + stackadjustpos,
                                 frame_depth + param_depth)
         self.patch_pending_failure_recoveries(rawstart)

pypy/jit/backend/x86/rx86.py

 
     # ------------------------------ MOV ------------------------------
 
-    MOV_ri = insn(rex_w, register(1), '\xB8', immediate(2, 'q'))
+    MOV_ri = insn(register(1), '\xB8', immediate(2))
     MOV8_ri = insn(rex_fw, byte_register(1), '\xB0', immediate(2, 'b'))
 
     # ------------------------------ Arithmetic ------------------------------
 
     CQO = insn(rex_w, '\x99')
 
-    # MOV_ri from the parent class is not wrong, but here is a better encoding
-    # for the common case where the immediate fits in 32 bits
+    # Three different encodings... following what gcc does.  From the
+    # shortest encoding to the longest one.
+    MOV_riu32 = insn(rex_nw, register(1), '\xB8', immediate(2, 'i'))
     MOV_ri32 = insn(rex_w, '\xC7', register(1), '\xC0', immediate(2, 'i'))
-    MOV_ri64 = AbstractX86CodeBuilder.MOV_ri
+    MOV_ri64 = insn(rex_w, register(1), '\xB8', immediate(2, 'q'))
 
     def MOV_ri(self, reg, immed):
-        if fits_in_32bits(immed):
+        if 0 <= immed <= 4294967295:
+            immed = intmask(rffi.cast(rffi.INT, immed))
+            self.MOV_riu32(reg, immed)
+        elif fits_in_32bits(immed):    # for negative values that fit in 32 bit
             self.MOV_ri32(reg, immed)
         else:
-            AbstractX86CodeBuilder.MOV_ri(self, reg, immed)
+            self.MOV_ri64(reg, immed)
 
 def define_modrm_modes(insnname_template, before_modrm, after_modrm=[], regtype='GPR'):
     def add_insn(code, *modrm):

pypy/jit/backend/x86/test/test_regloc.py

     assert_encodes_as(cb64, "MOV16", (r8, ebx), '\x66\x41\x89\xD8')  # 11 011 000
     assert_encodes_as(cb64, "MOV16", (ebx, r8), '\x66\x44\x89\xC3')  # 11 000 011
     assert_encodes_as(cb64, "MOV16", (ecx, ebx), '\x66\x40\x89\xD9')
-    # XXX: What we are testing for here is actually not the most compact
-    # encoding.
-    assert_encodes_as(cb64, "MOV16", (ecx, ImmedLoc(12345)), '\x66\x40\xC7\xC1\x39\x30')
+    assert_encodes_as(cb64, "MOV16", (ecx, ImmedLoc(12345)), '\x66\xB9\x39\x30')
+    # for the next case we don't pick the most efficient encoding, but well
+    expected = '\x66\x40\xC7\xC1\xC7\xCF'  # could be '\x66\xB9\xC7\xCF'
+    assert_encodes_as(cb64, "MOV16", (ecx, ImmedLoc(-12345)), expected)
+    assert_encodes_as(cb64, "MOV16", (r9, ImmedLoc(12345)), '\x66\x41\xB9\x39\x30')
+    # for the next case we don't pick the most efficient encoding, but well
+    expected = '\x66\x41\xC7\xC1\xC7\xCF'  # could be '\x66\x41\xB9\xC7\xCF'
+    assert_encodes_as(cb64, "MOV16", (r9, ImmedLoc(-12345)), expected)
     assert_encodes_as(cb64, "MOV16", (AddressLoc(r13, ImmedLoc(0), 0, 0), ImmedLoc(12345)), '\x66\x41\xC7\x45\x00\x39\x30')
 
 def test_cmp_16():
 def test_relocation():
     from pypy.rpython.lltypesystem import lltype, rffi
     from pypy.jit.backend.x86 import codebuf
-    for target in [0x01020304, 0x0102030405060708]:
+    for target in [0x01020304, -0x05060708, 0x0102030405060708]:
         if target > sys.maxint:
             continue
         mc = codebuf.MachineCodeBlockWrapper()
             expected = "\xE8" + struct.pack('<i', target - (rawstart + 5))
         elif IS_X86_64:
             assert mc.relocations == []
-            if target <= 0x7fffffff:
+            if 0 <= target <= 0xffffffff:
+                assert length == 9
+                expected = (
+                    "\x41\xBB\x04\x03\x02\x01"      # MOV %r11, target
+                    "\x41\xFF\xD3")                 # CALL *%r11
+            elif -0x80000000 <= target < 0:
                 assert length == 10
                 expected = (
-                    "\x49\xC7\xC3\x04\x03\x02\x01"  # MOV %r11, target
+                    "\x49\xC7\xC3\xF8\xF8\xF9\xFA"  # MOV %r11, target
                     "\x41\xFF\xD3")                 # CALL *%r11
             else:
                 assert length == 13

pypy/jit/backend/x86/test/test_rx86.py

 def test_mov_ri_64():
     s = CodeBuilder64()
     s.MOV_ri(ecx, -2)
+    s.MOV_ri(r15, -3)
+    s.MOV_ri(ebx, -0x80000003)
+    s.MOV_ri(r13, -0x80000002)
+    s.MOV_ri(ecx, 42)
     s.MOV_ri(r12, 0x80000042)
+    s.MOV_ri(r12, 0x100000007)
     assert s.getvalue() == ('\x48\xC7\xC1\xFE\xFF\xFF\xFF' +
-                            '\x49\xBC\x42\x00\x00\x80\x00\x00\x00\x00')
+                            '\x49\xC7\xC7\xFD\xFF\xFF\xFF' +
+                            '\x48\xBB\xFD\xFF\xFF\x7F\xFF\xFF\xFF\xFF' +
+                            '\x49\xBD\xFE\xFF\xFF\x7F\xFF\xFF\xFF\xFF' +
+                            '\xB9\x2A\x00\x00\x00' +
+                            '\x41\xBC\x42\x00\x00\x80' +
+                            '\x49\xBC\x07\x00\x00\x00\x01\x00\x00\x00')
 
 def test_mov_rm_64():
     s = CodeBuilder64()

pypy/jit/backend/x86/test/test_rx86_32_auto_encoding.py

             for mode, v in zip(argmodes, args):
                 ops.append(assembler_operand[mode](v))
             ops.reverse()
+            #
+            if (instrname.lower() == 'mov' and suffix == 'q' and
+                ops[0].startswith('$') and 0 <= int(ops[0][1:]) <= 4294967295
+                and ops[1].startswith('%r')):
+                # movq $xxx, %rax => movl $xxx, %eax
+                suffix = 'l'
+                if ops[1][2:].isdigit():
+                    ops[1] += 'd'
+                else:
+                    ops[1] = '%e' + ops[1][2:]
+            #