[Python-checkins] r88467 - in python/branches/py3k: Lib/doctest.py Lib/test/pickletester.py Lib/test/regrtest.py Lib/test/support.py Lib/test/test_doctest.py Lib/test/test_exceptions.py Lib/test/test_io.py Lib/test/test_pdb.py Lib/test/test_richcmp.py Lib/test/test_runpy.py Lib/test/test_scope.py Lib/test/test_sys_settrace.py Lib/test/test_trace.py Lib/test/test_zipimport_support.py Misc/NEWS

brett.cannon python-checkins at python.org
Mon Feb 21 20:29:56 CET 2011


Author: brett.cannon
Date: Mon Feb 21 20:29:56 2011
New Revision: 88467

Log:
Issue #10990: Prevent tests from clobbering a set trace function.

Many tests simply didn't care if they unset a pre-existing trace function. This
made test coverage impossible. This patch fixes various tests to put back any
pre-existing trace function. It also introduces test.support.no_tracing as a
decorator which will temporarily unset the trace function for tests which
simply fail otherwise.

Thanks to Kristian Vlaardingerbroek for helping to find the cause of various
trace function unsets.


Modified:
   python/branches/py3k/Lib/doctest.py
   python/branches/py3k/Lib/test/pickletester.py
   python/branches/py3k/Lib/test/regrtest.py
   python/branches/py3k/Lib/test/support.py
   python/branches/py3k/Lib/test/test_doctest.py
   python/branches/py3k/Lib/test/test_exceptions.py
   python/branches/py3k/Lib/test/test_io.py
   python/branches/py3k/Lib/test/test_pdb.py
   python/branches/py3k/Lib/test/test_richcmp.py
   python/branches/py3k/Lib/test/test_runpy.py
   python/branches/py3k/Lib/test/test_scope.py
   python/branches/py3k/Lib/test/test_sys_settrace.py
   python/branches/py3k/Lib/test/test_trace.py
   python/branches/py3k/Lib/test/test_zipimport_support.py
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Lib/doctest.py
==============================================================================
--- python/branches/py3k/Lib/doctest.py	(original)
+++ python/branches/py3k/Lib/doctest.py	Mon Feb 21 20:29:56 2011
@@ -1373,6 +1373,7 @@
         # Note that the interactive output will go to *our*
         # save_stdout, even if that's not the real sys.stdout; this
         # allows us to write test cases for the set_trace behavior.
+        save_trace = sys.gettrace()
         save_set_trace = pdb.set_trace
         self.debugger = _OutputRedirectingPdb(save_stdout)
         self.debugger.reset()
@@ -1392,6 +1393,7 @@
         finally:
             sys.stdout = save_stdout
             pdb.set_trace = save_set_trace
+            sys.settrace(save_trace)
             linecache.getlines = self.save_linecache_getlines
             sys.displayhook = save_displayhook
             if clear_globs:

Modified: python/branches/py3k/Lib/test/pickletester.py
==============================================================================
--- python/branches/py3k/Lib/test/pickletester.py	(original)
+++ python/branches/py3k/Lib/test/pickletester.py	Mon Feb 21 20:29:56 2011
@@ -5,7 +5,7 @@
 import copyreg
 from http.cookies import SimpleCookie
 
-from test.support import TestFailed, TESTFN, run_with_locale
+from test.support import TestFailed, TESTFN, run_with_locale, no_tracing
 
 from pickle import bytes_types
 
@@ -1002,6 +1002,7 @@
             y = self.loads(s)
             self.assertEqual(y._reduce_called, 1)
 
+    @no_tracing
     def test_bad_getattr(self):
         x = BadGetattr()
         for proto in 0, 1:

Modified: python/branches/py3k/Lib/test/regrtest.py
==============================================================================
--- python/branches/py3k/Lib/test/regrtest.py	(original)
+++ python/branches/py3k/Lib/test/regrtest.py	Mon Feb 21 20:29:56 2011
@@ -827,7 +827,7 @@
     resources = ('sys.argv', 'cwd', 'sys.stdin', 'sys.stdout', 'sys.stderr',
                  'os.environ', 'sys.path', 'sys.path_hooks', '__import__',
                  'warnings.filters', 'asyncore.socket_map',
-                 'logging._handlers', 'logging._handlerList')
+                 'logging._handlers', 'logging._handlerList', 'sys.gettrace')
 
     def get_sys_argv(self):
         return id(sys.argv), sys.argv, sys.argv[:]
