Skip to content

Commit 3ab0136

Browse files
bpo-32604: Implement force-closing channels. (gh-6937)
This will make it easier to clean up channels (e.g. when used in tests).
1 parent 74fc9c0 commit 3ab0136

File tree

2 files changed

+232
-25
lines changed

2 files changed

+232
-25
lines changed

Lib/test/test__xxsubinterpreters.py

Lines changed: 96 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,12 +1379,104 @@ def test_close_multiple_times(self):
13791379
with self.assertRaises(interpreters.ChannelClosedError):
13801380
interpreters.channel_close(cid)
13811381

1382-
def test_close_with_unused_items(self):
1382+
def test_close_empty(self):
1383+
tests = [
1384+
(False, False),
1385+
(True, False),
1386+
(False, True),
1387+
(True, True),
1388+
]
1389+
for send, recv in tests:
1390+
with self.subTest((send, recv)):
1391+
cid = interpreters.channel_create()
1392+
interpreters.channel_send(cid, b'spam')
1393+
interpreters.channel_recv(cid)
1394+
interpreters.channel_close(cid, send=send, recv=recv)
1395+
1396+
with self.assertRaises(interpreters.ChannelClosedError):
1397+
interpreters.channel_send(cid, b'eggs')
1398+
with self.assertRaises(interpreters.ChannelClosedError):
1399+
interpreters.channel_recv(cid)
1400+
1401+
def test_close_defaults_with_unused_items(self):
1402+
cid = interpreters.channel_create()
1403+
interpreters.channel_send(cid, b'spam')
1404+
interpreters.channel_send(cid, b'ham')
1405+
1406+
with self.assertRaises(interpreters.ChannelNotEmptyError):
1407+
interpreters.channel_close(cid)
1408+
interpreters.channel_recv(cid)
1409+
interpreters.channel_send(cid, b'eggs')
1410+
1411+
def test_close_recv_with_unused_items_unforced(self):
13831412
cid = interpreters.channel_create()
13841413
interpreters.channel_send(cid, b'spam')
13851414
interpreters.channel_send(cid, b'ham')
1386-
interpreters.channel_close(cid)
1415+
1416+
with self.assertRaises(interpreters.ChannelNotEmptyError):
1417+
interpreters.channel_close(cid, recv=True)
1418+
interpreters.channel_recv(cid)
1419+
interpreters.channel_send(cid, b'eggs')
1420+
interpreters.channel_recv(cid)
1421+
interpreters.channel_recv(cid)
1422+
interpreters.channel_close(cid, recv=True)
1423+
1424+
def test_close_send_with_unused_items_unforced(self):
1425+
cid = interpreters.channel_create()
1426+
interpreters.channel_send(cid, b'spam')
1427+
interpreters.channel_send(cid, b'ham')
1428+
interpreters.channel_close(cid, send=True)
13871429

1430+
with self.assertRaises(interpreters.ChannelClosedError):
1431+
interpreters.channel_send(cid, b'eggs')
1432+
interpreters.channel_recv(cid)
1433+
interpreters.channel_recv(cid)
1434+
with self.assertRaises(interpreters.ChannelClosedError):
1435+
interpreters.channel_recv(cid)
1436+
1437+
def test_close_both_with_unused_items_unforced(self):
1438+
cid = interpreters.channel_create()
1439+
interpreters.channel_send(cid, b'spam')
1440+
interpreters.channel_send(cid, b'ham')
1441+
1442+
with self.assertRaises(interpreters.ChannelNotEmptyError):
1443+
interpreters.channel_close(cid, recv=True, send=True)
1444+
interpreters.channel_recv(cid)
1445+
interpreters.channel_send(cid, b'eggs')
1446+
interpreters.channel_recv(cid)
1447+
interpreters.channel_recv(cid)
1448+
interpreters.channel_close(cid, recv=True)
1449+
1450+
def test_close_recv_with_unused_items_forced(self):
1451+
cid = interpreters.channel_create()
1452+
interpreters.channel_send(cid, b'spam')
1453+
interpreters.channel_send(cid, b'ham')
1454+
interpreters.channel_close(cid, recv=True, force=True)
1455+
1456+
with self.assertRaises(interpreters.ChannelClosedError):
1457+
interpreters.channel_send(cid, b'eggs')
1458+
with self.assertRaises(interpreters.ChannelClosedError):
1459+
interpreters.channel_recv(cid)
1460+
1461+
def test_close_send_with_unused_items_forced(self):
1462+
cid = interpreters.channel_create()
1463+
interpreters.channel_send(cid, b'spam')
1464+
interpreters.channel_send(cid, b'ham')
1465+
interpreters.channel_close(cid, send=True, force=True)
1466+
1467+
with self.assertRaises(interpreters.ChannelClosedError):
1468+
interpreters.channel_send(cid, b'eggs')
1469+
with self.assertRaises(interpreters.ChannelClosedError):
1470+
interpreters.channel_recv(cid)
1471+
1472+
def test_close_both_with_unused_items_forced(self):
1473+
cid = interpreters.channel_create()
1474+
interpreters.channel_send(cid, b'spam')
1475+
interpreters.channel_send(cid, b'ham')
1476+
interpreters.channel_close(cid, send=True, recv=True, force=True)
1477+
1478+
with self.assertRaises(interpreters.ChannelClosedError):
1479+
interpreters.channel_send(cid, b'eggs')
13881480
with self.assertRaises(interpreters.ChannelClosedError):
13891481
interpreters.channel_recv(cid)
13901482

@@ -1403,7 +1495,7 @@ def test_close_by_unassociated_interp(self):
14031495
interp = interpreters.create()
14041496
interpreters.run_string(interp, dedent(f"""
14051497
import _xxsubinterpreters as _interpreters
1406-
_interpreters.channel_close({cid})
1498+
_interpreters.channel_close({cid}, force=True)
14071499
"""))
14081500
with self.assertRaises(interpreters.ChannelClosedError):
14091501
interpreters.channel_recv(cid)
@@ -1416,7 +1508,7 @@ def test_close_used_multiple_times_by_single_user(self):
14161508
interpreters.channel_send(cid, b'spam')
14171509
interpreters.channel_send(cid, b'spam')
14181510
interpreters.channel_recv(cid)
1419-
interpreters.channel_close(cid)
1511+
interpreters.channel_close(cid, force=True)
14201512

14211513
with self.assertRaises(interpreters.ChannelClosedError):
14221514
interpreters.channel_send(cid, b'eggs')

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy