Skip to content

Commit 9fb1028

Browse files
committed
support the "= None" pattern
1 parent b0f92e5 commit 9fb1028

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

Lib/contextlib.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Utilities for with-statement contexts. See PEP 343."""
22
import abc
33
import sys
4+
import _collections_abc
45
from collections import deque
56
from functools import wraps
67

@@ -48,9 +49,8 @@ async def __aexit__(self, exc_type, exc_value, traceback):
4849
@classmethod
4950
def __subclasshook__(cls, C):
5051
if cls is AbstractAsyncContextManager:
51-
if (any("__aenter__" in B.__dict__ for B in C.__mro__) and
52-
any("__aexit__" in B.__dict__ for B in C.__mro__)):
53-
return True
52+
return _collections_abc._check_methods(C, "__aenter__",
53+
"__aexit__")
5454
return NotImplemented
5555

5656

Lib/test/test_contextlib_async.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ async def __aexit__(self, *args):
3131
manager = DefaultEnter()
3232
self.assertIs(await manager.__aenter__(), manager)
3333

34+
async with manager as context:
35+
self.assertIs(manager, context)
36+
3437
def test_exit_is_abstract(self):
3538
class MissingAexit(AbstractAsyncContextManager):
3639
pass
@@ -53,6 +56,16 @@ async def __aexit__(self, *args):
5356

5457
self.assertTrue(issubclass(DefaultEnter, AbstractAsyncContextManager))
5558

59+
class NoneAenter(ManagerFromScratch):
60+
__aenter__ = None
61+
62+
self.assertFalse(issubclass(NoneAenter, AbstractAsyncContextManager))
63+
64+
class NoneAexit(ManagerFromScratch):
65+
__aexit__ = None
66+
67+
self.assertFalse(issubclass(NoneAexit, AbstractAsyncContextManager))
68+
5669

5770
class AsyncContextManagerTestCase(unittest.TestCase):
5871

0 commit comments

Comments
 (0)