@@ -874,6 +874,11 @@
         sys.path_hooks = saved_hooks[1]
         sys.path_hooks[:] = saved_hooks[2]
 
+    def get_sys_gettrace(self):
+        return sys.gettrace()
+    def restore_sys_gettrace(self, trace_fxn):
+        sys.settrace(trace_fxn)
+
     def get___import__(self):
         return builtins.__import__
     def restore___import__(self, import_):

Modified: python/branches/py3k/Lib/test/support.py
==============================================================================
--- python/branches/py3k/Lib/test/support.py	(original)
+++ python/branches/py3k/Lib/test/support.py	Mon Feb 21 20:29:56 2011
@@ -1108,6 +1108,21 @@
     return guards.get(platform.python_implementation().lower(), default)
 
 
+def no_tracing(func):
+    """Decorator to temporarily turn off tracing for the duration of a test."""
+    if not hasattr(sys, 'gettrace'):
+        return func
+    else:
+        @functools.wraps(func)
+        def wrapper(*args, **kwargs):
+            original_trace = sys.gettrace()
+            try:
+                sys.settrace(None)
+                return func(*args, **kwargs)
+            finally:
+                sys.settrace(original_trace)
+        return wrapper
+
 
 def _run_suite(suite):
     """Run tests from a unittest.TestSuite-derived class."""

Modified: python/branches/py3k/Lib/test/test_doctest.py
==============================================================================
--- python/branches/py3k/Lib/test/test_doctest.py	(original)
+++ python/branches/py3k/Lib/test/test_doctest.py	Mon Feb 21 20:29:56 2011
@@ -5,6 +5,7 @@
 from test import support
 import doctest
 import os
+import sys
 
 
 # NOTE: There are some additional tests relating to interaction with
@@ -373,7 +374,7 @@
     >>> tests = finder.find(sample_func)
 
     >>> print(tests)  # doctest: +ELLIPSIS
-    [<DocTest sample_func from ...:17 (1 example)>]
+    [<DocTest sample_func from ...:18 (1 example)>]
 
 The exact name depends on how test_doctest was invoked, so allow for
 leading path components.
