]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-105726: Add `__slots__` to `AbstractContextManager` and `AbstractAsyncContextManag...
authorGrigoriev Semyon <33061489+grigoriev-semyon@users.noreply.github.com>
Sun, 16 Jul 2023 15:30:39 +0000 (18:30 +0300)
committerGitHub <noreply@github.com>
Sun, 16 Jul 2023 15:30:39 +0000 (15:30 +0000)
Co-authored-by: Kumar Aditya <kumaraditya@python.org>
Lib/contextlib.py
Lib/test/test_contextlib.py
Lib/test/test_contextlib_async.py
Misc/NEWS.d/next/Library/2023-07-15-12-52-50.gh-issue-105726.NGthO8.rst [new file with mode: 0644]

index b5acbcb9e6d77cfe5bf1f42fa14905b4d6ae53fb..95947aceccc3043810253d7f30da34c4dff13f90 100644 (file)
@@ -20,6 +20,8 @@ class AbstractContextManager(abc.ABC):
 
     __class_getitem__ = classmethod(GenericAlias)
 
+    __slots__ = ()
+
     def __enter__(self):
         """Return `self` upon entering the runtime context."""
         return self
@@ -42,6 +44,8 @@ class AbstractAsyncContextManager(abc.ABC):
 
     __class_getitem__ = classmethod(GenericAlias)
 
+    __slots__ = ()
+
     async def __aenter__(self):
         """Return `self` upon entering the runtime context."""
         return self
index 0f8351ab8108a64f587d41218a45975efbd8e272..ecc5a43dad43da444a48d832c1796691762cef5e 100644 (file)
@@ -24,6 +24,16 @@ class TestAbstractContextManager(unittest.TestCase):
         manager = DefaultEnter()
         self.assertIs(manager.__enter__(), manager)
 
+    def test_slots(self):
+        class DefaultContextManager(AbstractContextManager):
+            __slots__ = ()
+
+            def __exit__(self, *args):
+                super().__exit__(*args)
+
+        with self.assertRaises(AttributeError):
+            DefaultContextManager().var = 42
+
     def test_exit_is_abstract(self):
         class MissingExit(AbstractContextManager):
             pass
index 3d43ed0fcab1686764695443185509a3686d3738..bb72ae74e5845fcaddd7e680b6e976d14573e245 100644 (file)
@@ -37,6 +37,18 @@ class TestAbstractAsyncContextManager(unittest.TestCase):
         async with manager as context:
             self.assertIs(manager, context)
 
+    @_async_test
+    async def test_slots(self):
+        class DefaultAsyncContextManager(AbstractAsyncContextManager):
+            __slots__ = ()
+
+            async def __aexit__(self, *args):
+                await super().__aexit__(*args)
+
+        with self.assertRaises(AttributeError):
+            manager = DefaultAsyncContextManager()
+            manager.var = 42
+
     @_async_test
     async def test_async_gen_propagates_generator_exit(self):
         # A regression test for https://bugs.python.org/issue33786.
diff --git a/Misc/NEWS.d/next/Library/2023-07-15-12-52-50.gh-issue-105726.NGthO8.rst b/Misc/NEWS.d/next/Library/2023-07-15-12-52-50.gh-issue-105726.NGthO8.rst
new file mode 100644 (file)
index 0000000..434f932
--- /dev/null
@@ -0,0 +1,3 @@
+Added ``__slots__`` to :class:`contextlib.AbstractContextManager` and :class:`contextlib.AbstractAsyncContextManager`
+so that child classes can use ``__slots__``.
+