[Python-checkins] gh-102799: use sys.exception() instead of sys.exc_info() in tests (#103293)

iritkatriel webhook-mailer at python.org
Thu Apr 6 06:08:32 EDT 2023


https://github.com/python/cpython/commit/482b6eeadcde3e6573f0d243e687de7be7680379
commit: 482b6eeadcde3e6573f0d243e687de7be7680379
branch: main
author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com>
committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com>
date: 2023-04-06T11:08:25+01:00
summary:

gh-102799: use sys.exception() instead of sys.exc_info() in tests (#103293)

files:
M Lib/test/profilee.py
M Lib/test/support/asyncore.py
M Lib/test/test_asyncio/test_tasks.py
M Lib/test/test_asyncio/utils.py
M Lib/test/test_class.py
M Lib/test/test_cprofile.py
M Lib/test/test_exceptions.py
M Lib/test/test_generators.py
M Lib/test/test_logging.py
M Lib/test/test_profile.py
M Lib/test/test_ssl.py
M Lib/test/test_traceback.py

diff --git a/Lib/test/profilee.py b/Lib/test/profilee.py
index 6ad2c8395634..b6a090a2e346 100644
--- a/Lib/test/profilee.py
+++ b/Lib/test/profilee.py
@@ -79,7 +79,7 @@ def helper1():
     TICKS += 19
     lst = []
     lst.append(42)                      # 0
-    sys.exc_info()                      # 0
+    sys.exception()                     # 0
 
 def helper2_indirect():
     helper2()                           # 50
diff --git a/Lib/test/support/asyncore.py b/Lib/test/support/asyncore.py
index 401fa60bcf35..b397aca55680 100644
--- a/Lib/test/support/asyncore.py
+++ b/Lib/test/support/asyncore.py
@@ -537,10 +537,11 @@ def send(self, data):
 # ---------------------------------------------------------------------------
 
 def compact_traceback():
-    t, v, tb = sys.exc_info()
-    tbinfo = []
+    exc = sys.exception()
+    tb = exc.__traceback__
     if not tb: # Must have a traceback
         raise AssertionError("traceback does not exist")
+    tbinfo = []
     while tb:
         tbinfo.append((
             tb.tb_frame.f_code.co_filename,
@@ -554,7 +555,7 @@ def compact_traceback():
 
     file, function, line = tbinfo[-1]
     info = ' '.join(['[%s|%s|%s]' % x for x in tbinfo])
-    return (file, function, line), t, v, info
+    return (file, function, line), type(exc), exc, info
 
 def close_all(map=None, ignore_all=False):
     if map is None:
diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py
index 731fa0c5a60b..31622c91470b 100644
--- a/Lib/test/test_asyncio/test_tasks.py
+++ b/Lib/test/test_asyncio/test_tasks.py
@@ -606,7 +606,7 @@ def on_timeout():
                     if (
                         timed_out
                         and task.uncancel() == 0
-                        and sys.exc_info()[0] is asyncio.CancelledError
+                        and type(sys.exception()) is asyncio.CancelledError
                     ):
                         # Note the five rules that are needed here to satisfy proper
                         # uncancellation:
diff --git a/Lib/test/test_asyncio/utils.py b/Lib/test/test_asyncio/utils.py
index 5b9c86eb9859..6dee5bb33b25 100644
--- a/Lib/test/test_asyncio/utils.py
+++ b/Lib/test/test_asyncio/utils.py
@@ -577,7 +577,7 @@ def tearDown(self):
 
         # Detect CPython bug #23353: ensure that yield/yield-from is not used
         # in an except block of a generator
-        self.assertEqual(sys.exc_info(), (None, None, None))
+        self.assertIsNone(sys.exception())
 
         self.doCleanups()
         threading_helper.threading_cleanup(*self._thread_cleanup)
diff --git a/Lib/test/test_class.py b/Lib/test/test_class.py
index 61df81b16977..d7a48e55b101 100644
--- a/Lib/test/test_class.py
+++ b/Lib/test/test_class.py
@@ -457,7 +457,7 @@ def __init__(self):
         a = A()
         self.assertEqual(_testcapi.hasattr_string(a, "attr"), True)
         self.assertEqual(_testcapi.hasattr_string(a, "noattr"), False)
-        self.assertEqual(sys.exc_info(), (None, None, None))
+        self.assertIsNone(sys.exception())
 
     def testDel(self):
         x = []
diff --git a/Lib/test/test_cprofile.py b/Lib/test/test_cprofile.py
index 4ec769885292..98648528bc81 100644
--- a/Lib/test/test_cprofile.py
+++ b/Lib/test/test_cprofile.py
@@ -100,7 +100,7 @@ def main():
 profilee.py:98(subhelper)                         <-       8    0.064    0.080  profilee.py:88(helper2)
 {built-in method builtins.hasattr}                <-       4    0.000    0.004  profilee.py:73(helper1)
                                                            8    0.000    0.008  profilee.py:88(helper2)
-{built-in method sys.exc_info}                    <-       4    0.000    0.000  profilee.py:73(helper1)
+{built-in method sys.exception}                   <-       4    0.000    0.000  profilee.py:73(helper1)
 {method 'append' of 'list' objects}               <-       4    0.000    0.000  profilee.py:73(helper1)"""
 _ProfileOutput['print_callees'] = """\
 <string>:1(<module>)                              ->       1    0.270    1.000  profilee.py:25(testfunc)
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py
index 74a5884264d5..684e888f08c7 100644
--- a/Lib/test/test_exceptions.py
+++ b/Lib/test/test_exceptions.py
@@ -334,8 +334,7 @@ def test_capi1():
             try:
                 _testcapi.raise_exception(BadException, 1)
             except TypeError as err:
-                exc, err, tb = sys.exc_info()
-                co = tb.tb_frame.f_code
+                co = err.__traceback__.tb_frame.f_code
                 self.assertEqual(co.co_name, "test_capi1")
                 self.assertTrue(co.co_filename.endswith('test_exceptions.py'))
             else:
@@ -346,8 +345,7 @@ def test_capi2():
             try:
                 _testcapi.raise_exception(BadException, 0)
             except RuntimeError as err:
-                exc, err, tb = sys.exc_info()
-                tb = tb.tb_next
+                tb = err.__traceback__.tb_next
                 co = tb.tb_frame.f_code
                 self.assertEqual(co.co_name, "__init__")
                 self.assertTrue(co.co_filename.endswith('test_exceptions.py'))
@@ -888,28 +886,28 @@ def yield_raise():
             try:
                 raise KeyError("caught")
             except KeyError:
-                yield sys.exc_info()[0]
-                yield sys.exc_info()[0]
-            yield sys.exc_info()[0]
+                yield sys.exception()
+                yield sys.exception()
+            yield sys.exception()
         g = yield_raise()
-        self.assertEqual(next(g), KeyError)
-        self.assertEqual(sys.exc_info()[0], None)
-        self.assertEqual(next(g), KeyError)
-        self.assertEqual(sys.exc_info()[0], None)
-        self.assertEqual(next(g), None)
+        self.assertIsInstance(next(g), KeyError)
+        self.assertIsNone(sys.exception())
+        self.assertIsInstance(next(g), KeyError)
+        self.assertIsNone(sys.exception())
+        self.assertIsNone(next(g))
 
         # Same test, but inside an exception handler
         try:
             raise TypeError("foo")
         except TypeError:
             g = yield_raise()
-            self.assertEqual(next(g), KeyError)
-            self.assertEqual(sys.exc_info()[0], TypeError)
-            self.assertEqual(next(g), KeyError)
-            self.assertEqual(sys.exc_info()[0], TypeError)
-            self.assertEqual(next(g), TypeError)
+            self.assertIsInstance(next(g), KeyError)
+            self.assertIsInstance(sys.exception(), TypeError)
+            self.assertIsInstance(next(g), KeyError)
+            self.assertIsInstance(sys.exception(), TypeError)
+            self.assertIsInstance(next(g), TypeError)
             del g
-            self.assertEqual(sys.exc_info()[0], TypeError)
+            self.assertIsInstance(sys.exception(), TypeError)
 
     def test_generator_leaking2(self):
         # See issue 12475.
@@ -924,7 +922,7 @@ def g():
             next(it)
         except StopIteration:
             pass
-        self.assertEqual(sys.exc_info(), (None, None, None))
+        self.assertIsNone(sys.exception())
 
     def test_generator_leaking3(self):
         # See issue #23353.  When gen.throw() is called, the caller's
@@ -933,17 +931,17 @@ def g():
             try:
                 yield
             except ZeroDivisionError:
-                yield sys.exc_info()[1]
+                yield sys.exception()
         it = g()
         next(it)
         try:
             1/0
         except ZeroDivisionError as e:
-            self.assertIs(sys.exc_info()[1], e)
+            self.assertIs(sys.exception(), e)
             gen_exc = it.throw(e)
-            self.assertIs(sys.exc_info()[1], e)
+            self.assertIs(sys.exception(), e)
             self.assertIs(gen_exc, e)
-        self.assertEqual(sys.exc_info(), (None, None, None))
+        self.assertIsNone(sys.exception())
 
     def test_generator_leaking4(self):
         # See issue #23353.  When an exception is raised by a generator,
@@ -952,7 +950,7 @@ def g():
             try:
                 1/0
             except ZeroDivisionError:
-                yield sys.exc_info()[0]
+                yield sys.exception()
                 raise
         it = g()
         try:
@@ -960,7 +958,7 @@ def g():
         except TypeError:
             # The caller's exception state (TypeError) is temporarily
             # saved in the generator.
-            tp = next(it)
+            tp = type(next(it))
         self.assertIs(tp, ZeroDivisionError)
         try:
             next(it)
@@ -968,15 +966,15 @@ def g():
             # with an exception, it shouldn't have restored the old
             # exception state (TypeError).
         except ZeroDivisionError as e:
-            self.assertIs(sys.exc_info()[1], e)
+            self.assertIs(sys.exception(), e)
         # We used to find TypeError here.
-        self.assertEqual(sys.exc_info(), (None, None, None))
+        self.assertIsNone(sys.exception())
 
     def test_generator_doesnt_retain_old_exc(self):
         def g():
-            self.assertIsInstance(sys.exc_info()[1], RuntimeError)
+            self.assertIsInstance(sys.exception(), RuntimeError)
             yield
-            self.assertEqual(sys.exc_info(), (None, None, None))
+            self.assertIsNone(sys.exception())
         it = g()
         try:
             raise RuntimeError
@@ -984,7 +982,7 @@ def g():
             next(it)
         self.assertRaises(StopIteration, next, it)
 
-    def test_generator_finalizing_and_exc_info(self):
+    def test_generator_finalizing_and_sys_exception(self):
         # See #7173
         def simple_gen():
             yield 1
@@ -996,7 +994,7 @@ def run_gen():
                 return next(gen)
         run_gen()
         gc_collect()
-        self.assertEqual(sys.exc_info(), (None, None, None))
+        self.assertIsNone(sys.exception())
 
     def _check_generator_cleanup_exc_state(self, testfunc):
         # Issue #12791: exception state is cleaned up as soon as a generator
@@ -1067,14 +1065,14 @@ def test_3114(self):
         class MyObject:
             def __del__(self):
                 nonlocal e
-                e = sys.exc_info()
+                e = sys.exception()
         e = ()
         try:
             raise Exception(MyObject())
         except:
             pass
         gc_collect()  # For PyPy or other GCs.
-        self.assertEqual(e, (None, None, None))
+        self.assertIsNone(e)
 
     def test_raise_does_not_create_context_chain_cycle(self):
         class A(Exception):
@@ -1692,7 +1690,7 @@ def g():
                 raise ValueError
             except ValueError:
                 yield 1
-            self.assertEqual(sys.exc_info(), (None, None, None))
+            self.assertIsNone(sys.exception())
             yield 2
 
         gen = g()
diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py
index 492b77a954d8..a5949dec70d1 100644
--- a/Lib/test/test_generators.py
+++ b/Lib/test/test_generators.py
@@ -234,16 +234,16 @@ class ExceptionTest(unittest.TestCase):
     def test_except_throw(self):
         def store_raise_exc_generator():
             try:
-                self.assertEqual(sys.exc_info()[0], None)
+                self.assertIsNone(sys.exception())
                 yield
             except Exception as exc:
                 # exception raised by gen.throw(exc)
-                self.assertEqual(sys.exc_info()[0], ValueError)
+                self.assertIsInstance(sys.exception(), ValueError)
                 self.assertIsNone(exc.__context__)
                 yield
 
                 # ensure that the exception is not lost
-                self.assertEqual(sys.exc_info()[0], ValueError)
+                self.assertIsInstance(sys.exception(), ValueError)
                 yield
 
                 # we should be able to raise back the ValueError
@@ -265,11 +265,11 @@ def store_raise_exc_generator():
             next(make)
         self.assertIsNone(cm.exception.__context__)
 
-        self.assertEqual(sys.exc_info(), (None, None, None))
+        self.assertIsNone(sys.exception())
 
     def test_except_next(self):
         def gen():
-            self.assertEqual(sys.exc_info()[0], ValueError)
+            self.assertIsInstance(sys.exception(), ValueError)
             yield "done"
 
         g = gen()
@@ -277,23 +277,23 @@ def gen():
             raise ValueError
         except Exception:
             self.assertEqual(next(g), "done")
-        self.assertEqual(sys.exc_info(), (None, None, None))
+        self.assertIsNone(sys.exception())
 
     def test_except_gen_except(self):
         def gen():
             try:
-                self.assertEqual(sys.exc_info()[0], None)
+                self.assertIsNone(sys.exception())
                 yield
                 # we are called from "except ValueError:", TypeError must
                 # inherit ValueError in its context
                 raise TypeError()
             except TypeError as exc:
-                self.assertEqual(sys.exc_info()[0], TypeError)
+                self.assertIsInstance(sys.exception(), TypeError)
                 self.assertEqual(type(exc.__context__), ValueError)
             # here we are still called from the "except ValueError:"
-            self.assertEqual(sys.exc_info()[0], ValueError)
+            self.assertIsInstance(sys.exception(), ValueError)
             yield
-            self.assertIsNone(sys.exc_info()[0])
+            self.assertIsNone(sys.exception())
             yield "done"
 
         g = gen()
@@ -304,7 +304,7 @@ def gen():
             next(g)
 
         self.assertEqual(next(g), "done")
-        self.assertEqual(sys.exc_info(), (None, None, None))
+        self.assertIsNone(sys.exception())
 
     def test_nested_gen_except_loop(self):
         def gen():
@@ -330,19 +330,19 @@ def test_except_throw_exception_context(self):
         def gen():
             try:
                 try:
-                    self.assertEqual(sys.exc_info()[0], None)
+                    self.assertIsNone(sys.exception())
                     yield
                 except ValueError:
                     # we are called from "except ValueError:"
-                    self.assertEqual(sys.exc_info()[0], ValueError)
+                    self.assertIsInstance(sys.exception(), ValueError)
                     raise TypeError()
             except Exception as exc:
-                self.assertEqual(sys.exc_info()[0], TypeError)
+                self.assertIsInstance(sys.exception(), TypeError)
                 self.assertEqual(type(exc.__context__), ValueError)
             # we are still called from "except ValueError:"
-            self.assertEqual(sys.exc_info()[0], ValueError)
+            self.assertIsInstance(sys.exception(), ValueError)
             yield
-            self.assertIsNone(sys.exc_info()[0])
+            self.assertIsNone(sys.exception())
             yield "done"
 
         g = gen()
@@ -353,7 +353,7 @@ def gen():
             g.throw(exc)
 
         self.assertEqual(next(g), "done")
-        self.assertEqual(sys.exc_info(), (None, None, None))
+        self.assertIsNone(sys.exception())
 
     def test_except_throw_bad_exception(self):
         class E(Exception):
diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py
index 072056d37221..c6de34e9dbdc 100644
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -5097,8 +5097,7 @@ def test_encoding_errors_none(self):
             message = []
 
             def dummy_handle_error(record):
-                _, v, _ = sys.exc_info()
-                message.append(str(v))
+                message.append(str(sys.exception()))
 
             handler.handleError = dummy_handle_error
             logging.debug('The Øresund Bridge joins Copenhagen to Malmö')
diff --git a/Lib/test/test_profile.py b/Lib/test/test_profile.py
index d97fe447c38b..a1dfc9abbb8e 100644
--- a/Lib/test/test_profile.py
+++ b/Lib/test/test_profile.py
@@ -178,7 +178,7 @@ def main():
         8   63.976    7.997   79.960    9.995 profilee.py:98(subhelper)"""
 _ProfileOutput['print_callers'] = """\
 :0(append)                        <- profilee.py:73(helper1)(4)  119.964
-:0(exc_info)                      <- profilee.py:73(helper1)(4)  119.964
+:0(exception)                     <- profilee.py:73(helper1)(4)  119.964
 :0(hasattr)                       <- profilee.py:73(helper1)(4)  119.964
                                      profilee.py:88(helper2)(8)  399.912
 profilee.py:110(__getattr__)      <- :0(hasattr)(12)   11.964
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
index abf024fb89d2..d46ce5e60e21 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -253,7 +253,7 @@ def wrapper(*args, **kw):
 
 
 def handle_error(prefix):
-    exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
+    exc_format = ' '.join(traceback.format_exception(sys.exception()))
     if support.verbose:
         sys.stdout.write(prefix + exc_format)
 
diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py
index 399c59f8780d..a6172ff05eed 100644
--- a/Lib/test/test_traceback.py
+++ b/Lib/test/test_traceback.py
@@ -1211,8 +1211,7 @@ def test_recursive_traceback_python(self):
     def test_recursive_traceback_cpython_internal(self):
         from _testcapi import exception_print
         def render_exc():
-            exc_type, exc_value, exc_tb = sys.exc_info()
-            exception_print(exc_value)
+            exception_print(sys.exception())
         self._check_recursive_traceback_display(render_exc)
 
     def test_format_stack(self):
@@ -2470,8 +2469,8 @@ def test_cause(self):
             try:
                 1/0
             finally:
-                exc_info_context = sys.exc_info()
-                exc_context = traceback.TracebackException(*exc_info_context)
+                exc = sys.exception()
+                exc_context = traceback.TracebackException.from_exception(exc)
                 cause = Exception("cause")
                 raise Exception("uh oh") from cause
         except Exception as e:
@@ -2492,8 +2491,8 @@ def test_context(self):
             try:
                 1/0
             finally:
-                exc_info_context = sys.exc_info()
-                exc_context = traceback.TracebackException(*exc_info_context)
+                exc = sys.exception()
+                exc_context = traceback.TracebackException.from_exception(exc)
                 raise Exception("uh oh")
         except Exception as e:
             exc_obj = e
@@ -2557,8 +2556,8 @@ def test_compact_no_cause(self):
             try:
                 1/0
             finally:
-                exc_info_context = sys.exc_info()
-                exc_context = traceback.TracebackException(*exc_info_context)
+                exc = sys.exception()
+                exc_context = traceback.TracebackException.from_exception(exc)
                 raise Exception("uh oh")
         except Exception as e:
             exc_obj = e



More information about the Python-checkins mailing list