@@ -1686,226 +1687,227 @@
 
 """
 
-def test_pdb_set_trace():
-    """Using pdb.set_trace from a doctest.
-
-    You can use pdb.set_trace from a doctest.  To do so, you must
-    retrieve the set_trace function from the pdb module at the time
-    you use it.  The doctest module changes sys.stdout so that it can
-    capture program output.  It also temporarily replaces pdb.set_trace
-    with a version that restores stdout.  This is necessary for you to
-    see debugger output.
-
-      >>> doc = '''
-      ... >>> x = 42
-      ... >>> raise Exception('clé')
-      ... Traceback (most recent call last):
-      ... Exception: clé
-      ... >>> import pdb; pdb.set_trace()
-      ... '''
-      >>> parser = doctest.DocTestParser()
-      >>> test = parser.get_doctest(doc, {}, "foo-bar at baz", "foo-bar at baz.py", 0)
-      >>> runner = doctest.DocTestRunner(verbose=False)
-
-    To demonstrate this, we'll create a fake standard input that
-    captures our debugger input:
-
-      >>> import tempfile
-      >>> real_stdin = sys.stdin
-      >>> sys.stdin = _FakeInput([
-      ...    'print(x)',  # print data defined by the example
-      ...    'continue', # stop debugging
-      ...    ''])
-
-      >>> try: runner.run(test)
-      ... finally: sys.stdin = real_stdin
-      --Return--
-      > <doctest foo-bar at baz[2]>(1)<module>()->None
-      -> import pdb; pdb.set_trace()
-      (Pdb) print(x)
-      42
-      (Pdb) continue
-      TestResults(failed=0, attempted=3)
-
-      You can also put pdb.set_trace in a function called from a test:
-
-      >>> def calls_set_trace():
-      ...    y=2
-      ...    import pdb; pdb.set_trace()
-
-      >>> doc = '''
-      ... >>> x=1
-      ... >>> calls_set_trace()
-      ... '''
-      >>> test = parser.get_doctest(doc, globals(), "foo-bar at baz", "foo-bar at baz.py", 0)
-      >>> real_stdin = sys.stdin
-      >>> sys.stdin = _FakeInput([
-      ...    'print(y)',  # print data defined in the function
-      ...    'up',       # out of function
-      ...    'print(x)',  # print data defined by the example
-      ...    'continue', # stop debugging
-      ...    ''])
-
-      >>> try:
-      ...     runner.run(test)
-      ... finally:
-      ...     sys.stdin = real_stdin
-      --Return--
-      > <doctest test.test_doctest.test_pdb_set_trace[8]>(3)calls_set_trace()->None
-      -> import pdb; pdb.set_trace()
-      (Pdb) print(y)
-      2
-      (Pdb) up
-      > <doctest foo-bar at baz[1]>(1)<module>()
-      -> calls_set_trace()
-      (Pdb) print(x)
-      1
-      (Pdb) continue
-      TestResults(failed=0, attempted=2)
-
-    During interactive debugging, source code is shown, even for
-    doctest examples:
-
-      >>> doc = '''
-      ... >>> def f(x):
-      ... ...     g(x*2)
-      ... >>> def g(x):
-      ... ...     print(x+3)
-      ... ...     import pdb; pdb.set_trace()
-      ... >>> f(3)
-      ... '''
-      >>> test = parser.get_doctest(doc, globals(), "foo-bar at baz", "foo-bar at baz.py", 0)
-      >>> real_stdin = sys.stdin
-      >>> sys.stdin = _FakeInput([
-      ...    'list',     # list source from example 2
-      ...    'next',     # return from g()
-      ...    'list',     # list source from example 1
-      ...    'next',     # return from f()
-      ...    'list',     # list source from example 3
-      ...    'continue', # stop debugging
-      ...    ''])
-      >>> try: runner.run(test)
-      ... finally: sys.stdin = real_stdin
-      ... # doctest: +NORMALIZE_WHITESPACE
-      --Return--
-      > <doctest foo-bar at baz[1]>(3)g()->None
-      -> import pdb; pdb.set_trace()
-      (Pdb) list
-        1     def g(x):
-        2         print(x+3)
-        3  ->     import pdb; pdb.set_trace()
-      [EOF]
-      (Pdb) next
-      --Return--
-      > <doctest foo-bar at baz[0]>(2)f()->None
-      -> g(x*2)
-      (Pdb) list
-        1     def f(x):
-        2  ->     g(x*2)
-      [EOF]
-      (Pdb) next
-      --Return--
-      > <doctest foo-bar at baz[2]>(1)<module>()->None
-      -> f(3)
-      (Pdb) list
-        1  -> f(3)
-      [EOF]
-      (Pdb) continue
-      **********************************************************************
-      File "foo-bar at baz.py", line 7, in foo-bar at baz
-      Failed example:
-          f(3)
-      Expected nothing
-      Got:
-          9
-      TestResults(failed=1, attempted=3)
-      """
-
-def test_pdb_set_trace_nested():
-    """This illustrates more-demanding use of set_trace with nested functions.
-
-    >>> class C(object):
-    ...     def calls_set_trace(self):
-    ...         y = 1
-    ...         import pdb; pdb.set_trace()
-    ...         self.f1()
-    ...         y = 2
-    ...     def f1(self):
-    ...         x = 1
-    ...         self.f2()
-    ...         x = 2
-    ...     def f2(self):
-    ...         z = 1
-    ...         z = 2
-
-    >>> calls_set_trace = C().calls_set_trace
-
-    >>> doc = '''
-    ... >>> a = 1
-    ... >>> calls_set_trace()
-    ... '''
-    >>> parser = doctest.DocTestParser()
-    >>> runner = doctest.DocTestRunner(verbose=False)
-    >>> test = parser.get_doctest(doc, globals(), "foo-bar at baz", "foo-bar at baz.py", 0)
-    >>> real_stdin = sys.stdin
-    >>> sys.stdin = _FakeInput([
-    ...    'print(y)',  # print data defined in the function
-    ...    'step', 'step', 'step', 'step', 'step', 'step', 'print(z)',
-    ...    'up', 'print(x)',
-    ...    'up', 'print(y)',
-    ...    'up', 'print(foo)',
-    ...    'continue', # stop debugging
-    ...    ''])
-
-    >>> try:
-    ...     runner.run(test)
-    ... finally:
-    ...     sys.stdin = real_stdin
-    ... # doctest: +REPORT_NDIFF
-    > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(5)calls_set_trace()
-    -> self.f1()
-    (Pdb) print(y)
-    1
-    (Pdb) step
-    --Call--
-    > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(7)f1()
-    -> def f1(self):
-    (Pdb) step
-    > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(8)f1()
-    -> x = 1
-    (Pdb) step
-    > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(9)f1()
-    -> self.f2()
-    (Pdb) step
-    --Call--
-    > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(11)f2()
-    -> def f2(self):
-    (Pdb) step
-    > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(12)f2()
-    -> z = 1
-    (Pdb) step
-    > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(13)f2()
-    -> z = 2
-    (Pdb) print(z)
-    1
-    (Pdb) up
-    > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(9)f1()
-    -> self.f2()
-    (Pdb) print(x)
-    1
-    (Pdb) up
-    > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(5)calls_set_trace()
-    -> self.f1()
-    (Pdb) print(y)
-    1
-    (Pdb) up
-    > <doctest foo-bar at baz[1]>(1)<module>()
-    -> calls_set_trace()
-    (Pdb) print(foo)
-    *** NameError: name 'foo' is not defined
-    (Pdb) continue
-    TestResults(failed=0, attempted=2)
-"""
+if not hasattr(sys, 'gettrace') or not sys.gettrace():
+    def test_pdb_set_trace():
+        """Using pdb.set_trace from a doctest.
+
+        You can use pdb.set_trace from a doctest.  To do so, you must
+        retrieve the set_trace function from the pdb module at the time
+        you use it.  The doctest module changes sys.stdout so that it can
+        capture program output.  It also temporarily replaces pdb.set_trace
+        with a version that restores stdout.  This is necessary for you to
+        see debugger output.
+
+          >>> doc = '''
+          ... >>> x = 42
+          ... >>> raise Exception('clé')
+          ... Traceback (most recent call last):
+          ... Exception: clé
+          ... >>> import pdb; pdb.set_trace()
+          ... '''
+          >>> parser = doctest.DocTestParser()
+          >>> test = parser.get_doctest(doc, {}, "foo-bar at baz", "foo-bar at baz.py", 0)
+          >>> runner = doctest.DocTestRunner(verbose=False)
+
+        To demonstrate this, we'll create a fake standard input that
+        captures our debugger input:
+
+          >>> import tempfile
+          >>> real_stdin = sys.stdin
+          >>> sys.stdin = _FakeInput([
+          ...    'print(x)',  # print data defined by the example
+          ...    'continue', # stop debugging
+          ...    ''])
+
+          >>> try: runner.run(test)
+          ... finally: sys.stdin = real_stdin
+          --Return--
+          > <doctest foo-bar at baz[2]>(1)<module>()->None
+          -> import pdb; pdb.set_trace()
+          (Pdb) print(x)
+          42
+          (Pdb) continue
+          TestResults(failed=0, attempted=3)
+
+          You can also put pdb.set_trace in a function called from a test:
+
+          >>> def calls_set_trace():
+          ...    y=2
+          ...    import pdb; pdb.set_trace()
+
+          >>> doc = '''
+          ... >>> x=1
+          ... >>> calls_set_trace()
+          ... '''
+          >>> test = parser.get_doctest(doc, globals(), "foo-bar at baz", "foo-bar at baz.py", 0)
+          >>> real_stdin = sys.stdin
+          >>> sys.stdin = _FakeInput([
+          ...    'print(y)',  # print data defined in the function
+          ...    'up',       # out of function
+          ...    'print(x)',  # print data defined by the example
+          ...    'continue', # stop debugging
+          ...    ''])
+
+          >>> try:
+          ...     runner.run(test)
+          ... finally:
+          ...     sys.stdin = real_stdin
+          --Return--
+          > <doctest test.test_doctest.test_pdb_set_trace[8]>(3)calls_set_trace()->None
+          -> import pdb; pdb.set_trace()
+          (Pdb) print(y)
+          2
+          (Pdb) up
+          > <doctest foo-bar at baz[1]>(1)<module>()
+          -> calls_set_trace()
+          (Pdb) print(x)
+          1
+          (Pdb) continue
+          TestResults(failed=0, attempted=2)
+
+        During interactive debugging, source code is shown, even for
+        doctest examples:
+
+          >>> doc = '''
+          ... >>> def f(x):
+          ... ...     g(x*2)
+          ... >>> def g(x):
+          ... ...     print(x+3)
+          ... ...     import pdb; pdb.set_trace()
+          ... >>> f(3)
+          ... '''
+          >>> test = parser.get_doctest(doc, globals(), "foo-bar at baz", "foo-bar at baz.py", 0)
+          >>> real_stdin = sys.stdin
+          >>> sys.stdin = _FakeInput([
+          ...    'list',     # list source from example 2
+          ...    'next',     # return from g()
+          ...    'list',     # list source from example 1
+          ...    'next',     # return from f()
+          ...    'list',     # list source from example 3
+          ...    'continue', # stop debugging
+          ...    ''])
+          >>> try: runner.run(test)
+          ... finally: sys.stdin = real_stdin
+          ... # doctest: +NORMALIZE_WHITESPACE
+          --Return--
+          > <doctest foo-bar at baz[1]>(3)g()->None
+          -> import pdb; pdb.set_trace()
+          (Pdb) list
+            1     def g(x):
+            2         print(x+3)
+            3  ->     import pdb; pdb.set_trace()
+          [EOF]
+          (Pdb) next
+          --Return--
+          > <doctest foo-bar at baz[0]>(2)f()->None
+          -> g(x*2)
+          (Pdb) list
+            1     def f(x):
+            2  ->     g(x*2)
+          [EOF]
+          (Pdb) next
+          --Return--
+          > <doctest foo-bar at baz[2]>(1)<module>()->None
+          -> f(3)
+          (Pdb) list
+            1  -> f(3)
+          [EOF]
+          (Pdb) continue
+          **********************************************************************
+          File "foo-bar at baz.py", line 7, in foo-bar at baz
+          Failed example:
+              f(3)
+          Expected nothing
+          Got:
+              9
+          TestResults(failed=1, attempted=3)
+          """
+
+    def test_pdb_set_trace_nested():
+        """This illustrates more-demanding use of set_trace with nested functions.
+
+        >>> class C(object):
+        ...     def calls_set_trace(self):
+        ...         y = 1
+        ...         import pdb; pdb.set_trace()
+        ...         self.f1()
+        ...         y = 2
+        ...     def f1(self):
+        ...         x = 1
+        ...         self.f2()
+        ...         x = 2
+        ...     def f2(self):
+        ...         z = 1
+        ...         z = 2
+
+        >>> calls_set_trace = C().calls_set_trace
+
+        >>> doc = '''
+        ... >>> a = 1
+        ... >>> calls_set_trace()
+        ... '''
+        >>> parser = doctest.DocTestParser()
+        >>> runner = doctest.DocTestRunner(verbose=False)
+        >>> test = parser.get_doctest(doc, globals(), "foo-bar at baz", "foo-bar at baz.py", 0)
+        >>> real_stdin = sys.stdin
+        >>> sys.stdin = _FakeInput([
+        ...    'print(y)',  # print data defined in the function
+        ...    'step', 'step', 'step', 'step', 'step', 'step', 'print(z)',
+        ...    'up', 'print(x)',
+        ...    'up', 'print(y)',
+        ...    'up', 'print(foo)',
+        ...    'continue', # stop debugging
+        ...    ''])
+
+        >>> try:
+        ...     runner.run(test)
+        ... finally:
+        ...     sys.stdin = real_stdin
+        ... # doctest: +REPORT_NDIFF
+        > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(5)calls_set_trace()
+        -> self.f1()
+        (Pdb) print(y)
+        1
+        (Pdb) step
+        --Call--
+        > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(7)f1()
+        -> def f1(self):
+        (Pdb) step
+        > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(8)f1()
+        -> x = 1
+        (Pdb) step
+        > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(9)f1()
+        -> self.f2()
+        (Pdb) step
+        --Call--
+        > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(11)f2()
+        -> def f2(self):
+        (Pdb) step
+        > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(12)f2()
+        -> z = 1
+        (Pdb) step
+        > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(13)f2()
+        -> z = 2
+        (Pdb) print(z)
+        1
+        (Pdb) up
+        > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(9)f1()
+        -> self.f2()
+        (Pdb) print(x)
+        1
+        (Pdb) up
+        > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(5)calls_set_trace()
+        -> self.f1()
+        (Pdb) print(y)
+        1
+        (Pdb) up
+        > <doctest foo-bar at baz[1]>(1)<module>()
+        -> calls_set_trace()
+        (Pdb) print(foo)
+        *** NameError: name 'foo' is not defined
+        (Pdb) continue
+        TestResults(failed=0, attempted=2)
+    """
 
 def test_DocTestSuite():
     """DocTestSuite creates a unittest test suite from a doctest.

