Ignore:
Timestamp:
Mar 19, 2014, 11:31:01 PM (11 years ago)
Author:
dmik
Message:

python: Merge vendor 2.7.6 to trunk.

Location:
python/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • python/trunk

  • python/trunk/Lib/test/test_gc.py

    r2 r391  
    22from test.test_support import verbose, run_unittest
    33import sys
     4import time
    45import gc
    56import weakref
     7
     8try:
     9    import threading
     10except ImportError:
     11    threading = None
    612
    713### Support code
     
    245251    def test_get_count(self):
    246252        # Avoid future allocation of method object
    247         assertEqual = self.assertEqual
     253        assertEqual = self._baseAssertEqual
    248254        gc.collect()
    249255        assertEqual(gc.get_count(), (0, 0, 0))
     
    300306        gc.disable()
    301307
     308    @unittest.skipUnless(threading, "test meaningless on builds without threads")
     309    def test_trashcan_threads(self):
     310        # Issue #13992: trashcan mechanism should be thread-safe
     311        NESTING = 60
     312        N_THREADS = 2
     313
     314        def sleeper_gen():
     315            """A generator that releases the GIL when closed or dealloc'ed."""
     316            try:
     317                yield
     318            finally:
     319                time.sleep(0.000001)
     320
     321        class C(list):
     322            # Appending to a list is atomic, which avoids the use of a lock.
     323            inits = []
     324            dels = []
     325            def __init__(self, alist):
     326                self[:] = alist
     327                C.inits.append(None)
     328            def __del__(self):
     329                # This __del__ is called by subtype_dealloc().
     330                C.dels.append(None)
     331                # `g` will release the GIL when garbage-collected.  This
     332                # helps assert subtype_dealloc's behaviour when threads
     333                # switch in the middle of it.
     334                g = sleeper_gen()
     335                next(g)
     336                # Now that __del__ is finished, subtype_dealloc will proceed
     337                # to call list_dealloc, which also uses the trashcan mechanism.
     338
     339        def make_nested():
     340            """Create a sufficiently nested container object so that the
     341            trashcan mechanism is invoked when deallocating it."""
     342            x = C([])
     343            for i in range(NESTING):
     344                x = [C([x])]
     345            del x
     346
     347        def run_thread():
     348            """Exercise make_nested() in a loop."""
     349            while not exit:
     350                make_nested()
     351
     352        old_checkinterval = sys.getcheckinterval()
     353        sys.setcheckinterval(3)
     354        try:
     355            exit = False
     356            threads = []
     357            for i in range(N_THREADS):
     358                t = threading.Thread(target=run_thread)
     359                threads.append(t)
     360            for t in threads:
     361                t.start()
     362            time.sleep(1.0)
     363            exit = True
     364            for t in threads:
     365                t.join()
     366        finally:
     367            sys.setcheckinterval(old_checkinterval)
     368        gc.collect()
     369        self.assertEqual(len(C.inits), len(C.dels))
     370
    302371    def test_boom(self):
    303372        class Boom:
     
    415484
    416485        self.assertEqual(gc.get_referents(1, 'a', 4j), [])
     486
     487    def test_is_tracked(self):
     488        # Atomic built-in types are not tracked, user-defined objects and
     489        # mutable containers are.
     490        # NOTE: types with special optimizations (e.g. tuple) have tests
     491        # in their own test files instead.
     492        self.assertFalse(gc.is_tracked(None))
     493        self.assertFalse(gc.is_tracked(1))
     494        self.assertFalse(gc.is_tracked(1.0))
     495        self.assertFalse(gc.is_tracked(1.0 + 5.0j))
     496        self.assertFalse(gc.is_tracked(True))
     497        self.assertFalse(gc.is_tracked(False))
     498        self.assertFalse(gc.is_tracked("a"))
     499        self.assertFalse(gc.is_tracked(u"a"))
     500        self.assertFalse(gc.is_tracked(bytearray("a")))
     501        self.assertFalse(gc.is_tracked(type))
     502        self.assertFalse(gc.is_tracked(int))
     503        self.assertFalse(gc.is_tracked(object))
     504        self.assertFalse(gc.is_tracked(object()))
     505
     506        class OldStyle:
     507            pass
     508        class NewStyle(object):
     509            pass
     510        self.assertTrue(gc.is_tracked(gc))
     511        self.assertTrue(gc.is_tracked(OldStyle))
     512        self.assertTrue(gc.is_tracked(OldStyle()))
     513        self.assertTrue(gc.is_tracked(NewStyle))
     514        self.assertTrue(gc.is_tracked(NewStyle()))
     515        self.assertTrue(gc.is_tracked([]))
     516        self.assertTrue(gc.is_tracked(set()))
    417517
    418518    def test_bug1055820b(self):
Note: See TracChangeset for help on using the changeset viewer.