Skip to content

Commit 9220223

Browse files
committed
Add extra unit tests.
Check behaviour of the catch_warnings() context manager when used with asyncio co-routines and threads.
1 parent 153c6b1 commit 9220223

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed

Lib/test/test_warnings/__init__.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
15311644
class DeprecatedTests(PyPublicAPITests):
15321645
def test_dunder_deprecated(self):
15331646
@deprecated("A will go away soon")

0 commit comments

Comments
 (0)