Modified: python/branches/py3k/Lib/test/test_exceptions.py
==============================================================================
--- python/branches/py3k/Lib/test/test_exceptions.py	(original)
+++ python/branches/py3k/Lib/test/test_exceptions.py	Mon Feb 21 20:29:56 2011
@@ -7,7 +7,7 @@
 import weakref
 
 from test.support import (TESTFN, unlink, run_unittest, captured_output,
-                          gc_collect, cpython_only)
+                          gc_collect, cpython_only, no_tracing)
 
 # XXX This is not really enough, each *operation* should be tested!
 
@@ -388,6 +388,7 @@
         x = DerivedException(fancy_arg=42)
         self.assertEqual(x.fancy_arg, 42)
 
+    @no_tracing
     def testInfiniteRecursion(self):
         def f():
             return f()
@@ -631,6 +632,7 @@
         u.start = 1000
         self.assertEqual(str(u), "can't translate characters in position 1000-4: 965230951443685724997")
 
+    @no_tracing
     def test_badisinstance(self):
         # Bug #2542: if issubclass(e, MyException) raises an exception,
         # it should be ignored
@@ -741,6 +743,7 @@
             self.fail("MemoryError not raised")
         self.assertEqual(wr(), None)
 
+    @no_tracing
     def test_recursion_error_cleanup(self):
         # Same test as above, but with "recursion exceeded" errors
         class C:

