@@ -1528,6 +1528,119 @@ def test_late_resource_warning(self):
15281528 self .assertTrue (err .startswith (expected ), ascii (err ))
15291529
15301530
1531+ class AsyncTests (BaseTest ):
1532+ """Verifies that the catch_warnings() context manager behaves
1533+ as expected when used inside async co-routines. This requires
1534+ that the context_aware_warnings flag is enabled, so that
1535+ the context manager uses a context variable.
1536+ """
1537+
1538+ @unittest .skipIf (not sys .flags .context_aware_warnings ,
1539+ "requires context aware warnings" )
1540+ def test_async_context (self ):
1541+ import asyncio
1542+
1543+ async def run_a ():
1544+ with self .module .catch_warnings (record = True ) as w :
1545+ await asyncio .sleep (0 )
1546+ # The warning emitted here should be caught be the enclosing
1547+ # context manager.
1548+ self .module .warn ('run_a warning' , UserWarning )
1549+ await asyncio .sleep (0 )
1550+ self .assertEqual (len (w ), 1 )
1551+ self .assertEqual (w [0 ].message .args [0 ], 'run_a warning' )
1552+
1553+ async def run_b ():
1554+ with self .module .catch_warnings (record = True ) as w :
1555+ await asyncio .sleep (0 )
1556+ # The warning emitted here should be caught be the enclosing
1557+ # context manager.
1558+ self .module .warn ('run_b warning' , UserWarning )
1559+ await asyncio .sleep (0 )
1560+ self .assertEqual (len (w ), 1 )
1561+ self .assertEqual (w [0 ].message .args [0 ], 'run_b warning' )
1562+
1563+ async def run_tasks ():
1564+ task_a = asyncio .create_task (run_a ())
1565+ task_b = asyncio .create_task (run_b ())
1566+ await asyncio .gather (task_a , task_b )
1567+
1568+ asyncio .run (run_tasks ())
1569+
1570+
1571+ class CAsyncTests (AsyncTests , unittest .TestCase ):
1572+ module = c_warnings
1573+
1574+
1575+ class PyAsyncTests (AsyncTests , unittest .TestCase ):
1576+ module = py_warnings
1577+
1578+
1579+ class ThreadTests (BaseTest ):
1580+ """Verifies that the catch_warnings() context manager behaves as
1581+ expected when used within threads. This requires that both the
1582+ context_aware_warnings flag and thread_inherit_context flags are enabled.
1583+ """
1584+
1585+ ENABLE_THREAD_TESTS = (sys .flags .context_aware_warnings and
1586+ sys .flags .thread_inherit_context )
1587+
1588+ @unittest .skipIf (not ENABLE_THREAD_TESTS ,
1589+ "requires thread-safe warnings flags" )
1590+ def test_threaded_context (self ):
1591+ import threading
1592+
1593+ barrier = threading .Barrier (2 )
1594+
1595+ def run_a ():
1596+ with self .module .catch_warnings (record = True ) as w :
1597+ barrier .wait ()
1598+ # The warning emitted here should be caught be the enclosing
1599+ # context manager.
1600+ self .module .warn ('run_a warning' , UserWarning )
1601+ barrier .wait ()
1602+ self .assertEqual (len (w ), 1 )
1603+ self .assertEqual (w [0 ].message .args [0 ], 'run_a warning' )
1604+ # Should be caught be the catch_warnings() context manager of run_threads()
1605+ self .module .warn ('main warning' , UserWarning )
1606+
1607+ def run_b ():
1608+ with self .module .catch_warnings (record = True ) as w :
1609+ barrier .wait ()
1610+ # The warning emitted here should be caught be the enclosing
1611+ # context manager.
1612+ barrier .wait ()
1613+ self .module .warn ('run_b warning' , UserWarning )
1614+ self .assertEqual (len (w ), 1 )
1615+ self .assertEqual (w [0 ].message .args [0 ], 'run_b warning' )
1616+ # Should be caught be the catch_warnings() context manager of run_threads()
1617+ self .module .warn ('main warning' , UserWarning )
1618+
1619+ def run_threads ():
1620+ threads = [
1621+ threading .Thread (target = run_a ),
1622+ threading .Thread (target = run_b ),
1623+ ]
1624+ with self .module .catch_warnings (record = True ) as w :
1625+ for thread in threads :
1626+ thread .start ()
1627+ for thread in threads :
1628+ thread .join ()
1629+ self .assertEqual (len (w ), 2 )
1630+ self .assertEqual (w [0 ].message .args [0 ], 'main warning' )
1631+ self .assertEqual (w [1 ].message .args [0 ], 'main warning' )
1632+
1633+ run_threads ()
1634+
1635+
1636+ class CThreadTests (ThreadTests , unittest .TestCase ):
1637+ module = c_warnings
1638+
1639+
1640+ class PyThreadTests (ThreadTests , unittest .TestCase ):
1641+ module = py_warnings
1642+
1643+
15311644class DeprecatedTests (PyPublicAPITests ):
15321645 def test_dunder_deprecated (self ):
15331646 @deprecated ("A will go away soon" )
0 commit comments