Skip to content

Commit 753422f

Browse files
authored
bpo-30266: support "= None" pattern in AbstractContextManager (GH-1448) (GH-2054)
contextlib.AbstractContextManager now supports anti-registration by setting __enter__ = None or __exit__ = None, following the pattern introduced in bpo-25958.. (cherry picked from commit 57161aa)
1 parent e380c19 commit 753422f

File tree

3 files changed

+16
-3
lines changed

3 files changed

+16
-3
lines changed

Lib/contextlib.py

Lines changed: 2 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

@@ -25,9 +26,7 @@ def __exit__(self, exc_type, exc_value, traceback):
2526
@classmethod
2627
def __subclasshook__(cls, C):
2728
if cls is AbstractContextManager:
28-
if (any("__enter__" in B.__dict__ for B in C.__mro__) and
29-
any("__exit__" in B.__dict__ for B in C.__mro__)):
30-
return True
29+
return _collections_abc._check_methods(C, "__enter__", "__exit__")
3130
return NotImplemented
3231

3332

Lib/test/test_contextlib.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ def __exit__(self, *args):
4444

4545
self.assertTrue(issubclass(DefaultEnter, AbstractContextManager))
4646

47+
class NoEnter(ManagerFromScratch):
48+
__enter__ = None
49+
50+
self.assertFalse(issubclass(NoEnter, AbstractContextManager))
51+
52+
class NoExit(ManagerFromScratch):
53+
__exit__ = None
54+
55+
self.assertFalse(issubclass(NoExit, AbstractContextManager))
56+
4757

4858
class ContextManagerTestCase(unittest.TestCase):
4959

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ Library
9696
- bpo-30048: Fixed ``Task.cancel()`` can be ignored when the task is
9797
running coroutine and the coroutine returned without any more ``await``.
9898

99+
- bpo-30266: contextlib.AbstractContextManager now supports anti-registration
100+
by setting __enter__ = None or __exit__ = None, following the pattern
101+
introduced in bpo-25958. Patch by Jelle Zijlstra.
102+
99103
- bpo-30298: Weaken the condition of deprecation warnings for inline modifiers.
100104
Now allowed several subsequential inline modifiers at the start of the
101105
pattern (e.g. ``'(?i)(?s)...'``). In verbose mode whitespaces and comments

0 commit comments

Comments
 (0)