Modified: python/branches/py3k/Lib/test/test_io.py
==============================================================================
--- python/branches/py3k/Lib/test/test_io.py	(original)
+++ python/branches/py3k/Lib/test/test_io.py	Mon Feb 21 20:29:56 2011
@@ -2214,6 +2214,7 @@
         with self.open(support.TESTFN, "w", errors="replace") as f:
             self.assertEqual(f.errors, "replace")
 
+    @support.no_tracing
     @unittest.skipUnless(threading, 'Threading required for this test.')
     def test_threads_write(self):
         # Issue6750: concurrent writes could duplicate data
@@ -2669,6 +2670,7 @@
     def test_interrupted_write_text(self):
         self.check_interrupted_write("xy", b"xy", mode="w", encoding="ascii")
 
+    @support.no_tracing
     def check_reentrant_write(self, data, **fdopen_kwargs):
         def on_alarm(*args):
             # Will be called reentrantly from the same thread

Modified: python/branches/py3k/Lib/test/test_pdb.py
==============================================================================
--- python/branches/py3k/Lib/test/test_pdb.py	(original)
+++ python/branches/py3k/Lib/test/test_pdb.py	Mon Feb 21 20:29:56 2011
@@ -20,9 +20,12 @@
     def __enter__(self):
         self.real_stdin = sys.stdin
         sys.stdin = _FakeInput(self.input)
+        self.orig_trace = sys.gettrace() if hasattr(sys, 'gettrace') else None
 
     def __exit__(self, *exc):
         sys.stdin = self.real_stdin
+        if self.orig_trace:
+            sys.settrace(self.orig_trace)
 
 
 def test_pdb_displayhook():

Modified: python/branches/py3k/Lib/test/test_richcmp.py
==============================================================================
--- python/branches/py3k/Lib/test/test_richcmp.py	(original)
+++ python/branches/py3k/Lib/test/test_richcmp.py	Mon Feb 21 20:29:56 2011
@@ -220,6 +220,7 @@
         for func in (do, operator.not_):
             self.assertRaises(Exc, func, Bad())
 
+    @support.no_tracing
     def test_recursion(self):
         # Check that comparison for recursive objects fails gracefully
         from collections import UserList

Modified: python/branches/py3k/Lib/test/test_runpy.py
==============================================================================
--- python/branches/py3k/Lib/test/test_runpy.py	(original)
+++ python/branches/py3k/Lib/test/test_runpy.py	Mon Feb 21 20:29:56 2011
@@ -6,7 +6,8 @@
 import re
 import tempfile
 import py_compile
-from test.support import forget, make_legacy_pyc, run_unittest, unload, verbose
+from test.support import (
+    forget, make_legacy_pyc, run_unittest, unload, verbose, no_tracing)
 from test.script_helper import (
     make_pkg, make_script, make_zip_pkg, make_zip_script, temp_dir)
 
@@ -395,6 +396,7 @@
             msg = "can't find '__main__' module in %r" % zip_name
             self._check_import_error(zip_name, msg)
 
+    @no_tracing
     def test_main_recursion_error(self):
         with temp_dir() as script_dir, temp_dir() as dummy_dir:
             mod_name = '__main__'

Modified: python/branches/py3k/Lib/test/test_scope.py
==============================================================================
--- python/branches/py3k/Lib/test/test_scope.py	(original)
+++ python/branches/py3k/Lib/test/test_scope.py	Mon Feb 21 20:29:56 2011
@@ -1,5 +1,5 @@
 import unittest
-from test.support import check_syntax_error, run_unittest
+from test.support import check_syntax_error, cpython_only, run_unittest
 
 
 class ScopeTests(unittest.TestCase):
@@ -496,23 +496,22 @@
         self.assertNotIn("x", varnames)
         self.assertIn("y", varnames)
 
+    @cpython_only
     def testLocalsClass_WithTrace(self):
         # Issue23728: after the trace function returns, the locals()
         # dictionary is used to update all variables, this used to
         # include free variables. But in class statements, free
         # variables are not inserted...
         import sys
+        self.addCleanup(sys.settrace, sys.gettrace())
         sys.settrace(lambda a,b,c:None)
-        try:
-            x = 12
+        x = 12
 
-            class C:
-                def f(self):
-                    return x
+        class C:
+            def f(self):
+                return x
 
-            self.assertEqual(x, 12) # Used to raise UnboundLocalError
-        finally:
-            sys.settrace(None)
+        self.assertEqual(x, 12) # Used to raise UnboundLocalError
 
     def testBoundAndFree(self):
         # var is bound and free in class
@@ -527,6 +526,7 @@
         inst = f(3)()
         self.assertEqual(inst.a, inst.m())
 
+    @cpython_only
     def testInteractionWithTraceFunc(self):
 
         import sys
@@ -543,6 +543,7 @@
         class TestClass:
             pass
 
+        self.addCleanup(sys.settrace, sys.gettrace())
         sys.settrace(tracer)
         adaptgetter("foo", TestClass, (1, ""))
         sys.settrace(None)

Modified: python/branches/py3k/Lib/test/test_sys_settrace.py
==============================================================================
--- python/branches/py3k/Lib/test/test_sys_settrace.py	(original)
+++ python/branches/py3k/Lib/test/test_sys_settrace.py	Mon Feb 21 20:29:56 2011
@@ -251,6 +251,7 @@
     def setUp(self):
         self.using_gc = gc.isenabled()
         gc.disable()
+        self.addCleanup(sys.settrace, sys.gettrace())
 
     def tearDown(self):
         if self.using_gc:
@@ -389,6 +390,9 @@
 
 
 class RaisingTraceFuncTestCase(unittest.TestCase):
+    def setUp(self):
+        self.addCleanup(sys.settrace, sys.gettrace())
+
     def trace(self, frame, event, arg):
         """A trace function that raises an exception in response to a
         specific trace event."""
@@ -688,6 +692,10 @@
 
 
 class JumpTestCase(unittest.TestCase):
+    def setUp(self):
+        self.addCleanup(sys.settrace, sys.gettrace())
+        sys.settrace(None)
+
     def compare_jump_output(self, expected, received):
         if received != expected:
             self.fail( "Outputs don't match:\n" +
@@ -739,6 +747,8 @@
     def test_18_no_jump_to_non_integers(self):
         self.run_test(no_jump_to_non_integers)
     def test_19_no_jump_without_trace_function(self):
+        # Must set sys.settrace(None) in setUp(), else condition is not
+        # triggered.
         no_jump_without_trace_function()
 
     def test_20_large_function(self):

Modified: python/branches/py3k/Lib/test/test_trace.py
==============================================================================
--- python/branches/py3k/Lib/test/test_trace.py	(original)
+++ python/branches/py3k/Lib/test/test_trace.py	Mon Feb 21 20:29:56 2011
@@ -102,6 +102,7 @@
 class TestLineCounts(unittest.TestCase):
     """White-box testing of line-counting, via runfunc"""
     def setUp(self):
+        self.addCleanup(sys.settrace, sys.gettrace())
         self.tracer = Trace(count=1, trace=0, countfuncs=0, countcallers=0)
         self.my_py_filename = fix_ext_py(__file__)
 
@@ -192,6 +193,7 @@
     """A simple sanity test of line-counting, via runctx (exec)"""
     def setUp(self):
         self.my_py_filename = fix_ext_py(__file__)
+        self.addCleanup(sys.settrace, sys.gettrace())
 
     def test_exec_counts(self):
         self.tracer = Trace(count=1, trace=0, countfuncs=0, countcallers=0)
@@ -218,6 +220,7 @@
 class TestFuncs(unittest.TestCase):
     """White-box testing of funcs tracing"""
     def setUp(self):
+        self.addCleanup(sys.settrace, sys.gettrace())
         self.tracer = Trace(count=0, trace=0, countfuncs=1)
         self.filemod = my_file_and_modname()
 
@@ -257,6 +260,7 @@
 class TestCallers(unittest.TestCase):
     """White-box testing of callers tracing"""
     def setUp(self):
+        self.addCleanup(sys.settrace, sys.gettrace())
         self.tracer = Trace(count=0, trace=0, countcallers=1)
         self.filemod = my_file_and_modname()
 
@@ -280,6 +284,9 @@
 
 # Created separately for issue #3821
 class TestCoverage(unittest.TestCase):
+    def setUp(self):
+        self.addCleanup(sys.settrace, sys.gettrace())
+
     def tearDown(self):
         rmtree(TESTFN)
         unlink(TESTFN)

Modified: python/branches/py3k/Lib/test/test_zipimport_support.py
==============================================================================
--- python/branches/py3k/Lib/test/test_zipimport_support.py	(original)
+++ python/branches/py3k/Lib/test/test_zipimport_support.py	Mon Feb 21 20:29:56 2011
@@ -163,20 +163,24 @@
                     test_zipped_doctest.test_DocTestRunner.verbose_flag,
                     test_zipped_doctest.test_Example,
                     test_zipped_doctest.test_debug,
-                    test_zipped_doctest.test_pdb_set_trace,
-                    test_zipped_doctest.test_pdb_set_trace_nested,
                     test_zipped_doctest.test_testsource,
                     test_zipped_doctest.test_trailing_space_in_test,
                     test_zipped_doctest.test_DocTestSuite,
                     test_zipped_doctest.test_DocTestFinder,
                 ]
-                # These remaining tests are the ones which need access
+                # These tests are the ones which need access
                 # to the data files, so we don't run them
                 fail_due_to_missing_data_files = [
                     test_zipped_doctest.test_DocFileSuite,
                     test_zipped_doctest.test_testfile,
                     test_zipped_doctest.test_unittest_reportflags,
                 ]
+                # These tests are skipped when a trace funciton is set
+                can_fail_due_to_tracing = [
+                    test_zipped_doctest.test_pdb_set_trace,
+                    test_zipped_doctest.test_pdb_set_trace_nested,
+                ]
+
                 for obj in known_good_tests:
                     _run_object_doctest(obj, test_zipped_doctest)
             finally:

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Mon Feb 21 20:29:56 2011
@@ -18,6 +18,10 @@
 - Issue #10276: Fix the results of zlib.crc32() and zlib.adler32() on buffers
   larger than 4GB.  Patch by Nadeem Vawda.
 
+Tests
+
+- Issue #10990: Prevent tests from clobbering a set trace function.
+
 
 What's New in Python 3.2?
 =========================


More information about the Python-checkins mailing list